From 0136ee950c46aaf3922c42c48053f127490ced80 Mon Sep 17 00:00:00 2001 From: Stephen Canon Date: Mon, 16 Nov 2015 21:52:48 +0000 Subject: [PATCH] Add isInteger() to APFloat. 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 | 3 +++ lib/Support/APFloat.cpp | 9 +++++++++ unittests/ADT/APFloatTest.cpp | 16 +++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 5984749ea9a..3fe04060fd5 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -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 is an exact integer. + bool isInteger() const; /// @} diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 91b3db59d0e..19b8221b60c 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -767,6 +767,15 @@ APFloat::isLargest() const { && 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) diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp index a4445f6e465..55c3f48f00d 100644 --- a/unittests/ADT/APFloatTest.cpp +++ b/unittests/ADT/APFloatTest.cpp @@ -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); - +} + +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) { -- 2.34.1