#include <vtkFastNumericConversion.h>
Inheritance diagram for vtkFastNumericConversion:
vtkFastNumericConversion uses a portable (assuming IEEE format) method for converting single and double precision floating point values to a fixed point representation. This allows fast integer floor operations on platforms, such as Intel X86, in which CPU floating point conversion algorithms are very slow. It is based on the techniques described in Chris Hecker's article, "Let's Get to the (Floating) Point", in Game Developer Magazine, Feb/Mar 1996, and the techniques described in Michael Herf's website, http://www.stereopsis.com/FPU.html. The Hecker article can be found at http://www.d6.com/users/checker/pdfs/gdmfp.pdf. Unfortunately, each of these techniques is incomplete, and doesn't convert properly, in a way that depends on how many bits are reserved for fixed point fractional use, due to failing to properly account for the default roundtowardseven rounding mode of the X86. Thus, my implementation incorporates some rounding correction that undoes the rounding that the FPU performs during denormalization of the floating point value. Note that the rounding affect I'm talking about here is not the effect on the fistp instruction, but rather the effect that occurs during the denormalization of a value that occurs when adding it to a much larger value. The bits must be shifted to the right, and when a "1" bit falls off the edge, the rounding mode determines what happens next, in order to avoid completely "losing" the 1bit. Furthermore, my implementation works on Linux, where the default precision mode is 64bit extended precision.
This class is contributed to VTK by Chris Volpe of Applied Research Associates, Inc. (My employer requires me to say that  CRV)
This code assumes that the FPU is in roundtonearest mode. It assumes, on Linux, that the default extended precision mode is in effect, and it assumes, on Windows, that the default double precision mode is in effect.
Definition at line 77 of file vtkFastNumericConversion.h.
void  SetReservedFracBits (int bits) 
static int  SafeFinalShift () 
void  PerformanceTests (void) 
static int  QuickFloor (const double &val) 
static double  RoundingTieBreaker () 
static double  QuickFloorDenormalizer () 
Public Types  
typedef vtkObject  Superclass 
Public Member Functions  
virtual const char *  GetClassName () 
virtual int  IsA (const char *type) 
void  PrintSelf (ostream &os, vtkIndent indent) 
int  TestQuickFloor (double val) 
int  TestSafeFloor (double val) 
int  TestRound (double val) 
int  TestConvertFixedPointIntPart (double val) 
int  TestConvertFixedPointFracPart (double val) 
int  ConvertFixedPoint (const double &val, int &fracPart) 
Static Public Member Functions  
static vtkFastNumericConversion *  New () 
static int  IsTypeOf (const char *type) 
static vtkFastNumericConversion *  SafeDownCast (vtkObject *o) 
static int  SafeFloor (const double &val) 
static int  Round (const double &val) 
Protected Types  
enum  { exponent_pos = 1, mantissa_pos = 0 } 
Protected Member Functions  
vtkFastNumericConversion ()  
~vtkFastNumericConversion ()  
void  InternalRebuild (void) 
Static Protected Member Functions  
static double  BorrowBit () 
static double  QuickRoundAdjust () 
static double  SafeRoundAdjust () 
static double  two30 () 
static double  two52 () 
static double  two51 () 
static double  two63 () 
static double  two62 () 
static double  SafeFloorDenormalizer () 
static double  QuickExtPrecTempDenormalizer () 
static double  SafeExtPrecTempDenormalizer () 

Reimplemented from vtkObject. Definition at line 81 of file vtkFastNumericConversion.h. 

Definition at line 246 of file vtkFastNumericConversion.h. 

Definition at line 422 of file vtkFastNumericConversion.h. 

Definition at line 440 of file vtkFastNumericConversion.h. 

Create an object with Debug turned off, modified time initialized to zero, and reference counting on. Reimplemented from vtkObject. 

Reimplemented from vtkObject. 

Return 1 if this class type is the same type of (or a subclass of) the named class. Returns 0 otherwise. This method works in combination with vtkTypeRevisionMacro found in vtkSetGet.h. Reimplemented from vtkObject. 

Return 1 if this class is the same type of (or a subclass of) the named class. Returns 0 otherwise. This method works in combination with vtkTypeRevisionMacro found in vtkSetGet.h. Reimplemented from vtkObject. 

Reimplemented from vtkObject. 

