gml_Fraction.h

Go to the documentation of this file.
00001 /** @file gml_Fraction.h
00002  * 
00003  *     Extraction of the IEEE floating-point representation to do integer math.
00004  * 
00005  *   Copyright (c) 2003-2004 CLIPS-IMAG
00006  * 
00007  *   See the file "gml_LicenseTerms.txt" for information on usage and redistribution
00008  *   of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00009  * 
00010  *   Created on April, 2003 (JL).
00011  *   Ported to GML on January 19, 2004 (JL).
00012  */
00013 #ifndef __GML_FRACTION__
00014 #define __GML_FRACTION__
00015 
00016 #include <assert.h>
00017 #include <math.h>
00018 
00019 #include "gml/base/gml_Types.h"
00020 #include "gml/base/gml_Errors.h"
00021 #include "gml/math/gml_Math.h"
00022 
00023 ///
00024 /// gml_TFloatUnion --
00025 ///   A structure to extract the fields of an 
00026 ///   IEEE 32-bit floating point number.
00027 ///
00028 union gml_TFloatUnion
00029 {
00030   Float32   fFloat;                     ///< full floating-point representation
00031   struct {
00032     #if BYTE_ORDER == BIG_ENDIAN
00033       unsigned int  fSign      :  1;    ///< sign bit
00034       unsigned int  fExponent  :  8;    ///< 8-bit binary exponent
00035       unsigned int  fRemainder : 23;    ///< 23-bit binary mantissa
00036     #else
00037       unsigned int  fRemainder : 23;    ///< 23-bit binary mantissa
00038       unsigned int  fExponent  :  8;    ///< 8-bit binary exponent
00039       unsigned int  fSign      :  1;    ///< sign bit
00040     #endif
00041   };
00042 };
00043 
00044 
00045 ///
00046 /// gml_TFraction --
00047 ///   Fast integer representation of a floating-point number between 0 and 1.
00048 ///   Provides a Merge() method for fast blending of two integers
00049 ///   (e.g. for alpha-compositing purposes)
00050 ///
00051 class gml_TFraction
00052 {
00053   public:
00054   
00055     ///
00056     /// Constructor --
00057     ///   Build a gml_TFraction from the IEEE 32-bit float <fraction>.
00058     ///
00059     gml_TFraction (Float32 fraction)
00060     {
00061       const gml_TFloatUnion fu = { fraction };
00062       
00063       assert (fraction >= 0.0F && fraction <= 1.0F);
00064       fExponent = 127 - fu.fExponent + 23;
00065       fNumerator1 = fu.fRemainder + (1 << 23);
00066       fNumerator2 = (1 << fExponent) - fNumerator1;
00067     }
00068     
00069     ///
00070     /// Constructor --
00071     ///   Build a gml_TFraction as <numerator> / 2 ** <exponent>.
00072     ///
00073     gml_TFraction (UInt32 numerator, UInt8 exponent)
00074     {      
00075       assert (numerator   < (1 << 23));
00076       assert (exponent < (1 << 7));
00077       fExponent = exponent;
00078       fNumerator1 = numerator;
00079       fNumerator2 = (1 << fExponent) - fNumerator1;
00080     }
00081     
00082     ///
00083     /// Constructor --
00084     ///   Build the fraction representing 1.
00085     ///
00086     gml_TFraction ()
00087     {
00088       fExponent = 0;
00089       fNumerator1 = 1;
00090       fNumerator2 = 0;
00091     }
00092 
00093     ///
00094     /// Merge --
00095     ///   Return a*f + b*(1-f) using only integer arithmetics.
00096     ///
00097     inline UInt32 Merge (const UInt32 a, const UInt32 b) const
00098     {
00099       return 
00100         (UInt64(a) * fNumerator1 + UInt64(b) * fNumerator2) >> fExponent;
00101     }
00102     
00103     ///
00104     /// Numerator --
00105     ///   Return the numerator.
00106     ///
00107     inline UInt32 Numerator () const
00108     {
00109       return fNumerator1;
00110     }
00111     
00112     ///
00113     /// Exponent --
00114     ///   Return the exponent.
00115     ///
00116     inline UInt8 Exponent () const
00117     {
00118       return fExponent;
00119     }
00120     
00121     ///
00122     /// Value --
00123     ///   Return the floating-point value corresponding to this fraction
00124     ///
00125     inline Float32 Value () const
00126     {
00127       return Divide (Float32(fNumerator1), Float32(1UL << fExponent));
00128     }
00129     
00130   protected:
00131     UInt8   fExponent;      ///< the opposite of the fraction's power-of-two exponent
00132     UInt32  fNumerator1;    ///< the fraction's numerator  
00133     UInt32  fNumerator2;    ///< the numerator of the fraction's complement to 1
00134 } ;
00135 
00136 ///
00137 /// Merge --
00138 ///   Return the <alpha>-compositon of <a> and <b>.
00139 ///
00140 inline
00141 UInt32 Merge (UInt32 a, UInt32 b, UInt8 alpha)
00142 {
00143   #ifdef __GML_AVOID_EUCLIDIAN_DIVISION
00144     // avoid doing a division using 255 ~= 2^16 / 257
00145     return ((a * (255 - alpha) + b * alpha) * 257UL) >> 16;
00146   #else
00147     return (a * (255 - alpha) + b * alpha) / 255;
00148   #endif
00149 }
00150 
00151 #endif /* __GML_FRACTION__ */
00152 
Generated on Tue Jun 12 14:03:27 2007 for gml by Doxygen 1.5.2.