diff options
Diffstat (limited to 'lib/Support/APFloat.cpp')
-rw-r--r-- | lib/Support/APFloat.cpp | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index e765ba0..c3169ac 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -726,7 +726,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const { } APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) -{ + : exponent2(0), sign2(0) { assertArithmeticOK(ourSemantics); initialize(&ourSemantics); sign = 0; @@ -736,14 +736,15 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) normalize(rmNearestTiesToEven, lfExactlyZero); } -APFloat::APFloat(const fltSemantics &ourSemantics) { +APFloat::APFloat(const fltSemantics &ourSemantics) : exponent2(0), sign2(0) { assertArithmeticOK(ourSemantics); initialize(&ourSemantics); category = fcZero; sign = false; } -APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) { +APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) + : exponent2(0), sign2(0) { assertArithmeticOK(ourSemantics); // Allocates storage if necessary but does not initialize it. initialize(&ourSemantics); @@ -751,7 +752,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) { APFloat::APFloat(const fltSemantics &ourSemantics, fltCategory ourCategory, bool negative) -{ + : exponent2(0), sign2(0) { assertArithmeticOK(ourSemantics); initialize(&ourSemantics); category = ourCategory; @@ -763,14 +764,13 @@ APFloat::APFloat(const fltSemantics &ourSemantics, } APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) -{ + : exponent2(0), sign2(0) { assertArithmeticOK(ourSemantics); initialize(&ourSemantics); convertFromString(text, rmNearestTiesToEven); } -APFloat::APFloat(const APFloat &rhs) -{ +APFloat::APFloat(const APFloat &rhs) : exponent2(0), sign2(0) { initialize(rhs.semantics); assign(rhs); } @@ -3257,18 +3257,15 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) { return Val; } -APFloat::APFloat(const APInt& api, bool isIEEE) -{ +APFloat::APFloat(const APInt& api, bool isIEEE) : exponent2(0), sign2(0) { initFromAPInt(api, isIEEE); } -APFloat::APFloat(float f) -{ +APFloat::APFloat(float f) : exponent2(0), sign2(0) { initFromAPInt(APInt::floatToBits(f)); } -APFloat::APFloat(double d) -{ +APFloat::APFloat(double d) : exponent2(0), sign2(0) { initFromAPInt(APInt::doubleToBits(d)); } @@ -3565,3 +3562,37 @@ void APFloat::toString(SmallVectorImpl<char> &Str, for (; I != NDigits; ++I) Str.push_back(buffer[NDigits-I-1]); } + +bool APFloat::getExactInverse(APFloat *inv) const { + // We can only guarantee the existence of an exact inverse for IEEE floats. + if (semantics != &IEEEhalf && semantics != &IEEEsingle && + semantics != &IEEEdouble && semantics != &IEEEquad) + return false; + + // Special floats and denormals have no exact inverse. + if (category != fcNormal) + return false; + + // Check that the number is a power of two by making sure that only the + // integer bit is set in the significand. + if (significandLSB() != semantics->precision - 1) + return false; + + // Get the inverse. + APFloat reciprocal(*semantics, 1ULL); + if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK) + return false; + + // Avoid multiplication with a denormal, it is not safe on all platforms and + // may be slower than a normal division. + if (reciprocal.significandMSB() + 1 < reciprocal.semantics->precision) + return false; + + assert(reciprocal.category == fcNormal && + reciprocal.significandLSB() == reciprocal.semantics->precision - 1); + + if (inv) + *inv = reciprocal; + + return true; +} |