Methods invoked by print to print information about the object including superclasses. Typically not called by the user (use Print() instead) but used in the hierarchical print process to combine the output of several classes. Reimplemented from vtkObject. 

Wrappable method for scripttesting of correct crossplatform functionality 

Wrappable method for scripttesting of correct crossplatform functionality 

Wrappable method for scripttesting of correct crossplatform functionality 

Wrappable method for scripttesting of correct crossplatform functionality 

Wrappable method for scripttesting of correct crossplatform functionality 

Internal use: multiply the denormalizer value by 1.5 to ensure that it has a "1" bit, other than the implicit initial "1" bit, from which to borrow when adding (flooring) a negative number, so that we don't borrow from the implicit "1" bit, which would cause partial renormalization, resulting in a shift of our integer bits. Definition at line 111 of file vtkFastNumericConversion.h. 

Represent 2^30 as a double precision float. Use as a stepping stone for computing 2^52 as a double, since we can't represent 2^52 as an int before converting to double. Definition at line 116 of file vtkFastNumericConversion.h. 

Represent 2^52 as a double precision float. This value is significant because doubles have 52 bits of precision in the mantissa Definition at line 121 of file vtkFastNumericConversion.h. 

Represent 2^51 as a double precision float. This value is significant because doubles have 52 (explicit) bits of precision in the mantissa, but we're going to pretend we only have 51 to play with when using safe floor, since the default roundtoeven on an X86 mucks with the LSB during the denormalizing shift. Definition at line 131 of file vtkFastNumericConversion.h. 

Represent 2^63 as a double precision float. We need this value to shift unwanted fractional bits off the end of an extended precision value Definition at line 139 of file vtkFastNumericConversion.h. 

Represent 2^62 as a double precision float. We need this value to shift unwanted fractional bits off the end of an extended precision value. Use when we're doing a SafeFloor. Definition at line 147 of file vtkFastNumericConversion.h. 

