LLVM API Documentation

APFloat.h

Go to the documentation of this file.
00001 //== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file declares a class to represent arbitrary precision floating
00011 // point values and provide a variety of arithmetic operations on them.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 /*  A self-contained host- and target-independent arbitrary-precision
00016     floating-point software implementation.  It uses bignum integer
00017     arithmetic as provided by static functions in the APInt class.
00018     The library will work with bignum integers whose parts are any
00019     unsigned type at least 16 bits wide, but 64 bits is recommended.
00020 
00021     Written for clarity rather than speed, in particular with a view
00022     to use in the front-end of a cross compiler so that target
00023     arithmetic can be correctly performed on the host.  Performance
00024     should nonetheless be reasonable, particularly for its intended
00025     use.  It may be useful as a base implementation for a run-time
00026     library during development of a faster target-specific one.
00027 
00028     All 5 rounding modes in the IEEE-754R draft are handled correctly
00029     for all implemented operations.  Currently implemented operations
00030     are add, subtract, multiply, divide, fused-multiply-add,
00031     conversion-to-float, conversion-to-integer and
00032     conversion-from-integer.  New rounding modes (e.g. away from zero)
00033     can be added with three or four lines of code.
00034 
00035     Four formats are built-in: IEEE single precision, double
00036     precision, quadruple precision, and x87 80-bit extended double
00037     (when operating with full extended precision).  Adding a new
00038     format that obeys IEEE semantics only requires adding two lines of
00039     code: a declaration and definition of the format.
00040 
00041     All operations return the status of that operation as an exception
00042     bit-mask, so multiple operations can be done consecutively with
00043     their results or-ed together.  The returned status can be useful
00044     for compiler diagnostics; e.g., inexact, underflow and overflow
00045     can be easily diagnosed on constant folding, and compiler
00046     optimizers can determine what exceptions would be raised by
00047     folding operations and optimize, or perhaps not optimize,
00048     accordingly.
00049 
00050     At present, underflow tininess is detected after rounding; it
00051     should be straight forward to add support for the before-rounding
00052     case too.
00053 
00054     The library reads hexadecimal floating point numbers as per C99,
00055     and correctly rounds if necessary according to the specified
00056     rounding mode.  Syntax is required to have been validated by the
00057     caller.  It also converts floating point numbers to hexadecimal
00058     text as per the C99 %a and %A conversions.  The output precision
00059     (or alternatively the natural minimal precision) can be specified;
00060     if the requested precision is less than the natural precision the
00061     output is correctly rounded for the specified rounding mode.
00062 
00063     It also reads decimal floating point numbers and correctly rounds
00064     according to the specified rounding mode.
00065 
00066     Conversion to decimal text is not currently implemented.
00067 
00068     Non-zero finite numbers are represented internally as a sign bit,
00069     a 16-bit signed exponent, and the significand as an array of
00070     integer parts.  After normalization of a number of precision P the
00071     exponent is within the range of the format, and if the number is
00072     not denormal the P-th bit of the significand is set as an explicit
00073     integer bit.  For denormals the most significant bit is shifted
00074     right so that the exponent is maintained at the format's minimum,
00075     so that the smallest denormal has just the least significant bit
00076     of the significand set.  The sign of zeroes and infinities is
00077     significant; the exponent and significand of such numbers is not
00078     stored, but has a known implicit (deterministic) value: 0 for the
00079     significands, 0 for zero exponent, all 1 bits for infinity
00080     exponent.  For NaNs the sign and significand are deterministic,
00081     although not really meaningful, and preserved in non-conversion
00082     operations.  The exponent is implicitly all 1 bits.
00083 
00084     TODO
00085     ====
00086 
00087     Some features that may or may not be worth adding:
00088 
00089     Binary to decimal conversion (hard).
00090 
00091     Optional ability to detect underflow tininess before rounding.
00092 
00093     New formats: x87 in single and double precision mode (IEEE apart
00094     from extended exponent range) (hard).
00095 
00096     New operations: sqrt, IEEE remainder, C90 fmod, nextafter,
00097     nexttoward.
00098 */
00099 
00100 #ifndef LLVM_FLOAT_H
00101 #define LLVM_FLOAT_H
00102 
00103 // APInt contains static functions implementing bignum arithmetic.
00104 #include "llvm/ADT/APInt.h"
00105 
00106 namespace llvm {
00107 
00108   /* Exponents are stored as signed numbers.  */
00109   typedef signed short exponent_t;
00110 
00111   struct fltSemantics;
00112 
00113   /* When bits of a floating point number are truncated, this enum is
00114      used to indicate what fraction of the LSB those bits represented.
00115      It essentially combines the roles of guard and sticky bits.  */
00116   enum lostFraction {           // Example of truncated bits:
00117     lfExactlyZero,              // 000000
00118     lfLessThanHalf,             // 0xxxxx  x's not all zero
00119     lfExactlyHalf,              // 100000
00120     lfMoreThanHalf              // 1xxxxx  x's not all zero
00121   };
00122 
00123   class APFloat {
00124   public:
00125 
00126     /* We support the following floating point semantics.  */
00127     static const fltSemantics IEEEsingle;
00128     static const fltSemantics IEEEdouble;
00129     static const fltSemantics IEEEquad;
00130     static const fltSemantics PPCDoubleDouble;
00131     static const fltSemantics x87DoubleExtended;
00132     /* And this pseudo, used to construct APFloats that cannot
00133        conflict with anything real. */
00134     static const fltSemantics Bogus;
00135 
00136     static unsigned int semanticsPrecision(const fltSemantics &);
00137 
00138     /* Floating point numbers have a four-state comparison relation.  */
00139     enum cmpResult {
00140       cmpLessThan,
00141       cmpEqual,
00142       cmpGreaterThan,
00143       cmpUnordered
00144     };
00145 
00146     /* IEEE-754R gives five rounding modes.  */
00147     enum roundingMode {
00148       rmNearestTiesToEven,
00149       rmTowardPositive,
00150       rmTowardNegative,
00151       rmTowardZero,
00152       rmNearestTiesToAway
00153     };
00154 
00155     // Operation status.  opUnderflow or opOverflow are always returned
00156     // or-ed with opInexact.
00157     enum opStatus {
00158       opOK          = 0x00,
00159       opInvalidOp   = 0x01,
00160       opDivByZero   = 0x02,
00161       opOverflow    = 0x04,
00162       opUnderflow   = 0x08,
00163       opInexact     = 0x10
00164     };
00165 
00166     // Category of internally-represented number.
00167     enum fltCategory {
00168       fcInfinity,
00169       fcNaN,
00170       fcNormal,
00171       fcZero
00172     };
00173 
00174     // Constructors.
00175     APFloat(const fltSemantics &, const char *);
00176     APFloat(const fltSemantics &, integerPart);
00177     APFloat(const fltSemantics &, fltCategory, bool negative);
00178     explicit APFloat(double d);
00179     explicit APFloat(float f);
00180     explicit APFloat(const APInt &, bool isIEEE = false);
00181     APFloat(const APFloat &);
00182     ~APFloat();
00183 
00184     // Convenience "constructors"
00185     static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
00186       return APFloat(Sem, fcZero, Negative);
00187     }
00188     static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
00189       return APFloat(Sem, fcInfinity, Negative);
00190     }
00191     static APFloat getNaN(const fltSemantics &Sem, bool Negative = false) {
00192       return APFloat(Sem, fcNaN, Negative);
00193     }
00194 
00195     /// Profile - Used to insert APFloat objects, or objects that contain
00196     ///  APFloat objects, into FoldingSets.
00197     void Profile(FoldingSetNodeID& NID) const;
00198 
00199     /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
00200     void Emit(Serializer& S) const;
00201 
00202     /// @brief Used by the Bitcode deserializer to deserialize APInts.
00203     static APFloat ReadVal(Deserializer& D);
00204 
00205     /* Arithmetic.  */
00206     opStatus add(const APFloat &, roundingMode);
00207     opStatus subtract(const APFloat &, roundingMode);
00208     opStatus multiply(const APFloat &, roundingMode);
00209     opStatus divide(const APFloat &, roundingMode);
00210     /* IEEE remainder. */
00211     opStatus remainder(const APFloat &);
00212     /* C fmod, or llvm frem. */
00213     opStatus mod(const APFloat &, roundingMode);
00214     opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
00215 
00216     /* Sign operations.  */
00217     void changeSign();
00218     void clearSign();
00219     void copySign(const APFloat &);
00220 
00221     /* Conversions.  */
00222     opStatus convert(const fltSemantics &, roundingMode, bool *);
00223     opStatus convertToInteger(integerPart *, unsigned int, bool,
00224                               roundingMode, bool *) const;
00225     opStatus convertFromAPInt(const APInt &,
00226                               bool, roundingMode);
00227     opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
00228                                             bool, roundingMode);
00229     opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
00230                                             bool, roundingMode);
00231     opStatus convertFromString(const char *, roundingMode);
00232     APInt bitcastToAPInt() const;
00233     double convertToDouble() const;
00234     float convertToFloat() const;
00235 
00236     /* The definition of equality is not straightforward for floating point,
00237        so we won't use operator==.  Use one of the following, or write
00238        whatever it is you really mean. */
00239     // bool operator==(const APFloat &) const;     // DO NOT IMPLEMENT
00240 
00241     /* IEEE comparison with another floating point number (NaNs
00242        compare unordered, 0==-0). */
00243     cmpResult compare(const APFloat &) const;
00244 
00245     /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */
00246     bool bitwiseIsEqual(const APFloat &) const;
00247 
00248     /* Write out a hexadecimal representation of the floating point
00249        value to DST, which must be of sufficient size, in the C99 form
00250        [-]0xh.hhhhp[+-]d.  Return the number of characters written,
00251        excluding the terminating NUL.  */
00252     unsigned int convertToHexString(char *dst, unsigned int hexDigits,
00253                                     bool upperCase, roundingMode) const;
00254 
00255     /* Simple queries.  */
00256     fltCategory getCategory() const { return category; }
00257     const fltSemantics &getSemantics() const { return *semantics; }
00258     bool isZero() const { return category == fcZero; }
00259     bool isNonZero() const { return category != fcZero; }
00260     bool isNaN() const { return category == fcNaN; }
00261     bool isInfinity() const { return category == fcInfinity; }
00262     bool isNegative() const { return sign; }
00263     bool isPosZero() const { return isZero() && !isNegative(); }
00264     bool isNegZero() const { return isZero() && isNegative(); }
00265 
00266     APFloat& operator=(const APFloat &);
00267 
00268     /* Return an arbitrary integer value usable for hashing. */
00269     uint32_t getHashValue() const;
00270 
00271   private:
00272 
00273     /* Trivial queries.  */
00274     integerPart *significandParts();
00275     const integerPart *significandParts() const;
00276     unsigned int partCount() const;
00277 
00278     /* Significand operations.  */
00279     integerPart addSignificand(const APFloat &);
00280     integerPart subtractSignificand(const APFloat &, integerPart);
00281     lostFraction addOrSubtractSignificand(const APFloat &, bool subtract);
00282     lostFraction multiplySignificand(const APFloat &, const APFloat *);
00283     lostFraction divideSignificand(const APFloat &);
00284     void incrementSignificand();
00285     void initialize(const fltSemantics *);
00286     void shiftSignificandLeft(unsigned int);
00287     lostFraction shiftSignificandRight(unsigned int);
00288     unsigned int significandLSB() const;
00289     unsigned int significandMSB() const;
00290     void zeroSignificand();
00291 
00292     /* Arithmetic on special values.  */
00293     opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
00294     opStatus divideSpecials(const APFloat &);
00295     opStatus multiplySpecials(const APFloat &);
00296     opStatus modSpecials(const APFloat &);
00297 
00298     /* Miscellany.  */
00299     void makeNaN(void);
00300     opStatus normalize(roundingMode, lostFraction);
00301     opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
00302     cmpResult compareAbsoluteValue(const APFloat &) const;
00303     opStatus handleOverflow(roundingMode);
00304     bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
00305     opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
00306                                           roundingMode, bool *) const;
00307     opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
00308                                       roundingMode);
00309     opStatus convertFromHexadecimalString(const char *, roundingMode);
00310     opStatus convertFromDecimalString (const char *, roundingMode);
00311     char *convertNormalToHexString(char *, unsigned int, bool,
00312                                    roundingMode) const;
00313     opStatus roundSignificandWithExponent(const integerPart *, unsigned int,
00314                                           int, roundingMode);
00315 
00316     APInt convertFloatAPFloatToAPInt() const;
00317     APInt convertDoubleAPFloatToAPInt() const;
00318     APInt convertF80LongDoubleAPFloatToAPInt() const;
00319     APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
00320     void initFromAPInt(const APInt& api, bool isIEEE = false);
00321     void initFromFloatAPInt(const APInt& api);
00322     void initFromDoubleAPInt(const APInt& api);
00323     void initFromF80LongDoubleAPInt(const APInt& api);
00324     void initFromPPCDoubleDoubleAPInt(const APInt& api);
00325 
00326     void assign(const APFloat &);
00327     void copySignificand(const APFloat &);
00328     void freeSignificand();
00329 
00330     /* What kind of semantics does this value obey?  */
00331     const fltSemantics *semantics;
00332 
00333     /* Significand - the fraction with an explicit integer bit.  Must be
00334        at least one bit wider than the target precision.  */
00335     union Significand
00336     {
00337       integerPart part;
00338       integerPart *parts;
00339     } significand;
00340 
00341     /* The exponent - a signed number.  */
00342     exponent_t exponent;
00343 
00344     /* What kind of floating point number this is.  */
00345     /* Only 2 bits are required, but VisualStudio incorrectly sign extends
00346        it.  Using the extra bit keeps it from failing under VisualStudio */
00347     fltCategory category: 3;
00348 
00349     /* The sign bit of this number.  */
00350     unsigned int sign: 1;
00351 
00352     /* For PPCDoubleDouble, we have a second exponent and sign (the second
00353        significand is appended to the first one, although it would be wrong to
00354        regard these as a single number for arithmetic purposes).  These fields
00355        are not meaningful for any other type. */
00356     exponent_t exponent2 : 11;
00357     unsigned int sign2: 1;
00358   };
00359 } /* namespace llvm */
00360 
00361 #endif /* LLVM_FLOAT_H */