[libc-commits] [libc] 00bd8e9 - [libc] Add a str() method to FPBits which returns a string representation.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Thu May 18 23:20:49 PDT 2023
Author: Siva Chandra Reddy
Date: 2023-05-19T06:20:41Z
New Revision: 00bd8e90116d99499f9161914fa5e00eed14a5ff
URL: https://github.com/llvm/llvm-project/commit/00bd8e90116d99499f9161914fa5e00eed14a5ff
DIFF: https://github.com/llvm/llvm-project/commit/00bd8e90116d99499f9161914fa5e00eed14a5ff.diff
LOG: [libc] Add a str() method to FPBits which returns a string representation.
Unit tests for the str() method have also been added.
Previously, a separate test only helper function was being used by the
test matchers which has regressed over many cleanups. Moreover, being a
test only utility, it was not tested separately (and hence the
regression).
Reviewed By: michaelrj
Differential Revision: https://reviews.llvm.org/D150906
Added:
libc/test/src/__support/FPUtil/fpbits_test.cpp
Modified:
libc/src/__support/FPUtil/CMakeLists.txt
libc/src/__support/FPUtil/FPBits.h
libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
libc/test/UnitTest/FPMatcher.h
libc/test/src/__support/FPUtil/CMakeLists.txt
libc/utils/MPFRWrapper/MPFRUtils.cpp
Removed:
################################################################################
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index b737aad1093d0..4452655d5708a 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -36,7 +36,9 @@ add_header_library(
.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
index 49285527305ab..ddeb7c0f97ed2 100644
--- 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 <stdint.h>
@@ -213,6 +215,47 @@ template <typename T> struct FPBits {
result.set_mantissa(mantissa);
return result;
}
+
+ // Converts the bits to a string in the following format:
+ // "0x<NNN...N> = 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<UIntType>()];
+ 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<uint16_t>()];
+ 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<UIntType>()] = {'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
index ba2fddb2a6fed..1ef588fba54ac 100644
--- 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 @@ template <> struct FPBits<long double> {
result.set_mantissa(mantissa);
return result;
}
+
+ // Converts the bits to a string in the following format:
+ // "0x<NNN...N> = 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<UIntType>()] = {'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<uint16_t>()] = {'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<UIntType>()] = {'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
index d9234c3dc328f..d3e83384ba1ce 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -21,43 +21,6 @@ namespace __llvm_libc {
namespace fputil {
namespace testing {
-template <typename ValType>
-cpp::enable_if_t<cpp::is_floating_point_v<ValType>, void>
-describeValue(const char *label, ValType value) {
- __llvm_libc::testing::tlog << label;
-
- FPBits<ValType> 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<ValType>::VALUE - 1) / 4 + 1;
- constexpr int mantissaWidthInHex =
- (fputil::MantissaWidth<ValType>::VALUE - 1) / 4 + 1;
- constexpr int bitsWidthInHex =
- sizeof(typename fputil::FPBits<ValType>::UIntType) * 2;
-
- __llvm_libc::testing::tlog
- << "0x"
- << int_to_hex<typename fputil::FPBits<ValType>::UIntType>(
- bits.uintval(), bitsWidthInHex)
- << ", (S | E | M) = (" << (bits.get_sign() ? '1' : '0') << " | 0x"
- << int_to_hex<uint16_t>(bits.get_unbiased_exponent(),
- exponentWidthInHex)
- << " | 0x"
- << int_to_hex<typename fputil::FPBits<ValType>::UIntType>(
- bits.get_mantissa(), mantissaWidthInHex)
- << ")";
- }
-
- __llvm_libc::testing::tlog << '\n';
-}
-
template <typename T, __llvm_libc::testing::TestCondition Condition>
class FPMatcher : public __llvm_libc::testing::Matcher<T> {
static_assert(__llvm_libc::cpp::is_floating_point_v<T>,
@@ -87,8 +50,11 @@ class FPMatcher : public __llvm_libc::testing::Matcher<T> {
}
void explainError() override {
- describeValue("Expected floating point value: ", expected);
- describeValue(" Actual floating point value: ", actual);
+ __llvm_libc::testing::tlog
+ << "Expected floating point value: " << FPBits<T>(expected).str()
+ << '\n';
+ __llvm_libc::testing::tlog
+ << "Actual floating point value: " << FPBits<T>(actual).str() << '\n';
}
};
diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index 2e4f7f897773f..f421e7c584bfc 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -10,3 +10,13 @@ add_fp_unittest(
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
index 0000000000000..ba8aef77b8340
--- /dev/null
+++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp
@@ -0,0 +1,266 @@
+//===-- 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<float>::inf().str().c_str(), "(+Infinity)");
+ EXPECT_STREQ(FPBits<float>::neg_inf().str().c_str(), "(-Infinity)");
+ EXPECT_STREQ(FPBits<float>(FPBits<float>::build_nan(1)).str().c_str(),
+ "(NaN)");
+
+ FPBits<float> zero(0.0f);
+ EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_EQ(zero.get_unbiased_exponent(), static_cast<uint16_t>(0));
+ EXPECT_EQ(zero.get_mantissa(), static_cast<uint32_t>(0));
+ EXPECT_EQ(zero.uintval(), static_cast<uint32_t>(0x00000000));
+ EXPECT_STREQ(zero.str().c_str(),
+ "0x00000000 = (S: 0, E: 0x0000, M: 0x00000000)");
+
+ FPBits<float> negzero(-0.0f);
+ EXPECT_EQ(negzero.get_sign(), true);
+ EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast<uint16_t>(0));
+ EXPECT_EQ(negzero.get_mantissa(), static_cast<uint32_t>(0));
+ EXPECT_EQ(negzero.uintval(), static_cast<uint32_t>(0x80000000));
+ EXPECT_STREQ(negzero.str().c_str(),
+ "0x80000000 = (S: 1, E: 0x0000, M: 0x00000000)");
+
+ FPBits<float> one(1.0f);
+ EXPECT_EQ(one.get_sign(), false);
+ EXPECT_EQ(one.get_unbiased_exponent(), static_cast<uint16_t>(0x7F));
+ EXPECT_EQ(one.get_mantissa(), static_cast<uint32_t>(0));
+ EXPECT_EQ(one.uintval(), static_cast<uint32_t>(0x3F800000));
+ EXPECT_STREQ(one.str().c_str(),
+ "0x3F800000 = (S: 0, E: 0x007F, M: 0x00000000)");
+
+ FPBits<float> negone(-1.0f);
+ EXPECT_EQ(negone.get_sign(), true);
+ EXPECT_EQ(negone.get_unbiased_exponent(), static_cast<uint16_t>(0x7F));
+ EXPECT_EQ(negone.get_mantissa(), static_cast<uint32_t>(0));
+ EXPECT_EQ(negone.uintval(), static_cast<uint32_t>(0xBF800000));
+ EXPECT_STREQ(negone.str().c_str(),
+ "0xBF800000 = (S: 1, E: 0x007F, M: 0x00000000)");
+
+ FPBits<float> num(1.125f);
+ EXPECT_EQ(num.get_sign(), false);
+ EXPECT_EQ(num.get_unbiased_exponent(), static_cast<uint16_t>(0x7F));
+ EXPECT_EQ(num.get_mantissa(), static_cast<uint32_t>(0x00100000));
+ EXPECT_EQ(num.uintval(), static_cast<uint32_t>(0x3F900000));
+ EXPECT_STREQ(num.str().c_str(),
+ "0x3F900000 = (S: 0, E: 0x007F, M: 0x00100000)");
+
+ FPBits<float> negnum(-1.125f);
+ EXPECT_EQ(negnum.get_sign(), true);
+ EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast<uint16_t>(0x7F));
+ EXPECT_EQ(negnum.get_mantissa(), static_cast<uint32_t>(0x00100000));
+ EXPECT_EQ(negnum.uintval(), static_cast<uint32_t>(0xBF900000));
+ EXPECT_STREQ(negnum.str().c_str(),
+ "0xBF900000 = (S: 1, E: 0x007F, M: 0x00100000)");
+}
+
+TEST(LlvmLibcFPBitsTest, DoubleType) {
+ EXPECT_STREQ(FPBits<double>::inf().str().c_str(), "(+Infinity)");
+ EXPECT_STREQ(FPBits<double>::neg_inf().str().c_str(), "(-Infinity)");
+ EXPECT_STREQ(FPBits<double>(FPBits<double>::build_nan(1)).str().c_str(),
+ "(NaN)");
+
+ FPBits<double> zero(0.0);
+ EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_EQ(zero.get_unbiased_exponent(), static_cast<uint16_t>(0x0000));
+ EXPECT_EQ(zero.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
+ EXPECT_EQ(zero.uintval(), static_cast<uint64_t>(0x0000000000000000));
+ EXPECT_STREQ(zero.str().c_str(),
+ "0x0000000000000000 = (S: 0, E: 0x0000, M: 0x0000000000000000)");
+
+ FPBits<double> negzero(-0.0);
+ EXPECT_EQ(negzero.get_sign(), true);
+ EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast<uint16_t>(0x0000));
+ EXPECT_EQ(negzero.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
+ EXPECT_EQ(negzero.uintval(), static_cast<uint64_t>(0x8000000000000000));
+ EXPECT_STREQ(negzero.str().c_str(),
+ "0x8000000000000000 = (S: 1, E: 0x0000, M: 0x0000000000000000)");
+
+ FPBits<double> one(1.0);
+ EXPECT_EQ(one.get_sign(), false);
+ EXPECT_EQ(one.get_unbiased_exponent(), static_cast<uint16_t>(0x03FF));
+ EXPECT_EQ(one.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
+ EXPECT_EQ(one.uintval(), static_cast<uint64_t>(0x3FF0000000000000));
+ EXPECT_STREQ(one.str().c_str(),
+ "0x3FF0000000000000 = (S: 0, E: 0x03FF, M: 0x0000000000000000)");
+
+ FPBits<double> negone(-1.0);
+ EXPECT_EQ(negone.get_sign(), true);
+ EXPECT_EQ(negone.get_unbiased_exponent(), static_cast<uint16_t>(0x03FF));
+ EXPECT_EQ(negone.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
+ EXPECT_EQ(negone.uintval(), static_cast<uint64_t>(0xBFF0000000000000));
+ EXPECT_STREQ(negone.str().c_str(),
+ "0xBFF0000000000000 = (S: 1, E: 0x03FF, M: 0x0000000000000000)");
+
+ FPBits<double> num(1.125);
+ EXPECT_EQ(num.get_sign(), false);
+ EXPECT_EQ(num.get_unbiased_exponent(), static_cast<uint16_t>(0x03FF));
+ EXPECT_EQ(num.get_mantissa(), static_cast<uint64_t>(0x0002000000000000));
+ EXPECT_EQ(num.uintval(), static_cast<uint64_t>(0x3FF2000000000000));
+ EXPECT_STREQ(num.str().c_str(),
+ "0x3FF2000000000000 = (S: 0, E: 0x03FF, M: 0x0002000000000000)");
+
+ FPBits<double> negnum(-1.125);
+ EXPECT_EQ(negnum.get_sign(), true);
+ EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast<uint16_t>(0x03FF));
+ EXPECT_EQ(negnum.get_mantissa(), static_cast<uint64_t>(0x0002000000000000));
+ EXPECT_EQ(negnum.uintval(), static_cast<uint64_t>(0xBFF2000000000000));
+ EXPECT_STREQ(negnum.str().c_str(),
+ "0xBFF2000000000000 = (S: 1, E: 0x03FF, M: 0x0002000000000000)");
+}
+
+#ifdef LIBC_TARGET_ARCH_IS_X86
+TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
+ if constexpr (sizeof(long double) == sizeof(double))
+ return; // The tests for the "double" type cover for this case.
+
+ EXPECT_STREQ(FPBits<long double>::inf().str().c_str(), "(+Infinity)");
+ EXPECT_STREQ(FPBits<long double>::neg_inf().str().c_str(), "(-Infinity)");
+ EXPECT_STREQ(
+ FPBits<long double>(FPBits<long double>::build_nan(1)).str().c_str(),
+ "(NaN)");
+
+ FPBits<long double> zero(0.0l);
+ EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_EQ(zero.get_unbiased_exponent(), static_cast<uint16_t>(0x0000));
+ EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
+ << 64);
+ EXPECT_EQ(zero.uintval(), static_cast<UInt128>(0x0000000000000000) << 64);
+ EXPECT_STREQ(
+ zero.str().c_str(),
+ "0x00000000000000000000000000000000 = "
+ "(S: 0, E: 0x0000, I: 0, M: 0x00000000000000000000000000000000)");
+
+ FPBits<long double> negzero(-0.0l);
+ EXPECT_EQ(negzero.get_sign(), true);
+ EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast<uint16_t>(0x0000));
+ EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
+ << 64);
+ EXPECT_EQ(negzero.uintval(), static_cast<UInt128>(0x1) << 79);
+ EXPECT_STREQ(
+ negzero.str().c_str(),
+ "0x00000000000080000000000000000000 = "
+ "(S: 1, E: 0x0000, I: 0, M: 0x00000000000000000000000000000000)");
+
+ FPBits<long double> one(1.0l);
+ EXPECT_EQ(one.get_sign(), false);
+ EXPECT_EQ(one.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
+ EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
+ EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF8) << 60);
+ EXPECT_STREQ(
+ one.str().c_str(),
+ "0x0000000000003FFF8000000000000000 = "
+ "(S: 0, E: 0x3FFF, I: 1, M: 0x00000000000000000000000000000000)");
+
+ FPBits<long double> negone(-1.0l);
+ EXPECT_EQ(negone.get_sign(), true);
+ EXPECT_EQ(negone.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
+ EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
+ << 64);
+ EXPECT_EQ(negone.uintval(), static_cast<UInt128>(0xBFFF8) << 60);
+ EXPECT_STREQ(
+ negone.str().c_str(),
+ "0x000000000000BFFF8000000000000000 = "
+ "(S: 1, E: 0x3FFF, I: 1, M: 0x00000000000000000000000000000000)");
+
+ FPBits<long double> num(1.125l);
+ EXPECT_EQ(num.get_sign(), false);
+ EXPECT_EQ(num.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
+ EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x1) << 60);
+ EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF9) << 60);
+ EXPECT_STREQ(
+ num.str().c_str(),
+ "0x0000000000003FFF9000000000000000 = "
+ "(S: 0, E: 0x3FFF, I: 1, M: 0x00000000000000001000000000000000)");
+
+ FPBits<long double> negnum(-1.125l);
+ EXPECT_EQ(negnum.get_sign(), true);
+ EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
+ EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x1) << 60);
+ EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF9) << 60);
+ EXPECT_STREQ(
+ negnum.str().c_str(),
+ "0x000000000000BFFF9000000000000000 = "
+ "(S: 1, E: 0x3FFF, I: 1, M: 0x00000000000000001000000000000000)");
+}
+#else
+TEST(LlvmLibcFPBitsTest, LongDoubleType) {
+ if constexpr (sizeof(long double) == sizeof(double))
+ return; // The tests for the "double" type cover for this case.
+
+ EXPECT_STREQ(FPBits<long double>::inf().str().c_str(), "(+Infinity)");
+ EXPECT_STREQ(FPBits<long double>::neg_inf().str().c_str(), "(-Infinity)");
+ EXPECT_STREQ(
+ FPBits<long double>(FPBits<long double>::build_nan(1)).str().c_str(),
+ "(NaN)");
+
+ FPBits<long double> zero(0.0l);
+ EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_EQ(zero.get_unbiased_exponent(), static_cast<uint16_t>(0x0000));
+ EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
+ << 64);
+ EXPECT_EQ(zero.uintval(), static_cast<UInt128>(0x0000000000000000) << 64);
+ EXPECT_STREQ(zero.str().c_str(),
+ "0x00000000000000000000000000000000 = "
+ "(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)");
+
+ FPBits<long double> negzero(-0.0l);
+ EXPECT_EQ(negzero.get_sign(), true);
+ EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast<uint16_t>(0x0000));
+ EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
+ << 64);
+ EXPECT_EQ(negzero.uintval(), static_cast<UInt128>(0x1) << 127);
+ EXPECT_STREQ(negzero.str().c_str(),
+ "0x80000000000000000000000000000000 = "
+ "(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)");
+
+ FPBits<long double> one(1.0l);
+ EXPECT_EQ(one.get_sign(), false);
+ EXPECT_EQ(one.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
+ EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
+ EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF) << 112);
+ EXPECT_STREQ(one.str().c_str(),
+ "0x3FFF0000000000000000000000000000 = "
+ "(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)");
+
+ FPBits<long double> negone(-1.0l);
+ EXPECT_EQ(negone.get_sign(), true);
+ EXPECT_EQ(negone.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
+ EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
+ << 64);
+ EXPECT_EQ(negone.uintval(), static_cast<UInt128>(0xBFFF) << 112);
+ EXPECT_STREQ(negone.str().c_str(),
+ "0xBFFF0000000000000000000000000000 = "
+ "(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)");
+
+ FPBits<long double> num(1.125l);
+ EXPECT_EQ(num.get_sign(), false);
+ EXPECT_EQ(num.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
+ EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x2) << 108);
+ EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF2) << 108);
+ EXPECT_STREQ(num.str().c_str(),
+ "0x3FFF2000000000000000000000000000 = "
+ "(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
+
+ FPBits<long double> negnum(-1.125l);
+ EXPECT_EQ(negnum.get_sign(), true);
+ EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
+ EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x2) << 108);
+ EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(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
index e2a273b6aa98e..f19899c3098fd 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -703,12 +703,11 @@ void explain_unary_operation_single_output_error(Operation op, T input,
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<T>(input).str() << '\n';
tlog << '\n' << " Match decimal: " << mpfrMatchValue.str() << '\n';
- __llvm_libc::fputil::testing::describeValue(" Match bits: ", matchValue);
+ tlog << " Match bits: " << FPBits<T>(matchValue).str() << '\n';
tlog << '\n' << " MPFR result: " << mpfr_result.str() << '\n';
- __llvm_libc::fputil::testing::describeValue(" MPFR rounded: ",
- mpfr_result.as<T>());
+ tlog << " MPFR rounded: " << FPBits<T>(mpfr_result.as<T>()).str() << '\n';
tlog << '\n';
tlog << " ULP error: "
<< mpfr_result.ulp_as_mpfr_number(matchValue).str() << '\n';
@@ -748,13 +747,13 @@ void explain_unary_operation_two_outputs_error(
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<T>(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<T>());
+ tlog << " MPFR rounded: " << FPBits<T>(mpfr_result.as<T>()).str()
+ << '\n';
tlog << '\n'
<< " ULP error: "
<< mpfr_result.ulp_as_mpfr_number(libc_result.f).str() << '\n';
@@ -786,10 +785,10 @@ void explain_binary_operation_two_outputs_error(
<< "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<T>());
+ tlog << "Libc floating point result bits: " << FPBits<T>(libc_result.f).str()
+ << '\n';
+ tlog << " MPFR rounded bits: "
+ << FPBits<T>(mpfr_result.as<T>()).str() << '\n';
tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result.f).str()
<< '\n';
}
@@ -820,15 +819,15 @@ void explain_binary_operation_one_output_error(Operation op,
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<T>(input.x).str() << '\n';
+ tlog << "Second input bits: " << FPBits<T>(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<T>());
+ tlog << "Libc floating point result bits: " << FPBits<T>(libc_result).str()
+ << '\n';
+ tlog << " MPFR rounded bits: "
+ << FPBits<T>(mpfr_result.as<T>()).str() << '\n';
tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str()
<< '\n';
}
@@ -860,16 +859,16 @@ void explain_ternary_operation_one_output_error(Operation op,
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<T>(input.x).str() << '\n';
+ tlog << "Second input bits: " << FPBits<T>(input.y).str() << '\n';
+ tlog << " Third input bits: " << FPBits<T>(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<T>());
+ tlog << "Libc floating point result bits: " << FPBits<T>(libc_result).str()
+ << '\n';
+ tlog << " MPFR rounded bits: "
+ << FPBits<T>(mpfr_result.as<T>()).str() << '\n';
tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str()
<< '\n';
}
More information about the libc-commits
mailing list