Small amount to use as a rounding tiebreaker to prevent roundtonearestandeven mode from flooringdown odd numbered integers. But number to nudge by depends on number of bits mantissa in our floating point representation minus number of mantissa bits in the range of signed ints we need to handle. In order to ensure that flooringdown doesn't happen even for very large oddinteger values, the number of bits used to represent the tiebreaker (i.e. to the right of the binarypoint), plus the number of bits needed to represent the integer (to the left of the binary point), can not exceeds the number of bits in the current precision mode. Thus, in selecting the tiebreaker value, we select the largest number of bits to the right of the binary point as possible while still maintining that inequality. Thus, extended precision mode allows a larger number of bits to the right of the binary point. This, in turn, implies a smaller value of the tiebreaker. And a smaller tiebreaker will impose a tighter window on the range of values that are erroneously roundedup by a floor operation. Under double precision, a QuickFloor of 0.9999998 (six 9's and an 8) correctly yields 0. A value must be very close to 1.0, in fact, at least as close as 0.9999999 (seven 9's)in order for the tiebreaker to bump it up to 1. Under extended precision, an even smaller tiebreaker can be used. In this mode, a QuickFloor of 0.9999999999 (ten 9's) correctly yields 0. A QuickFloor of 0.99999999999 (eleven 9's) gets rounded up to 1. Since these spurious roundups occur only when the given value is virtually indistinguishable from the next higher integer, the results should be acceptable in most situations where performance is of the essence. Make this public so that clients can account for the RoundingTieBreaker if necessary Definition at line 199 of file vtkFastNumericConversion.h. 

This is the magic floating point value which when added to any other floating point value, causes the rounded integer portion of that floating point value to appear in the least significant bits of the mantissa, which is what we want. Definition at line 208 of file vtkFastNumericConversion.h. 

This is the magic floating point value which when added to any other floating point value, causes the rounded integer portion of that floating point value to appear in the NEXT TO least significant bits of the mantissa, which is what we want. This allows the CPU rounding mode to muck with the LSB which we can then discard in SafeFloor Definition at line 218 of file vtkFastNumericConversion.h. 

This value is added to and then subtracted from an extended precision value in order to clear the fractional bits so that they do not adversely affect the final doubleprecision result. Definition at line 226 of file vtkFastNumericConversion.h. 

Just like QuickExtPrecTempDenormalizer(), but preserves one extra bit of fixed point precision to guard against the CPU mucking with the LSB Definition at line 234 of file vtkFastNumericConversion.h. 

Definition at line 238 of file vtkFastNumericConversion.h. 

Definition at line 239 of file vtkFastNumericConversion.h. 

Set the number of bits reserved for fractional precision that are maintained as part of the flooring process. This number affects the flooring arithmetic. It may be useful if the factional part is to be used to index into a lookup table of some sort. However, if you are only interested in knowing the fractional remainder after flooring, there doesn't appear to be any advantage to using these bits, either in terms of a lookup table, or by directly multiplying by some unit fraction, over simply subtracting the floored value from the original value. Note that since only 32 bits are used for the entire fixed point representation, increasing the number of reserved fractional bits reduces the range of integer values that can be floored to. Definition at line 240 of file vtkFastNumericConversion.h. 

Set the number of bits reserved for fractional precision that are maintained as part of the flooring process. This number affects the flooring arithmetic. It may be useful if the factional part is to be used to index into a lookup table of some sort. However, if you are only interested in knowing the fractional remainder after flooring, there doesn't appear to be any advantage to using these bits, either in terms of a lookup table, or by directly multiplying by some unit fraction, over simply subtracting the floored value from the original value. Note that since only 32 bits are used for the entire fixed point representation, increasing the number of reserved fractional bits reduces the range of integer values that can be floored to. Definition at line 264 of file vtkFastNumericConversion.h. References vtkObject::GetMTime(). 

Conduct timing tests so that the usefulness of this class can be ascertained on whatever platform it is being used. Output can be retrieved via Print method. 

Perform a quick flooring of the doubleprecision floating point value. The result is sometimes incorrect, but in a way that makes it acceptable for most uses. The naive way to implement floor(), given that the x86 FPU does round() by default, is to define floor(x) as round(x.5). This would work fine except for the fact that the x86 FPU breaks rounding ties by selecting the even number. Thus, floor(4.0) = round(3.5) = 4, but floor(3.0) = round(2.5) = 2. As a result, subtracting .5 gives the wrong answer for odd integers. So, let's subtract just a TEENSY bit less than .5, to swing the oddinteger results up to their corect value. How teensy? Well, if it's too teensy, it will be insignificant compared to 0.5, and will become equivalent to 0.5. And if it's not teensy enough, we'll overshoot, causing results like floor(Nepsilon)==N, for some epsilon. Furthermore, the "too teensy" problem is exacerbated when trying to floor larger numbers, due to limitations of the representation's dynamic range. See the definition of RoundingTieBreaker() for details. Definition at line 303 of file vtkFastNumericConversion.h. Referenced by vtkFloorFuncMacro(). 

Perform a SAFE flooring. Similar to QuickFloor, but modified to return the correct result always. Use this when it absolutely positively needs to be the correct answer all the time, and considering 0.9999999 as being equal to 1.0 is simply not acceptable. It works similarly to QuickFloor, but it retains one extra bit of fixed point precision in the conversion process, so that the problem with QuickFloor affects only an unneeded bit, and then it ditches that bit from the resulting integer with a rightshift. In other words, it rounds to the nearest onehalf, choosing the EVEN onehalf (i.e. the integer) as a tiebreaker, and then shifting off that halfinteger bit. As a result of maintaining one extra bit of fixed point precision in the intermediate calculation, the range of integers supported is reduced by one bit. Plus, it takes a little longer to execute, due to the final bit shift. Definition at line 340 of file vtkFastNumericConversion.h. 

Round to nearest int. This is pretty sweet in the default roundtonearest FPU mode, since it is generally immaterial how ties are broken when rounding. I.e., either "2" or "3" are acceptable results for "Round(2.5)", but only one of them (the one naively not chosen without jumping through the hoops in QuickFloor and SafeFloor) is the acceptable result for the analogous "Floor(3)". Therefore, we don't need to worry at all about adding a teensy but not too teensy tie breaker, or shifting off a halfinteger bit. This makes it exceptionally fast. Definition at line 370 of file vtkFastNumericConversion.h. Referenced by vtkRoundFuncMacro(). 

Convert the value to a fixed point representation, returning the integer portion as function value, and returning the fractional part in the second parameter. Definition at line 401 of file vtkFastNumericConversion.h. 

