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

Chandler Carruth chandlerc at gmail.com
Thu Oct 9 22:14:12 PDT 2014


Author: chandlerc
Date: Fri Oct 10 00:14:12 2014
New Revision: 219474

URL: http://llvm.org/viewvc/llvm-project?rev=219474&view=rev
Log:
[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.

Modified:
    llvm/trunk/include/llvm/ADT/APFloat.h
    llvm/trunk/unittests/ADT/APFloatTest.cpp

Modified: llvm/trunk/include/llvm/ADT/APFloat.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=219474&r1=219473&r2=219474&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APFloat.h (original)
+++ llvm/trunk/include/llvm/ADT/APFloat.h Fri Oct 10 00:14:12 2014
@@ -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.

Modified: llvm/trunk/unittests/ADT/APFloatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=219474&r1=219473&r2=219474&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APFloatTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APFloatTest.cpp Fri Oct 10 00:14:12 2014
@@ -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"))));
-
-  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_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)));
+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")));
+
+  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_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) {





More information about the llvm-commits mailing list