From c08f0e3743eb13e2e59de3b4a84f686cdd254b2d Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 10 Oct 2014 05:21:32 +0000 Subject: [PATCH] Add minnum / maxnum to APFloat git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219475 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/APFloat.h | 22 ++++++++++++++++++++++ unittests/ADT/APFloatTest.cpp | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index f4be7e1c6e5..b3d61a3f325 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -649,6 +649,28 @@ private: hash_code hash_value(const APFloat &Arg); APFloat scalbn(APFloat X, int Exp); +/// Implements IEEE minNum semantics. Returns the smaller of the 2 arguments if +/// both are not NaN. If either argument is a NaN, returns the other argument. +LLVM_READONLY +inline APFloat minnum(const APFloat &A, const APFloat &B) { + if (A.isNaN()) + return B; + if (B.isNaN()) + return A; + return (B.compare(A) == APFloat::cmpLessThan) ? B : A; +} + +/// Implements IEEE maxNum semantics. Returns the larger of the 2 arguments if +/// both are not NaN. If either argument is a NaN, returns the other argument. +LLVM_READONLY +inline APFloat maxnum(const APFloat &A, const APFloat &B) { + if (A.isNaN()) + return B; + if (B.isNaN()) + return A; + return (A.compare(B) == APFloat::cmpLessThan) ? B : A; +} + } // namespace llvm #endif // LLVM_ADT_APFLOAT_H diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp index 8a29b86b785..880e8317084 100644 --- a/unittests/ADT/APFloatTest.cpp +++ b/unittests/ADT/APFloatTest.cpp @@ -476,6 +476,28 @@ TEST(APFloatTest, FMA) { } } +TEST(APFloatTest, MinNum) { + APFloat f1(1.0); + APFloat f2(2.0); + APFloat nan = APFloat::getNaN(APFloat::IEEEdouble); + + EXPECT_EQ(1.0, minnum(f1, f2).convertToDouble()); + EXPECT_EQ(1.0, minnum(f2, f1).convertToDouble()); + EXPECT_EQ(1.0, minnum(f1, nan).convertToDouble()); + EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble()); +} + +TEST(APFloatTest, MaxNum) { + APFloat f1(1.0); + APFloat f2(2.0); + APFloat nan = APFloat::getNaN(APFloat::IEEEdouble); + + EXPECT_EQ(2.0, maxnum(f1, f2).convertToDouble()); + EXPECT_EQ(2.0, maxnum(f2, f1).convertToDouble()); + EXPECT_EQ(1.0, maxnum(f1, nan).convertToDouble()); + EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble()); +} + TEST(APFloatTest, Denormal) { APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;