aboutsummaryrefslogtreecommitdiffstats
path: root/unittests/ADT/APFloatTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/ADT/APFloatTest.cpp')
-rw-r--r--unittests/ADT/APFloatTest.cpp601
1 files changed, 601 insertions, 0 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index 2789835..e1b9158 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -33,6 +33,449 @@ static std::string convertToString(double d, unsigned Prec, unsigned Pad) {
namespace {
+TEST(APFloatTest, isSignaling) {
+ // We test qNaN, -qNaN, +sNaN, -sNaN with and without payloads. *NOTE* The
+ // positive/negative distinction is included only since the getQNaN/getSNaN
+ // API provides the option.
+ APInt payload = APInt::getOneBitSet(4, 2);
+ EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, false).isSignaling());
+ EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, true).isSignaling());
+ EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, false, &payload).isSignaling());
+ EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, true, &payload).isSignaling());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false).isSignaling());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true).isSignaling());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false, &payload).isSignaling());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true, &payload).isSignaling());
+}
+
+TEST(APFloatTest, next) {
+
+ APFloat test(APFloat::IEEEquad, APFloat::uninitialized);
+ APFloat expected(APFloat::IEEEquad, APFloat::uninitialized);
+
+ // 1. Test Special Cases Values.
+ //
+ // Test all special values for nextUp and nextDown perscribed by IEEE-754R
+ // 2008. These are:
+ // 1. +inf
+ // 2. -inf
+ // 3. getLargest()
+ // 4. -getLargest()
+ // 5. getSmallest()
+ // 6. -getSmallest()
+ // 7. qNaN
+ // 8. sNaN
+ // 9. +0
+ // 10. -0
+
+ // nextUp(+inf) = +inf.
+ test = APFloat::getInf(APFloat::IEEEquad, false);
+ expected = APFloat::getInf(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isInfinity());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+inf) = -nextUp(-inf) = -(-getLargest()) = getLargest()
+ test = APFloat::getInf(APFloat::IEEEquad, false);
+ expected = APFloat::getLargest(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-inf) = -getLargest()
+ test = APFloat::getInf(APFloat::IEEEquad, true);
+ expected = APFloat::getLargest(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-inf) = -nextUp(+inf) = -(+inf) = -inf.
+ test = APFloat::getInf(APFloat::IEEEquad, true);
+ expected = APFloat::getInf(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isInfinity() && test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(getLargest()) = +inf
+ test = APFloat::getLargest(APFloat::IEEEquad, false);
+ expected = APFloat::getInf(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isInfinity() && !test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(getLargest()) = -nextUp(-getLargest())
+ // = -(-getLargest() + inc)
+ // = getLargest() - inc.
+ test = APFloat::getLargest(APFloat::IEEEquad, false);
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.fffffffffffffffffffffffffffep+16383");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isInfinity() && !test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-getLargest()) = -getLargest() + inc.
+ test = APFloat::getLargest(APFloat::IEEEquad, true);
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.fffffffffffffffffffffffffffep+16383");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-getLargest()) = -nextUp(getLargest()) = -(inf) = -inf.
+ test = APFloat::getLargest(APFloat::IEEEquad, true);
+ expected = APFloat::getInf(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isInfinity() && test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(getSmallest()) = getSmallest() + inc.
+ test = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x0.0000000000000000000000000002p-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(getSmallest()) = -nextUp(-getSmallest()) = -(-0) = +0.
+ test = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
+ expected = APFloat::getZero(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isZero() && !test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-getSmallest()) = -0.
+ test = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
+ expected = APFloat::getZero(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isZero() && test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-getSmallest()) = -nextUp(getSmallest()) = -getSmallest() - inc.
+ test = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.0000000000000000000000000002p-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(qNaN) = qNaN
+ test = APFloat::getQNaN(APFloat::IEEEquad, false);
+ expected = APFloat::getQNaN(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(qNaN) = qNaN
+ test = APFloat::getQNaN(APFloat::IEEEquad, false);
+ expected = APFloat::getQNaN(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(sNaN) = qNaN
+ test = APFloat::getSNaN(APFloat::IEEEquad, false);
+ expected = APFloat::getQNaN(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opInvalidOp);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(sNaN) = qNaN
+ test = APFloat::getSNaN(APFloat::IEEEquad, false);
+ expected = APFloat::getQNaN(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(true), APFloat::opInvalidOp);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(+0) = +getSmallest()
+ test = APFloat::getZero(APFloat::IEEEquad, false);
+ expected = APFloat::getSmallest(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+0) = -nextUp(-0) = -getSmallest()
+ test = APFloat::getZero(APFloat::IEEEquad, false);
+ expected = APFloat::getSmallest(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-0) = +getSmallest()
+ test = APFloat::getZero(APFloat::IEEEquad, true);
+ expected = APFloat::getSmallest(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-0) = -nextUp(0) = -getSmallest()
+ test = APFloat::getZero(APFloat::IEEEquad, true);
+ expected = APFloat::getSmallest(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 2. Binade Boundary Tests.
+
+ // 2a. Test denormal <-> normal binade boundaries.
+ // * nextUp(+Largest Denormal) -> +Smallest Normal.
+ // * nextDown(-Largest Denormal) -> -Smallest Normal.
+ // * nextUp(-Smallest Normal) -> -Largest Denormal.
+ // * nextDown(+Smallest Normal) -> +Largest Denormal.
+
+ // nextUp(+Largest Denormal) -> +Smallest Normal.
+ test = APFloat(APFloat::IEEEquad, "0x0.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.0000000000000000000000000000p-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Largest Denormal) -> -Smallest Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.0000000000000000000000000000p-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-Smallest Normal) -> -LargestDenormal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x1.0000000000000000000000000000p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffffffffp-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Smallest Normal) -> +Largest Denormal.
+ test = APFloat(APFloat::IEEEquad,
+ "+0x1.0000000000000000000000000000p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "+0x0.ffffffffffffffffffffffffffffp-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 2b. Test normal <-> normal binade boundaries.
+ // * nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
+ // * nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
+ // * nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
+ // * nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
+
+ // nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
+ test = APFloat(APFloat::IEEEquad, "-0x1p+1");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffffffffp+0");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
+ test = APFloat(APFloat::IEEEquad, "0x1p+1");
+ expected = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp+0");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
+ test = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp+0");
+ expected = APFloat(APFloat::IEEEquad, "0x1p+1");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
+ test = APFloat(APFloat::IEEEquad, "-0x1.ffffffffffffffffffffffffffffp+0");
+ expected = APFloat(APFloat::IEEEquad, "-0x1p+1");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 2c. Test using next at binade boundaries with a direction away from the
+ // binade boundary. Away from denormal <-> normal boundaries.
+ //
+ // This is to make sure that even though we are at a binade boundary, since
+ // we are rounding away, we do not trigger the binade boundary code. Thus we
+ // test:
+ // * nextUp(-Largest Denormal) -> -Largest Denormal + inc.
+ // * nextDown(+Largest Denormal) -> +Largest Denormal - inc.
+ // * nextUp(+Smallest Normal) -> +Smallest Normal + inc.
+ // * nextDown(-Smallest Normal) -> -Smallest Normal - inc.
+
+ // nextUp(-Largest Denormal) -> -Largest Denormal + inc.
+ test = APFloat(APFloat::IEEEquad, "-0x0.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.fffffffffffffffffffffffffffep-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Largest Denormal) -> +Largest Denormal - inc.
+ test = APFloat(APFloat::IEEEquad, "0x0.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x0.fffffffffffffffffffffffffffep-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(+Smallest Normal) -> +Smallest Normal + inc.
+ test = APFloat(APFloat::IEEEquad, "0x1.0000000000000000000000000000p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.0000000000000000000000000001p-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Smallest Normal) -> -Smallest Normal - inc.
+ test = APFloat(APFloat::IEEEquad, "-0x1.0000000000000000000000000000p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.0000000000000000000000000001p-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 2d. Test values which cause our exponent to go to min exponent. This
+ // is to ensure that guards in the code to check for min exponent
+ // trigger properly.
+ // * nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
+ // * nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
+ // -0x1p-16381
+ // * nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16382
+ // * nextDown(0x1p-16382) -> 0x1.ffffffffffffffffffffffffffffp-16382
+
+ // nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
+ test = APFloat(APFloat::IEEEquad, "-0x1p-16381");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffffffffp-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
+ // -0x1p-16381
+ test = APFloat(APFloat::IEEEquad, "-0x1.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad, "-0x1p-16381");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16381
+ test = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad, "0x1p-16381");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(0x1p-16381) -> 0x1.ffffffffffffffffffffffffffffp-16382
+ test = APFloat(APFloat::IEEEquad, "0x1p-16381");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffffffffp-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 3. Now we test both denormal/normal computation which will not cause us
+ // to go across binade boundaries. Specifically we test:
+ // * nextUp(+Denormal) -> +Denormal.
+ // * nextDown(+Denormal) -> +Denormal.
+ // * nextUp(-Denormal) -> -Denormal.
+ // * nextDown(-Denormal) -> -Denormal.
+ // * nextUp(+Normal) -> +Normal.
+ // * nextDown(+Normal) -> +Normal.
+ // * nextUp(-Normal) -> -Normal.
+ // * nextDown(-Normal) -> -Normal.
+
+ // nextUp(+Denormal) -> +Denormal.
+ test = APFloat(APFloat::IEEEquad,
+ "0x0.ffffffffffffffffffffffff000cp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x0.ffffffffffffffffffffffff000dp-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Denormal) -> +Denormal.
+ test = APFloat(APFloat::IEEEquad,
+ "0x0.ffffffffffffffffffffffff000cp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x0.ffffffffffffffffffffffff000bp-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-Denormal) -> -Denormal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffff000cp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffff000bp-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Denormal) -> -Denormal
+ test = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffff000cp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffff000dp-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(+Normal) -> +Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffff000cp-16000");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffff000dp-16000");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Normal) -> +Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffff000cp-16000");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffff000bp-16000");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-Normal) -> -Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffff000cp-16000");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffff000bp-16000");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Normal) -> -Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffff000cp-16000");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffff000dp-16000");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+}
+
+TEST(APFloatTest, FMA) {
+ APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
+
+ {
+ APFloat f1(14.5f);
+ APFloat f2(-14.5f);
+ APFloat f3(225.0f);
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(14.75f, f1.convertToFloat());
+ }
+
+ {
+ APFloat Val2(2.0f);
+ APFloat f1((float)1.17549435e-38F);
+ APFloat f2((float)1.17549435e-38F);
+ f1.divide(Val2, rdmd);
+ f2.divide(Val2, rdmd);
+ APFloat f3(12.0f);
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(12.0f, f1.convertToFloat());
+ }
+}
+
TEST(APFloatTest, Denormal) {
APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
@@ -771,6 +1214,103 @@ TEST(APFloatTest, getLargest) {
EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble).convertToDouble());
}
+TEST(APFloatTest, getSmallest) {
+ APFloat test = APFloat::getSmallest(APFloat::IEEEsingle, false);
+ APFloat expected = APFloat(APFloat::IEEEsingle, "0x0.000002p-126");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isNormal());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallest(APFloat::IEEEsingle, true);
+ expected = APFloat(APFloat::IEEEsingle, "-0x0.000002p-126");
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.isNormal());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallest(APFloat::IEEEquad, false);
+ expected = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isNormal());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallest(APFloat::IEEEquad, true);
+ expected = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.isNormal());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+}
+
+TEST(APFloatTest, getSmallestNormalized) {
+ APFloat test = APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
+ APFloat expected = APFloat(APFloat::IEEEsingle, "0x1p-126");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isNormal());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
+ expected = APFloat(APFloat::IEEEsingle, "-0x1p-126");
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.isNormal());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallestNormalized(APFloat::IEEEquad, false);
+ expected = APFloat(APFloat::IEEEquad, "0x1p-16382");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isNormal());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallestNormalized(APFloat::IEEEquad, true);
+ expected = APFloat(APFloat::IEEEquad, "-0x1p-16382");
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.isNormal());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+}
+
+TEST(APFloatTest, getZero) {
+ struct {
+ const fltSemantics *semantics;
+ const bool sign;
+ const unsigned long long bitPattern[2];
+ const unsigned bitPatternLength;
+ } const GetZeroTest[] = {
+ { &APFloat::IEEEhalf, false, {0, 0}, 1},
+ { &APFloat::IEEEhalf, true, {0x8000ULL, 0}, 1},
+ { &APFloat::IEEEsingle, false, {0, 0}, 1},
+ { &APFloat::IEEEsingle, true, {0x80000000ULL, 0}, 1},
+ { &APFloat::IEEEdouble, false, {0, 0}, 1},
+ { &APFloat::IEEEdouble, true, {0x8000000000000000ULL, 0}, 1},
+ { &APFloat::IEEEquad, false, {0, 0}, 2},
+ { &APFloat::IEEEquad, true, {0, 0x8000000000000000ULL}, 2},
+ { &APFloat::PPCDoubleDouble, false, {0, 0}, 2},
+ { &APFloat::PPCDoubleDouble, true, {0x8000000000000000ULL, 0}, 2},
+ { &APFloat::x87DoubleExtended, false, {0, 0}, 2},
+ { &APFloat::x87DoubleExtended, true, {0, 0x8000ULL}, 2},
+ };
+ const unsigned NumGetZeroTests = 12;
+ for (unsigned i = 0; i < NumGetZeroTests; ++i) {
+ APFloat test = APFloat::getZero(*GetZeroTest[i].semantics,
+ GetZeroTest[i].sign);
+ const char *pattern = GetZeroTest[i].sign? "-0x0p+0" : "0x0p+0";
+ APFloat expected = APFloat(*GetZeroTest[i].semantics,
+ pattern);
+ EXPECT_TRUE(test.isZero());
+ EXPECT_TRUE(GetZeroTest[i].sign? test.isNegative() : !test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+ for (unsigned j = 0, je = GetZeroTest[i].bitPatternLength; j < je; ++j) {
+ EXPECT_EQ(GetZeroTest[i].bitPattern[j],
+ test.bitcastToAPInt().getRawData()[j]);
+ }
+ }
+}
+
TEST(APFloatTest, convert) {
bool losesInfo;
APFloat test(APFloat::IEEEdouble, "1.0");
@@ -857,4 +1397,65 @@ TEST(APFloatTest, PPCDoubleDouble) {
EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
#endif
}
+
+TEST(APFloatTest, isNegative) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_FALSE(t.isNegative());
+ t = APFloat(APFloat::IEEEsingle, "-0x1p+0");
+ EXPECT_TRUE(t.isNegative());
+
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isNegative());
+ EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle, true).isNegative());
+
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isNegative());
+ EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle, true).isNegative());
+
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isNegative());
+ EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle, true).isNegative());
+
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isNegative());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true).isNegative());
+}
+
+TEST(APFloatTest, isIEEENormal) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_TRUE(t.isIEEENormal());
+
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isIEEENormal());
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isIEEENormal());
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isIEEENormal());
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isIEEENormal());
+ EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-159").isIEEENormal());
+}
+
+TEST(APFloatTest, isFinite) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_TRUE(t.isFinite());
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isFinite());
+ EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle, false).isFinite());
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isFinite());
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isFinite());
+ EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "0x1p-159").isFinite());
+}
+
+TEST(APFloatTest, isInfinity) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_FALSE(t.isInfinity());
+ EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle, false).isInfinity());
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isInfinity());
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isInfinity());
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isInfinity());
+ EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-159").isInfinity());
+}
+
+TEST(APFloatTest, isNaN) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_FALSE(t.isNaN());
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isNaN());
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isNaN());
+ EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle, false).isNaN());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false).isNaN());
+ EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-159").isNaN());
+}
+
}