Mercurial > hg > CbC > CbC_llvm
diff unittests/ADT/APFloatTest.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
line wrap: on
line diff
--- a/unittests/ADT/APFloatTest.cpp Sun Dec 23 19:23:36 2018 +0900 +++ b/unittests/ADT/APFloatTest.cpp Wed Aug 14 19:46:37 2019 +0900 @@ -1,9 +1,8 @@ //===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -555,6 +554,36 @@ EXPECT_EQ(1.0, maxnum(nan, f1).convertToDouble()); } +TEST(APFloatTest, Minimum) { + APFloat f1(1.0); + APFloat f2(2.0); + APFloat zp(0.0); + APFloat zn(-0.0); + APFloat nan = APFloat::getNaN(APFloat::IEEEdouble()); + + EXPECT_EQ(1.0, minimum(f1, f2).convertToDouble()); + EXPECT_EQ(1.0, minimum(f2, f1).convertToDouble()); + EXPECT_EQ(-0.0, minimum(zp, zn).convertToDouble()); + EXPECT_EQ(-0.0, minimum(zn, zp).convertToDouble()); + EXPECT_TRUE(std::isnan(minimum(f1, nan).convertToDouble())); + EXPECT_TRUE(std::isnan(minimum(nan, f1).convertToDouble())); +} + +TEST(APFloatTest, Maximum) { + APFloat f1(1.0); + APFloat f2(2.0); + APFloat zp(0.0); + APFloat zn(-0.0); + APFloat nan = APFloat::getNaN(APFloat::IEEEdouble()); + + EXPECT_EQ(2.0, maximum(f1, f2).convertToDouble()); + EXPECT_EQ(2.0, maximum(f2, f1).convertToDouble()); + EXPECT_EQ(0.0, maximum(zp, zn).convertToDouble()); + EXPECT_EQ(0.0, maximum(zn, zp).convertToDouble()); + EXPECT_TRUE(std::isnan(maximum(f1, nan).convertToDouble())); + EXPECT_TRUE(std::isnan(maximum(nan, f1).convertToDouble())); +} + TEST(APFloatTest, Denormal) { APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven; @@ -839,6 +868,33 @@ EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble(), "002.05000e+12").convertToDouble()); EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble(), "002.05000e-12").convertToDouble()); + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e").convertToDouble()); + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1e").convertToDouble()); + EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1e").convertToDouble()); + + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.e").convertToDouble()); + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1.e").convertToDouble()); + EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1.e").convertToDouble()); + + EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble()); + EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), "+.1e").convertToDouble()); + EXPECT_EQ(-0.1, APFloat(APFloat::IEEEdouble(), "-.1e").convertToDouble()); + + EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "1.1e").convertToDouble()); + EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "+1.1e").convertToDouble()); + EXPECT_EQ(-1.1, APFloat(APFloat::IEEEdouble(), "-1.1e").convertToDouble()); + + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e+").convertToDouble()); + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e-").convertToDouble()); + + EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble()); + EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e+").convertToDouble()); + EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e-").convertToDouble()); + + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e").convertToDouble()); + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e+").convertToDouble()); + EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e-").convertToDouble()); + // These are "carefully selected" to overflow the fast log-base // calculations in APFloat.cpp EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999").isInfinity()); @@ -983,6 +1039,13 @@ ASSERT_EQ("8.73183400000000010e+02", convertToString(873.1834, 0, 0, false)); ASSERT_EQ("1.79769313486231570e+308", convertToString(1.7976931348623157E+308, 0, 0, false)); + + { + SmallString<64> Str; + APFloat UnnormalZero(APFloat::x87DoubleExtended(), APInt(80, {0, 1})); + UnnormalZero.toString(Str); + ASSERT_EQ("NaN", Str); + } } TEST(APFloatTest, toInteger) { @@ -1033,33 +1096,49 @@ EXPECT_EQ(APSInt::getMaxValue(5, false), result); } -static APInt nanbits(const fltSemantics &Sem, - bool SNaN, bool Negative, uint64_t fill) { - APInt apfill(64, fill); +static APInt nanbitsFromAPInt(const fltSemantics &Sem, bool SNaN, bool Negative, + uint64_t payload) { + APInt appayload(64, payload); if (SNaN) - return APFloat::getSNaN(Sem, Negative, &apfill).bitcastToAPInt(); + return APFloat::getSNaN(Sem, Negative, &appayload).bitcastToAPInt(); else - return APFloat::getQNaN(Sem, Negative, &apfill).bitcastToAPInt(); + return APFloat::getQNaN(Sem, Negative, &appayload).bitcastToAPInt(); } TEST(APFloatTest, makeNaN) { - ASSERT_EQ(0x7fc00000, nanbits(APFloat::IEEEsingle(), false, false, 0)); - ASSERT_EQ(0xffc00000, nanbits(APFloat::IEEEsingle(), false, true, 0)); - ASSERT_EQ(0x7fc0ae72, nanbits(APFloat::IEEEsingle(), false, false, 0xae72)); - ASSERT_EQ(0x7fffae72, nanbits(APFloat::IEEEsingle(), false, false, 0xffffae72)); - ASSERT_EQ(0x7fa00000, nanbits(APFloat::IEEEsingle(), true, false, 0)); - ASSERT_EQ(0xffa00000, nanbits(APFloat::IEEEsingle(), true, true, 0)); - ASSERT_EQ(0x7f80ae72, nanbits(APFloat::IEEEsingle(), true, false, 0xae72)); - ASSERT_EQ(0x7fbfae72, nanbits(APFloat::IEEEsingle(), true, false, 0xffffae72)); - - ASSERT_EQ(0x7ff8000000000000ULL, nanbits(APFloat::IEEEdouble(), false, false, 0)); - ASSERT_EQ(0xfff8000000000000ULL, nanbits(APFloat::IEEEdouble(), false, true, 0)); - ASSERT_EQ(0x7ff800000000ae72ULL, nanbits(APFloat::IEEEdouble(), false, false, 0xae72)); - ASSERT_EQ(0x7fffffffffffae72ULL, nanbits(APFloat::IEEEdouble(), false, false, 0xffffffffffffae72ULL)); - ASSERT_EQ(0x7ff4000000000000ULL, nanbits(APFloat::IEEEdouble(), true, false, 0)); - ASSERT_EQ(0xfff4000000000000ULL, nanbits(APFloat::IEEEdouble(), true, true, 0)); - ASSERT_EQ(0x7ff000000000ae72ULL, nanbits(APFloat::IEEEdouble(), true, false, 0xae72)); - ASSERT_EQ(0x7ff7ffffffffae72ULL, nanbits(APFloat::IEEEdouble(), true, false, 0xffffffffffffae72ULL)); + const struct { + uint64_t expected; + const fltSemantics &semantics; + bool SNaN; + bool Negative; + uint64_t payload; + } tests[] = { + /* expected semantics SNaN Neg payload */ + { 0x7fc00000ULL, APFloat::IEEEsingle(), false, false, 0x00000000ULL }, + { 0xffc00000ULL, APFloat::IEEEsingle(), false, true, 0x00000000ULL }, + { 0x7fc0ae72ULL, APFloat::IEEEsingle(), false, false, 0x0000ae72ULL }, + { 0x7fffae72ULL, APFloat::IEEEsingle(), false, false, 0xffffae72ULL }, + { 0x7fdaae72ULL, APFloat::IEEEsingle(), false, false, 0x00daae72ULL }, + { 0x7fa00000ULL, APFloat::IEEEsingle(), true, false, 0x00000000ULL }, + { 0xffa00000ULL, APFloat::IEEEsingle(), true, true, 0x00000000ULL }, + { 0x7f80ae72ULL, APFloat::IEEEsingle(), true, false, 0x0000ae72ULL }, + { 0x7fbfae72ULL, APFloat::IEEEsingle(), true, false, 0xffffae72ULL }, + { 0x7f9aae72ULL, APFloat::IEEEsingle(), true, false, 0x001aae72ULL }, + { 0x7ff8000000000000ULL, APFloat::IEEEdouble(), false, false, 0x0000000000000000ULL }, + { 0xfff8000000000000ULL, APFloat::IEEEdouble(), false, true, 0x0000000000000000ULL }, + { 0x7ff800000000ae72ULL, APFloat::IEEEdouble(), false, false, 0x000000000000ae72ULL }, + { 0x7fffffffffffae72ULL, APFloat::IEEEdouble(), false, false, 0xffffffffffffae72ULL }, + { 0x7ffdaaaaaaaaae72ULL, APFloat::IEEEdouble(), false, false, 0x000daaaaaaaaae72ULL }, + { 0x7ff4000000000000ULL, APFloat::IEEEdouble(), true, false, 0x0000000000000000ULL }, + { 0xfff4000000000000ULL, APFloat::IEEEdouble(), true, true, 0x0000000000000000ULL }, + { 0x7ff000000000ae72ULL, APFloat::IEEEdouble(), true, false, 0x000000000000ae72ULL }, + { 0x7ff7ffffffffae72ULL, APFloat::IEEEdouble(), true, false, 0xffffffffffffae72ULL }, + { 0x7ff1aaaaaaaaae72ULL, APFloat::IEEEdouble(), true, false, 0x0001aaaaaaaaae72ULL }, + }; + + for (const auto &t : tests) { + ASSERT_EQ(t.expected, nanbitsFromAPInt(t.semantics, t.SNaN, t.Negative, t.payload)); + } } #ifdef GTEST_HAS_DEATH_TEST @@ -1113,36 +1192,6 @@ EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e"), "Significand has no digits"); } -TEST(APFloatTest, StringDecimalExponentDeath) { - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1e"), "Exponent has no digits"); - - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.e"), "Exponent has no digits"); - - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.1e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.1e"), "Exponent has no digits"); - - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.1e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.1e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.1e"), "Exponent has no digits"); - - - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e+"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e-"), "Exponent has no digits"); - - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e+"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e-"), "Exponent has no digits"); - - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e+"), "Exponent has no digits"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e-"), "Exponent has no digits"); -} - TEST(APFloatTest, StringHexadecimalDeath) { EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x"), "Invalid string"); EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x"), "Invalid string");