Add isInteger() to APFloat.
authorStephen Canon <scanon@apple.com>
Mon, 16 Nov 2015 21:52:48 +0000 (21:52 +0000)
committerStephen Canon <scanon@apple.com>
Mon, 16 Nov 2015 21:52:48 +0000 (21:52 +0000)
Useful utility function; this wasn't too hard to do before, but also wasn't
obviously discoverable.  Make it explicit.  Reviewed offline by Michael
Gottesman.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253254 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/APFloat.h
lib/Support/APFloat.cpp
unittests/ADT/APFloatTest.cpp

index 5984749ea9ab8d0519adb7c4ac05eaec7db9fad0..3fe04060fd591712a5c810e51e54e0e809e16cb9 100644 (file)
@@ -448,6 +448,9 @@ public:
   /// Returns true if and only if the number has the largest possible finite
   /// magnitude in the current semantics.
   bool isLargest() const;
   /// Returns true if and only if the number has the largest possible finite
   /// magnitude in the current semantics.
   bool isLargest() const;
+  
+  /// Returns true if and only if the number is an exact integer.
+  bool isInteger() const;
 
   /// @}
 
 
   /// @}
 
index 91b3db59d0e3d82e02271a07acf2339c1b6f1087..19b8221b60cb55389d7c9858fe93d0595c5e2c54 100644 (file)
@@ -767,6 +767,15 @@ APFloat::isLargest() const {
     && isSignificandAllOnes();
 }
 
     && isSignificandAllOnes();
 }
 
+bool
+APFloat::isInteger() const {
+  // This could be made more efficient; I'm going for obviously correct.
+  if (!isFinite()) return false;
+  APFloat truncated = *this;
+  truncated.roundToIntegral(rmTowardZero);
+  return compare(truncated) == cmpEqual;
+}
+
 bool
 APFloat::bitwiseIsEqual(const APFloat &rhs) const {
   if (this == &rhs)
 bool
 APFloat::bitwiseIsEqual(const APFloat &rhs) const {
   if (this == &rhs)
index a4445f6e4651c5b5278e5fc7c84e381d6292d136..55c3f48f00d4251e0d21e41dc7cf4330d012a165 100644 (file)
@@ -1313,7 +1313,21 @@ TEST(APFloatTest, roundToIntegral) {
   P = APFloat::getInf(APFloat::IEEEdouble, true);
   P.roundToIntegral(APFloat::rmTowardZero);
   EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);
   P = APFloat::getInf(APFloat::IEEEdouble, true);
   P.roundToIntegral(APFloat::rmTowardZero);
   EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);
-
+}
+  
+TEST(APFloatTest, isInteger) {
+  APFloat T(-0.0);
+  EXPECT_TRUE(T.isInteger());
+  T = APFloat(3.14159);
+  EXPECT_FALSE(T.isInteger());
+  T = APFloat::getNaN(APFloat::IEEEdouble);
+  EXPECT_FALSE(T.isInteger());
+  T = APFloat::getInf(APFloat::IEEEdouble);
+  EXPECT_FALSE(T.isInteger());
+  T = APFloat::getInf(APFloat::IEEEdouble, true);
+  EXPECT_FALSE(T.isInteger());
+  T = APFloat::getLargest(APFloat::IEEEdouble);
+  EXPECT_TRUE(T.isInteger());
 }
 
 TEST(APFloatTest, getLargest) {
 }
 
 TEST(APFloatTest, getLargest) {