• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- Unittests for the DyadicFloat class -------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/FPUtil/dyadic_float.h"
10 #include "src/__support/big_int.h"
11 #include "test/UnitTest/FPMatcher.h"
12 #include "test/UnitTest/Test.h"
13 #include "utils/MPFRWrapper/MPFRUtils.h"
14 
15 using Float128 = LIBC_NAMESPACE::fputil::DyadicFloat<128>;
16 using Float192 = LIBC_NAMESPACE::fputil::DyadicFloat<192>;
17 using Float256 = LIBC_NAMESPACE::fputil::DyadicFloat<256>;
18 
TEST(LlvmLibcDyadicFloatTest,BasicConversions)19 TEST(LlvmLibcDyadicFloatTest, BasicConversions) {
20   Float128 x(Sign::POS, /*exponent*/ 0,
21              /*mantissa*/ Float128::MantissaType(1));
22   ASSERT_FP_EQ(1.0f, float(x));
23   ASSERT_FP_EQ(1.0, double(x));
24 
25   Float128 y(0x1.0p-53);
26   ASSERT_FP_EQ(0x1.0p-53f, float(y));
27   ASSERT_FP_EQ(0x1.0p-53, double(y));
28 
29   Float128 z = quick_add(x, y);
30 
31   EXPECT_FP_EQ_ALL_ROUNDING(float(x) + float(y), float(z));
32   EXPECT_FP_EQ_ALL_ROUNDING(double(x) + double(y), double(z));
33 }
34 
TEST(LlvmLibcDyadicFloatTest,QuickAdd)35 TEST(LlvmLibcDyadicFloatTest, QuickAdd) {
36   Float192 x(Sign::POS, /*exponent*/ 0,
37              /*mantissa*/ Float192::MantissaType(0x123456));
38   ASSERT_FP_EQ(0x1.23456p20, double(x));
39 
40   Float192 y(0x1.abcdefp-20);
41   ASSERT_FP_EQ(0x1.abcdefp-20, double(y));
42 
43   Float192 z = quick_add(x, y);
44   EXPECT_FP_EQ_ALL_ROUNDING(double(x) + double(y), double(z));
45 }
46 
TEST(LlvmLibcDyadicFloatTest,QuickMul)47 TEST(LlvmLibcDyadicFloatTest, QuickMul) {
48   Float256 x(Sign::POS, /*exponent*/ 0,
49              /*mantissa*/ Float256::MantissaType(0x123456));
50   ASSERT_FP_EQ(0x1.23456p20, double(x));
51 
52   Float256 y(0x1.abcdefp-25);
53   ASSERT_FP_EQ(0x1.abcdefp-25, double(y));
54 
55   Float256 z = quick_mul(x, y);
56   EXPECT_FP_EQ_ALL_ROUNDING(double(x) * double(y), double(z));
57 }
58 
59 #define TEST_EDGE_RANGES(Name, Type)                                           \
60   TEST(LlvmLibcDyadicFloatTest, EdgeRanges##Name) {                            \
61     using Bits = LIBC_NAMESPACE::fputil::FPBits<Type>;                         \
62     using DFType = LIBC_NAMESPACE::fputil::DyadicFloat<Bits::STORAGE_LEN>;     \
63     Type max_normal = Bits::max_normal().get_val();                            \
64     Type min_normal = Bits::min_normal().get_val();                            \
65     Type min_subnormal = Bits::min_subnormal().get_val();                      \
66     Type two(2);                                                               \
67                                                                                \
68     DFType x(min_normal);                                                      \
69     EXPECT_FP_EQ_ALL_ROUNDING(min_normal, static_cast<Type>(x));               \
70     --x.exponent;                                                              \
71     EXPECT_FP_EQ(min_normal / two, static_cast<Type>(x));                      \
72                                                                                \
73     DFType y(two *min_normal - min_subnormal);                                 \
74     --y.exponent;                                                              \
75     EXPECT_FP_EQ(min_normal, static_cast<Type>(y));                            \
76                                                                                \
77     DFType z(min_subnormal);                                                   \
78     EXPECT_FP_EQ_ALL_ROUNDING(min_subnormal, static_cast<Type>(z));            \
79     --z.exponent;                                                              \
80     EXPECT_FP_EQ(Bits::zero().get_val(), static_cast<Type>(z));                \
81                                                                                \
82     DFType t(max_normal);                                                      \
83     EXPECT_FP_EQ_ALL_ROUNDING(max_normal, static_cast<Type>(t));               \
84     ++t.exponent;                                                              \
85     EXPECT_FP_EQ(Bits::inf().get_val(), static_cast<Type>(t));                 \
86   }                                                                            \
87   static_assert(true, "Require semicolon.")
88 
89 TEST_EDGE_RANGES(Float, float);
90 TEST_EDGE_RANGES(Double, double);
91 TEST_EDGE_RANGES(LongDouble, long double);
92