diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt --- a/libc/src/__support/FPUtil/CMakeLists.txt +++ b/libc/src/__support/FPUtil/CMakeLists.txt @@ -36,7 +36,9 @@ .platform_defs .float_properties libc.src.__support.builtin_wrappers + libc.src.__support.integer_to_string libc.src.__support.CPP.bit + libc.src.__support.CPP.string libc.src.__support.CPP.type_traits libc.src.__support.common ) diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h --- a/libc/src/__support/FPUtil/FPBits.h +++ b/libc/src/__support/FPUtil/FPBits.h @@ -12,9 +12,11 @@ #include "PlatformDefs.h" #include "src/__support/CPP/bit.h" +#include "src/__support/CPP/string.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/builtin_wrappers.h" #include "src/__support/common.h" +#include "src/__support/integer_to_string.h" #include "FloatProperties.h" #include @@ -213,6 +215,47 @@ result.set_mantissa(mantissa); return result; } + + // Converts the bits to a string in the following format: + // "0x = S: N, E: 0xNNNN, M:0xNNN...N" + // 1. N is a hexadecimal digit. + // 2. The hexadecimal number on the LHS is the raw numerical representation + // of the bits. + // 3. The exponent is always 16 bits wide irrespective of the type of the + // floating encoding. + LIBC_INLINE cpp::string str() const { + if (is_nan()) + return "(NaN)"; + if (is_inf()) + return get_sign() ? "(-Infinity)" : "(+Infinity)"; + + auto zerofill = [](char *arr, size_t n) { + for (size_t i = 0; i < n; ++i) + arr[i] = '0'; + }; + + cpp::string s("0x"); + char bitsbuf[IntegerToString::hex_bufsize()]; + zerofill(bitsbuf, sizeof(bitsbuf)); + IntegerToString::hex(bits, bitsbuf, false); + s += cpp::string(bitsbuf, sizeof(bitsbuf)); + + s += " = ("; + s += cpp::string("S: ") + (get_sign() ? "1" : "0"); + + char expbuf[IntegerToString::hex_bufsize()]; + zerofill(expbuf, sizeof(expbuf)); + IntegerToString::hex(get_unbiased_exponent(), expbuf, false); + s += cpp::string(", E: 0x") + cpp::string(expbuf, sizeof(expbuf)); + + char mantbuf[IntegerToString::hex_bufsize()] = {'0'}; + zerofill(mantbuf, sizeof(mantbuf)); + IntegerToString::hex(get_mantissa(), mantbuf, false); + s += cpp::string(", M: 0x") + cpp::string(mantbuf, sizeof(mantbuf)); + + s += ")"; + return s; + } }; } // namespace fputil diff --git a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h --- a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h +++ b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h @@ -10,8 +10,10 @@ #define LLVM_LIBC_SRC_SUPPORT_FPUTIL_X86_64_LONG_DOUBLE_BITS_H #include "src/__support/CPP/bit.h" +#include "src/__support/CPP/string.h" #include "src/__support/UInt128.h" #include "src/__support/common.h" +#include "src/__support/integer_to_string.h" #include "src/__support/macros/properties/architectures.h" #if !defined(LIBC_TARGET_ARCH_IS_X86) @@ -207,6 +209,50 @@ result.set_mantissa(mantissa); return result; } + + // Converts the bits to a string in the following format: + // "0x = S: N, E: 0xNNNN, I: N, M:0xNNN...N" + // 1. N is a hexadecimal digit. + // 2. "I" denotes the implicit bit. + // 3. The hexadecimal number on the LHS is the raw numerical representation + // of the bits. + // 4. The exponent is always 16 bits wide irrespective of the type of the + // floating encoding. + LIBC_INLINE cpp::string str() const { + if (is_nan()) + return "(NaN)"; + if (is_inf()) + return get_sign() ? "(-Infinity)" : "(+Infinity)"; + + auto zerofill = [](char *arr, size_t n) { + for (size_t i = 0; i < n; ++i) + arr[i] = '0'; + }; + + cpp::string s("0x"); + char bitsbuf[IntegerToString::hex_bufsize()] = {'0'}; + zerofill(bitsbuf, sizeof(bitsbuf)); + IntegerToString::hex(bits, bitsbuf, false); + s += cpp::string(bitsbuf, sizeof(bitsbuf)); + + s += " = ("; + s += cpp::string("S: ") + (get_sign() ? "1" : "0"); + + char expbuf[IntegerToString::hex_bufsize()] = {'0'}; + zerofill(expbuf, sizeof(expbuf)); + IntegerToString::hex(get_unbiased_exponent(), expbuf, false); + s += cpp::string(", E: 0x") + cpp::string(expbuf, sizeof(expbuf)); + + s += cpp::string(", I: ") + (get_implicit_bit() ? "1" : "0"); + + char mantbuf[IntegerToString::hex_bufsize()] = {'0'}; + zerofill(mantbuf, sizeof(mantbuf)); + IntegerToString::hex(get_mantissa(), mantbuf, false); + s += cpp::string(", M: 0x") + cpp::string(mantbuf, sizeof(mantbuf)); + + s += ")"; + return s; + } }; static_assert( diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h --- a/libc/test/UnitTest/FPMatcher.h +++ b/libc/test/UnitTest/FPMatcher.h @@ -21,43 +21,6 @@ namespace fputil { namespace testing { -template -cpp::enable_if_t, void> -describeValue(const char *label, ValType value) { - __llvm_libc::testing::tlog << label; - - FPBits bits(value); - if (bits.is_nan()) { - __llvm_libc::testing::tlog << "(NaN)"; - } else if (bits.is_inf()) { - if (bits.get_sign()) - __llvm_libc::testing::tlog << "(-Infinity)"; - else - __llvm_libc::testing::tlog << "(+Infinity)"; - } else { - constexpr int exponentWidthInHex = - (fputil::ExponentWidth::VALUE - 1) / 4 + 1; - constexpr int mantissaWidthInHex = - (fputil::MantissaWidth::VALUE - 1) / 4 + 1; - constexpr int bitsWidthInHex = - sizeof(typename fputil::FPBits::UIntType) * 2; - - __llvm_libc::testing::tlog - << "0x" - << int_to_hex::UIntType>( - bits.uintval(), bitsWidthInHex) - << ", (S | E | M) = (" << (bits.get_sign() ? '1' : '0') << " | 0x" - << int_to_hex(bits.get_unbiased_exponent(), - exponentWidthInHex) - << " | 0x" - << int_to_hex::UIntType>( - bits.get_mantissa(), mantissaWidthInHex) - << ")"; - } - - __llvm_libc::testing::tlog << '\n'; -} - template class FPMatcher : public __llvm_libc::testing::Matcher { static_assert(__llvm_libc::cpp::is_floating_point_v, @@ -87,8 +50,11 @@ } void explainError() override { - describeValue("Expected floating point value: ", expected); - describeValue(" Actual floating point value: ", actual); + __llvm_libc::testing::tlog + << "Expected floating point value: " << FPBits(expected).str() + << '\n'; + __llvm_libc::testing::tlog + << "Actual floating point value: " << FPBits(actual).str() << '\n'; } }; diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt --- a/libc/test/src/__support/FPUtil/CMakeLists.txt +++ b/libc/test/src/__support/FPUtil/CMakeLists.txt @@ -10,3 +10,13 @@ DEPENDS libc.src.__support.FPUtil.dyadic_float ) + +add_libc_test( + fpbits_test + SUITE + libc-fputil-tests + SRCS + fpbits_test.cpp + DEPENDS + libc.src.__support.FPUtil.fp_bits +) diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp @@ -0,0 +1,239 @@ +//===-- Unittests for the DyadicFloat class -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/FPUtil/FPBits.h" +#include "test/UnitTest/Test.h" + +using __llvm_libc::fputil::FPBits; + +TEST(LlvmLibcFPBitsTest, FloatType) { + EXPECT_STREQ(FPBits::inf().str().c_str(), "(+Infinity)"); + EXPECT_STREQ(FPBits::neg_inf().str().c_str(), "(-Infinity)"); + EXPECT_STREQ(FPBits(FPBits::build_nan(1)).str().c_str(), + "(NaN)"); + + FPBits zero(0.0f); + EXPECT_EQ(zero.get_sign(), false); + EXPECT_EQ(zero.get_unbiased_exponent(), static_cast(0)); + EXPECT_EQ(zero.get_mantissa(), static_cast(0)); + EXPECT_EQ(zero.uintval(), static_cast(0x00000000)); + EXPECT_STREQ(zero.str().c_str(), + "0x00000000 = (S: 0, E: 0x0000, M: 0x00000000)"); + + FPBits negzero(-0.0f); + EXPECT_EQ(negzero.get_sign(), true); + EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast(0)); + EXPECT_EQ(negzero.get_mantissa(), static_cast(0)); + EXPECT_EQ(negzero.uintval(), static_cast(0x80000000)); + EXPECT_STREQ(negzero.str().c_str(), + "0x80000000 = (S: 1, E: 0x0000, M: 0x00000000)"); + + FPBits one(1.0f); + EXPECT_EQ(one.get_sign(), false); + EXPECT_EQ(one.get_unbiased_exponent(), static_cast(0x7F)); + EXPECT_EQ(one.get_mantissa(), static_cast(0)); + EXPECT_EQ(one.uintval(), static_cast(0x3F800000)); + EXPECT_STREQ(one.str().c_str(), + "0x3F800000 = (S: 0, E: 0x007F, M: 0x00000000)"); + + FPBits negone(-1.0f); + EXPECT_EQ(negone.get_sign(), true); + EXPECT_EQ(negone.get_unbiased_exponent(), static_cast(0x7F)); + EXPECT_EQ(negone.get_mantissa(), static_cast(0)); + EXPECT_EQ(negone.uintval(), static_cast(0xBF800000)); + EXPECT_STREQ(negone.str().c_str(), + "0xBF800000 = (S: 1, E: 0x007F, M: 0x00000000)"); + + FPBits num(1.125f); + EXPECT_EQ(num.get_sign(), false); + EXPECT_EQ(num.get_unbiased_exponent(), static_cast(0x7F)); + EXPECT_EQ(num.get_mantissa(), static_cast(0x00100000)); + EXPECT_EQ(num.uintval(), static_cast(0x3F900000)); + EXPECT_STREQ(num.str().c_str(), + "0x3F900000 = (S: 0, E: 0x007F, M: 0x00100000)"); + + FPBits negnum(-1.125f); + EXPECT_EQ(negnum.get_sign(), true); + EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast(0x7F)); + EXPECT_EQ(negnum.get_mantissa(), static_cast(0x00100000)); + EXPECT_EQ(negnum.uintval(), static_cast(0xBF900000)); + EXPECT_STREQ(negnum.str().c_str(), + "0xBF900000 = (S: 1, E: 0x007F, M: 0x00100000)"); +} + +TEST(LlvmLibcFPBitsTest, DoubleType) { + EXPECT_STREQ(FPBits::inf().str().c_str(), "(+Infinity)"); + EXPECT_STREQ(FPBits::neg_inf().str().c_str(), "(-Infinity)"); + EXPECT_STREQ(FPBits(FPBits::build_nan(1)).str().c_str(), + "(NaN)"); + + FPBits zero(0.0); + EXPECT_EQ(zero.get_sign(), false); + EXPECT_EQ(zero.get_unbiased_exponent(), static_cast(0x0000)); + EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000)); + EXPECT_EQ(zero.uintval(), static_cast(0x0000000000000000)); + EXPECT_STREQ(zero.str().c_str(), + "0x0000000000000000 = (S: 0, E: 0x0000, M: 0x0000000000000000)"); + + FPBits negzero(-0.0); + EXPECT_EQ(negzero.get_sign(), true); + EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast(0x0000)); + EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000)); + EXPECT_EQ(negzero.uintval(), static_cast(0x8000000000000000)); + EXPECT_STREQ(negzero.str().c_str(), + "0x8000000000000000 = (S: 1, E: 0x0000, M: 0x0000000000000000)"); + + FPBits one(1.0); + EXPECT_EQ(one.get_sign(), false); + EXPECT_EQ(one.get_unbiased_exponent(), static_cast(0x03FF)); + EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000)); + EXPECT_EQ(one.uintval(), static_cast(0x3FF0000000000000)); + EXPECT_STREQ(one.str().c_str(), + "0x3FF0000000000000 = (S: 0, E: 0x03FF, M: 0x0000000000000000)"); + + FPBits negone(-1.0); + EXPECT_EQ(negone.get_sign(), true); + EXPECT_EQ(negone.get_unbiased_exponent(), static_cast(0x03FF)); + EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000)); + EXPECT_EQ(negone.uintval(), static_cast(0xBFF0000000000000)); + EXPECT_STREQ(negone.str().c_str(), + "0xBFF0000000000000 = (S: 1, E: 0x03FF, M: 0x0000000000000000)"); + + FPBits num(1.125); + EXPECT_EQ(num.get_sign(), false); + EXPECT_EQ(num.get_unbiased_exponent(), static_cast(0x03FF)); + EXPECT_EQ(num.get_mantissa(), static_cast(0x0002000000000000)); + EXPECT_EQ(num.uintval(), static_cast(0x3FF2000000000000)); + EXPECT_STREQ(num.str().c_str(), + "0x3FF2000000000000 = (S: 0, E: 0x03FF, M: 0x0002000000000000)"); + + FPBits negnum(-1.125); + EXPECT_EQ(negnum.get_sign(), true); + EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast(0x03FF)); + EXPECT_EQ(negnum.get_mantissa(), static_cast(0x0002000000000000)); + EXPECT_EQ(negnum.uintval(), static_cast(0xBFF2000000000000)); + EXPECT_STREQ(negnum.str().c_str(), + "0xBFF2000000000000 = (S: 1, E: 0x03FF, M: 0x0002000000000000)"); +} + +TEST(LlvmLibcFPBitsTest, LongDoubleType) { + if constexpr (sizeof(long double) == sizeof(double)) + return; // The tests for the "double" type cover for this case. + + EXPECT_STREQ(FPBits::inf().str().c_str(), "(+Infinity)"); + EXPECT_STREQ(FPBits::neg_inf().str().c_str(), "(-Infinity)"); + EXPECT_STREQ( + FPBits(FPBits::build_nan(1)).str().c_str(), + "(NaN)"); + + FPBits zero(0.0l); + EXPECT_EQ(zero.get_sign(), false); + EXPECT_EQ(zero.get_unbiased_exponent(), static_cast(0x0000)); + EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000) + << 64); + EXPECT_EQ(zero.uintval(), static_cast(0x0000000000000000) << 64); +#ifdef LIBC_TARGET_ARCH_IS_X86 + EXPECT_STREQ( + zero.str().c_str(), + "0x00000000000000000000000000000000 = " + "(S: 0, E: 0x0000, I: 0, M: 0x00000000000000000000000000000000)"); +#else + EXPECT_STREQ(zero.str().c_str(), + "0x00000000000000000000000000000000 = " + "(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)"); +#endif + + FPBits negzero(-0.0l); + EXPECT_EQ(negzero.get_sign(), true); + EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast(0x0000)); + EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000) + << 64); +#ifdef LIBC_TARGET_ARCH_IS_X86 + EXPECT_EQ(negzero.uintval(), static_cast(0x1) << 79); + EXPECT_STREQ( + negzero.str().c_str(), + "0x00000000000080000000000000000000 = " + "(S: 1, E: 0x0000, I: 0, M: 0x00000000000000000000000000000000)"); +#else + EXPECT_EQ(negzero.uintval(), static_cast(0x1) << 127); + EXPECT_STREQ(negzero.str().c_str(), + "0x80000000000000000000000000000000 = " + "(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)"); +#endif + + FPBits one(1.0l); + EXPECT_EQ(one.get_sign(), false); + EXPECT_EQ(one.get_unbiased_exponent(), static_cast(0x3FFF)); + EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000) << 64); +#ifdef LIBC_TARGET_ARCH_IS_X86 + EXPECT_EQ(one.uintval(), static_cast(0x3FFF8) << 60); + EXPECT_STREQ( + one.str().c_str(), + "0x0000000000003FFF8000000000000000 = " + "(S: 0, E: 0x3FFF, I: 1, M: 0x00000000000000000000000000000000)"); +#else + EXPECT_EQ(one.uintval(), static_cast(0x3FFF) << 112); + EXPECT_STREQ(one.str().c_str(), + "0x3FFF0000000000000000000000000000 = " + "(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); +#endif + + FPBits negone(-1.0l); + EXPECT_EQ(negone.get_sign(), true); + EXPECT_EQ(negone.get_unbiased_exponent(), static_cast(0x3FFF)); + EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000) + << 64); +#ifdef LIBC_TARGET_ARCH_IS_X86 + EXPECT_EQ(negone.uintval(), static_cast(0xBFFF8) << 60); + EXPECT_STREQ( + negone.str().c_str(), + "0x000000000000BFFF8000000000000000 = " + "(S: 1, E: 0x3FFF, I: 1, M: 0x00000000000000000000000000000000)"); +#else + EXPECT_EQ(negone.uintval(), static_cast(0xBFFF) << 112); + EXPECT_STREQ(negone.str().c_str(), + "0xBFFF0000000000000000000000000000 = " + "(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); +#endif + + FPBits num(1.125l); + EXPECT_EQ(num.get_sign(), false); + EXPECT_EQ(num.get_unbiased_exponent(), static_cast(0x3FFF)); +#ifdef LIBC_TARGET_ARCH_IS_X86 + EXPECT_EQ(num.get_mantissa(), static_cast(0x1) << 60); + EXPECT_EQ(num.uintval(), static_cast(0x3FFF9) << 60); + EXPECT_STREQ( + num.str().c_str(), + "0x0000000000003FFF9000000000000000 = " + "(S: 0, E: 0x3FFF, I: 1, M: 0x00000000000000001000000000000000)"); +#else + EXPECT_EQ(num.get_mantissa(), static_cast(0x2) << 108); + EXPECT_EQ(num.uintval(), static_cast(0x3FFF2) << 108); + EXPECT_STREQ(num.str().c_str(), + "0x3FFF2000000000000000000000000000 = " + "(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)"); +#endif + + FPBits negnum(-1.125l); + EXPECT_EQ(negnum.get_sign(), true); + EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast(0x3FFF)); +#ifdef LIBC_TARGET_ARCH_IS_X86 + EXPECT_EQ(negnum.get_mantissa(), static_cast(0x1) << 60); + EXPECT_EQ(negnum.uintval(), static_cast(0xBFFF9) << 60); + EXPECT_STREQ( + negnum.str().c_str(), + "0x000000000000BFFF9000000000000000 = " + "(S: 1, E: 0x3FFF, I: 1, M: 0x00000000000000001000000000000000)"); +#else + EXPECT_EQ(negnum.get_mantissa(), static_cast(0x2) << 108); + EXPECT_EQ(negnum.uintval(), static_cast(0xBFFF2) << 108); + EXPECT_STREQ(negnum.str().c_str(), + "0xBFFF2000000000000000000000000000 = " + "(S: 1, E: 0x3FFF, M: 0x00002000000000000000000000000000)"); +#endif +} diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp --- a/libc/utils/MPFRWrapper/MPFRUtils.cpp +++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp @@ -703,12 +703,11 @@ MPFRNumber mpfrMatchValue(matchValue); tlog << "Match value not within tolerance value of MPFR result:\n" << " Input decimal: " << mpfrInput.str() << '\n'; - __llvm_libc::fputil::testing::describeValue(" Input bits: ", input); + tlog << " Input bits: " << FPBits(input).str() << '\n'; tlog << '\n' << " Match decimal: " << mpfrMatchValue.str() << '\n'; - __llvm_libc::fputil::testing::describeValue(" Match bits: ", matchValue); + tlog << " Match bits: " << FPBits(matchValue).str() << '\n'; tlog << '\n' << " MPFR result: " << mpfr_result.str() << '\n'; - __llvm_libc::fputil::testing::describeValue(" MPFR rounded: ", - mpfr_result.as()); + tlog << " MPFR rounded: " << FPBits(mpfr_result.as()).str() << '\n'; tlog << '\n'; tlog << " ULP error: " << mpfr_result.ulp_as_mpfr_number(matchValue).str() << '\n'; @@ -748,13 +747,13 @@ tlog << " Input decimal: " << mpfrInput.str() << "\n\n"; tlog << "Libc floating point value: " << mpfrMatchValue.str() << '\n'; - __llvm_libc::fputil::testing::describeValue(" Libc floating point bits: ", - libc_result.f); + tlog << " Libc floating point bits: " << FPBits(libc_result.f).str() + << '\n'; tlog << "\n\n"; tlog << " MPFR result: " << mpfr_result.str() << '\n'; - __llvm_libc::fputil::testing::describeValue(" MPFR rounded: ", - mpfr_result.as()); + tlog << " MPFR rounded: " << FPBits(mpfr_result.as()).str() + << '\n'; tlog << '\n' << " ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result.f).str() << '\n'; @@ -786,10 +785,10 @@ << "Libc integral result: " << libc_result.i << '\n' << "Libc floating point result: " << mpfrMatchValue.str() << '\n' << " MPFR result: " << mpfr_result.str() << '\n'; - __llvm_libc::fputil::testing::describeValue( - "Libc floating point result bits: ", libc_result.f); - __llvm_libc::fputil::testing::describeValue( - " MPFR rounded bits: ", mpfr_result.as()); + tlog << "Libc floating point result bits: " << FPBits(libc_result.f).str() + << '\n'; + tlog << " MPFR rounded bits: " + << FPBits(mpfr_result.as()).str() << '\n'; tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result.f).str() << '\n'; } @@ -820,15 +819,15 @@ MPFRNumber mpfrMatchValue(libc_result); tlog << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << '\n'; - __llvm_libc::fputil::testing::describeValue("First input bits: ", input.x); - __llvm_libc::fputil::testing::describeValue("Second input bits: ", input.y); + tlog << "First input bits: " << FPBits(input.x).str() << '\n'; + tlog << "Second input bits: " << FPBits(input.y).str() << '\n'; tlog << "Libc result: " << mpfrMatchValue.str() << '\n' << "MPFR result: " << mpfr_result.str() << '\n'; - __llvm_libc::fputil::testing::describeValue( - "Libc floating point result bits: ", libc_result); - __llvm_libc::fputil::testing::describeValue( - " MPFR rounded bits: ", mpfr_result.as()); + tlog << "Libc floating point result bits: " << FPBits(libc_result).str() + << '\n'; + tlog << " MPFR rounded bits: " + << FPBits(mpfr_result.as()).str() << '\n'; tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str() << '\n'; } @@ -860,16 +859,16 @@ tlog << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << " z: " << mpfrZ.str() << '\n'; - __llvm_libc::fputil::testing::describeValue("First input bits: ", input.x); - __llvm_libc::fputil::testing::describeValue("Second input bits: ", input.y); - __llvm_libc::fputil::testing::describeValue("Third input bits: ", input.z); + tlog << " First input bits: " << FPBits(input.x).str() << '\n'; + tlog << "Second input bits: " << FPBits(input.y).str() << '\n'; + tlog << " Third input bits: " << FPBits(input.z).str() << '\n'; tlog << "Libc result: " << mpfrMatchValue.str() << '\n' << "MPFR result: " << mpfr_result.str() << '\n'; - __llvm_libc::fputil::testing::describeValue( - "Libc floating point result bits: ", libc_result); - __llvm_libc::fputil::testing::describeValue( - " MPFR rounded bits: ", mpfr_result.as()); + tlog << "Libc floating point result bits: " << FPBits(libc_result).str() + << '\n'; + tlog << " MPFR rounded bits: " + << FPBits(mpfr_result.as()).str() << '\n'; tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str() << '\n'; }