[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.
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.
///
/// Because the radix of APFloat is 2, this is equivalent to floor(log2(x)).
friend APFloat logb(const APFloat &Arg) {
if (Arg.isZero() || Arg.isNaN())
return Arg;
/// For special APFloat values, this returns special error codes:
///
/// 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())
return APFloat::getInf(Arg.getSemantics());
return IEK_Inf;
APFloat Result(Arg.getSemantics(), std::abs(Arg.exponent));
if (Arg.exponent < 0)
Result.changeSign();
return Result;
return Arg.exponent;
}
/// \brief Returns: X * 2^Exp for integral exponents.

View File

@ -2692,55 +2692,33 @@ TEST(APFloatTest, operatorOverloads) {
EXPECT_TRUE(One.bitwiseIsEqual(Two / Two));
}
TEST(APFloatTest, logb) {
EXPECT_TRUE(
APFloat(APFloat::IEEEsingle, "0x0p+0")
.bitwiseIsEqual(logb(APFloat(APFloat::IEEEsingle, "0x1p+0"))));
EXPECT_TRUE(
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"))));
TEST(APFloatTest, ilogb) {
EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+0")));
EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "-0x1p+0")));
EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+42")));
EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p-42")));
APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
EXPECT_EQ(APFloat::IEK_Inf,
ilogb(APFloat::getInf(APFloat::IEEEsingle, false)));
EXPECT_EQ(APFloat::IEK_Inf,
ilogb(APFloat::getInf(APFloat::IEEEsingle, true)));
EXPECT_EQ(APFloat::IEK_Zero,
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_TRUE(PInf.bitwiseIsEqual(logb(MInf)));
EXPECT_TRUE(PZero.bitwiseIsEqual(logb(PZero)));
EXPECT_TRUE(MZero.bitwiseIsEqual(logb(MZero)));
EXPECT_TRUE(QNaN.bitwiseIsEqual(logb(QNaN)));
EXPECT_TRUE(SNaN.bitwiseIsEqual(logb(SNaN)));
APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
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)));
EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, false)));
EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, true)));
EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, false)));
EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, true)));
EXPECT_EQ(-126,
ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, false)));
EXPECT_EQ(-126,
ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, true)));
}
TEST(APFloatTest, scalbn) {