[ADT] Replace the logb implementation with the simpler and much closer

to what we actually want ilogb implementation. This makes everything
*much* easier to deal with and is actually what we want when using it
anyways.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219474 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2014-10-10 05:14:12 +00:00
parent cb84b21243
commit f4ec6697b8
2 changed files with 45 additions and 56 deletions

View File

@ -491,20 +491,31 @@ public:
/// return true. /// return true.
bool getExactInverse(APFloat *inv) const; bool getExactInverse(APFloat *inv) const;
/// \brief Enumeration of \c ilogb error results.
enum IlogbErrorKinds {
IEK_Zero = INT_MIN+1,
IEK_NaN = INT_MIN,
IEK_Inf = INT_MAX
};
/// \brief Returns the exponent of the internal representation of the APFloat. /// \brief Returns the exponent of the internal representation of the APFloat.
/// ///
/// Because the radix of APFloat is 2, this is equivalent to floor(log2(x)). /// Because the radix of APFloat is 2, this is equivalent to floor(log2(x)).
friend APFloat logb(const APFloat &Arg) { /// For special APFloat values, this returns special error codes:
if (Arg.isZero() || Arg.isNaN()) ///
return Arg; /// NaN -> \c IEK_NaN
/// 0 -> \c IEK_Zero
/// Inf -> \c IEK_Inf
///
friend int ilogb(const APFloat &Arg) {
if (Arg.isNaN())
return IEK_NaN;
if (Arg.isZero())
return IEK_Zero;
if (Arg.isInfinity()) if (Arg.isInfinity())
return APFloat::getInf(Arg.getSemantics()); return IEK_Inf;
APFloat Result(Arg.getSemantics(), std::abs(Arg.exponent)); return Arg.exponent;
if (Arg.exponent < 0)
Result.changeSign();
return Result;
} }
/// \brief Returns: X * 2^Exp for integral exponents. /// \brief Returns: X * 2^Exp for integral exponents.

View File

@ -2692,55 +2692,33 @@ TEST(APFloatTest, operatorOverloads) {
EXPECT_TRUE(One.bitwiseIsEqual(Two / Two)); EXPECT_TRUE(One.bitwiseIsEqual(Two / Two));
} }
TEST(APFloatTest, logb) { TEST(APFloatTest, ilogb) {
EXPECT_TRUE( EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+0")));
APFloat(APFloat::IEEEsingle, "0x0p+0") EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "-0x1p+0")));
.bitwiseIsEqual(logb(APFloat(APFloat::IEEEsingle, "0x1p+0")))); EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+42")));
EXPECT_TRUE( EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p-42")));
APFloat(APFloat::IEEEsingle, "0x0p+0")
.bitwiseIsEqual(logb(APFloat(APFloat::IEEEsingle, "-0x1p+0"))));
EXPECT_TRUE(
APFloat(APFloat::IEEEsingle, "0x2Ap+0")
.bitwiseIsEqual(logb(APFloat(APFloat::IEEEsingle, "0x1p+42"))));
EXPECT_TRUE(
APFloat(APFloat::IEEEsingle, "-0x2Ap+0")
.bitwiseIsEqual(logb(APFloat(APFloat::IEEEsingle, "0x1p-42"))));
APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false); EXPECT_EQ(APFloat::IEK_Inf,
APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true); ilogb(APFloat::getInf(APFloat::IEEEsingle, false)));
APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false); EXPECT_EQ(APFloat::IEK_Inf,
APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true); ilogb(APFloat::getInf(APFloat::IEEEsingle, true)));
APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false); EXPECT_EQ(APFloat::IEK_Zero,
APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false); ilogb(APFloat::getZero(APFloat::IEEEsingle, false)));
EXPECT_EQ(APFloat::IEK_Zero,
ilogb(APFloat::getZero(APFloat::IEEEsingle, true)));
EXPECT_EQ(APFloat::IEK_NaN,
ilogb(APFloat::getNaN(APFloat::IEEEsingle, false)));
EXPECT_EQ(APFloat::IEK_NaN,
ilogb(APFloat::getSNaN(APFloat::IEEEsingle, false)));
EXPECT_TRUE(PInf.bitwiseIsEqual(logb(PInf))); EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, false)));
EXPECT_TRUE(PInf.bitwiseIsEqual(logb(MInf))); EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, true)));
EXPECT_TRUE(PZero.bitwiseIsEqual(logb(PZero))); EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, false)));
EXPECT_TRUE(MZero.bitwiseIsEqual(logb(MZero))); EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, true)));
EXPECT_TRUE(QNaN.bitwiseIsEqual(logb(QNaN))); EXPECT_EQ(-126,
EXPECT_TRUE(SNaN.bitwiseIsEqual(logb(SNaN))); ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, false)));
EXPECT_EQ(-126,
APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false); ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, true)));
APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
APFloat PSmallestNormalized =
APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
APFloat MSmallestNormalized =
APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
EXPECT_TRUE(
APFloat(APFloat::IEEEsingle, "0x7Fp+0").bitwiseIsEqual(logb(PLargestValue)));
EXPECT_TRUE(
APFloat(APFloat::IEEEsingle, "0x7Fp+0").bitwiseIsEqual(logb(MLargestValue)));
EXPECT_TRUE(
APFloat(APFloat::IEEEsingle, "-0x7Ep+0").bitwiseIsEqual(logb(PSmallestValue)));
EXPECT_TRUE(
APFloat(APFloat::IEEEsingle, "-0x7Ep+0").bitwiseIsEqual(logb(MSmallestValue)));
EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "-0x7Ep+0")
.bitwiseIsEqual(logb(PSmallestNormalized)));
EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "-0x7Ep+0")
.bitwiseIsEqual(logb(MSmallestNormalized)));
} }
TEST(APFloatTest, scalbn) { TEST(APFloatTest, scalbn) {