1 //===-- Unittests for strtold ---------------------------------------------===//
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/FPBits.h"
10 #include "src/stdlib/strtold.h"
11 
12 #include "utils/UnitTest/Test.h"
13 
14 #include <errno.h>
15 #include <limits.h>
16 #include <stddef.h>
17 
18 #ifdef __SIZEOF_INT128__
19 class LlvmLibcStrToLDTest : public __llvm_libc::testing::Test {
20 public:
21   void run_test(const char *inputString, const ptrdiff_t expectedStrLen,
22                 const uint64_t expectedRawData64,
23                 const __uint128_t expectedRawData80,
24                 const __uint128_t expectedRawData128,
25                 const int expectedErrno64 = 0, const int expectedErrno80 = 0,
26                 const int expectedErrno128 = 0) {
27     // expectedRawData64 is the expected long double result as a uint64_t,
28     // organized according to the IEEE754 double precision format:
29     //
30     // +-- 1 Sign Bit                        +-- 52 Mantissa bits
31     // |                                     |
32     // |           +-------------------------+------------------------+
33     // |           |                                                  |
34     // SEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
35     //  |         |
36     //  +----+----+
37     //       |
38     //       +-- 11 Exponent Bits
39 
40     // expectedRawData80 is the expected long double result as a __uint128_t,
41     // organized according to the x86 extended precision format:
42     //
43     // +-- 1 Sign Bit
44     // |
45     // |               +-- 1 Integer part bit (1 unless this is a subnormal)
46     // |               |
47     // SEEEEEEEEEEEEEEEIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM...M
48     //  |             | |                                                      |
49     //  +------+------+ +---------------------------+--------------------------+
50     //         |                                    |
51     //         +-- 15 Exponent Bits                 +-- 63 Mantissa bits
52 
53     // expectedRawData64 is the expected long double result as a __uint128_t,
54     // organized according to IEEE754 quadruple precision format:
55     //
56     // +-- 1 Sign Bit                               +-- 112 Mantissa bits
57     // |                                            |
58     // |               +----------------------------+--------------------------+
59     // |               |                                                       |
60     // SEEEEEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM...M
61     //  |             |
62     //  +------+------+
63     //         |
64     //         +-- 15 Exponent Bits
65     char *str_end = nullptr;
66 
67 #if defined(LONG_DOUBLE_IS_DOUBLE)
68     __llvm_libc::fputil::FPBits<long double> expected_fp =
69         __llvm_libc::fputil::FPBits<long double>(expectedRawData64);
70     const int expected_errno = expectedErrno64;
71 #elif defined(SPECIAL_X86_LONG_DOUBLE)
72     __llvm_libc::fputil::FPBits<long double> expected_fp =
73         __llvm_libc::fputil::FPBits<long double>(expectedRawData80);
74     const int expected_errno = expectedErrno80;
75 #else
76     __llvm_libc::fputil::FPBits<long double> expected_fp =
77         __llvm_libc::fputil::FPBits<long double>(expectedRawData128);
78     const int expected_errno = expectedErrno128;
79 #endif
80 
81     errno = 0;
82     long double result = __llvm_libc::strtold(inputString, &str_end);
83 
84     __llvm_libc::fputil::FPBits<long double> actual_fp =
85         __llvm_libc::fputil::FPBits<long double>();
86     actual_fp = __llvm_libc::fputil::FPBits<long double>(result);
87 
88     EXPECT_EQ(str_end - inputString, expectedStrLen);
89 
90     EXPECT_EQ(actual_fp.bits, expected_fp.bits);
91     EXPECT_EQ(actual_fp.get_sign(), expected_fp.get_sign());
92     EXPECT_EQ(actual_fp.get_exponent(), expected_fp.get_exponent());
93     EXPECT_EQ(actual_fp.get_mantissa(), expected_fp.get_mantissa());
94     EXPECT_EQ(errno, expected_errno);
95   }
96 };
97 
98 TEST_F(LlvmLibcStrToLDTest, SimpleTest) {
99   run_test("123", 3, uint64_t(0x405ec00000000000),
100            __uint128_t(0x4005f60000) << 40,
101            __uint128_t(0x4005ec0000000000) << 64);
102 
103   // This should fail on Eisel-Lemire, forcing a fallback to simple decimal
104   // conversion.
105   run_test("12345678901234549760", 20, uint64_t(0x43e56a95319d63d8),
106            (__uint128_t(0x403eab54a9) << 40) + __uint128_t(0x8ceb1ec400),
107            (__uint128_t(0x403e56a95319d63d) << 64) +
108                __uint128_t(0x8800000000000000));
109 
110   // Found while looking for difficult test cases here:
111   // https://github.com/nigeltao/parse-number-fxx-test-data/blob/main/more-test-cases/golang-org-issue-36657.txt
112   run_test("1090544144181609348835077142190", 31, uint64_t(0x462b8779f2474dfb),
113            (__uint128_t(0x4062dc3bcf) << 40) + __uint128_t(0x923a6fd402),
114            (__uint128_t(0x4062b8779f2474df) << 64) +
115                __uint128_t(0xa804bfd8c6d5c000));
116 
117   run_test("0x123", 5, uint64_t(0x4072300000000000),
118            (__uint128_t(0x4007918000) << 40),
119            (__uint128_t(0x4007230000000000) << 64));
120 }
121 
122 // These are tests that have caused problems for doubles in the past.
123 TEST_F(LlvmLibcStrToLDTest, Float64SpecificFailures) {
124   run_test("3E70000000000000", 16, uint64_t(0x7FF0000000000000),
125            (__uint128_t(0x7fff800000) << 40),
126            (__uint128_t(0x7fff000000000000) << 64), ERANGE, ERANGE, ERANGE);
127   run_test("358416272e-33", 13, uint64_t(0x3adbbb2a68c9d0b9),
128            (__uint128_t(0x3fadddd953) << 40) + __uint128_t(0x464e85c400),
129            (__uint128_t(0x3fadbbb2a68c9d0b) << 64) +
130                __uint128_t(0x8800e7969e1c5fc8));
131   run_test(
132       "2.16656806400000023841857910156251e9", 36, uint64_t(0x41e0246690000001),
133       (__uint128_t(0x401e812334) << 40) + __uint128_t(0x8000000400),
134       (__uint128_t(0x401e024669000000) << 64) + __uint128_t(0x800000000000018));
135   run_test("27949676547093071875", 20, uint64_t(0x43f83e132bc608c9),
136            (__uint128_t(0x403fc1f099) << 40) + __uint128_t(0x5e30464402),
137            (__uint128_t(0x403f83e132bc608c) << 64) +
138                __uint128_t(0x8803000000000000));
139 }
140 
141 TEST_F(LlvmLibcStrToLDTest, MaxSizeNumbers) {
142   run_test("1.1897314953572317650e4932", 26, uint64_t(0x7FF0000000000000),
143            (__uint128_t(0x7ffeffffff) << 40) + __uint128_t(0xffffffffff),
144            (__uint128_t(0x7ffeffffffffffff) << 64) +
145                __uint128_t(0xfffd57322e3f8675),
146            ERANGE, 0, 0);
147   run_test("1.18973149535723176508e4932", 27, uint64_t(0x7FF0000000000000),
148            (__uint128_t(0x7fff800000) << 40),
149            (__uint128_t(0x7ffeffffffffffff) << 64) +
150                __uint128_t(0xffffd2478338036c),
151            ERANGE, ERANGE, 0);
152 }
153 
154 // These tests check subnormal behavior for 80 bit and 128 bit floats. They will
155 // be too small for 64 bit floats.
156 TEST_F(LlvmLibcStrToLDTest, SubnormalTests) {
157   run_test("1e-4950", 7, uint64_t(0), (__uint128_t(0x00000000000000000003)),
158            (__uint128_t(0x000000000000000000057c9647e1a018)), ERANGE, ERANGE,
159            ERANGE);
160   run_test("1.89e-4951", 10, uint64_t(0), (__uint128_t(0x00000000000000000001)),
161            (__uint128_t(0x0000000000000000000109778a006738)), ERANGE, ERANGE,
162            ERANGE);
163   run_test("4e-4966", 7, uint64_t(0), (__uint128_t(0)),
164            (__uint128_t(0x00000000000000000000000000000001)), ERANGE, ERANGE,
165            ERANGE);
166 }
167 
168 TEST_F(LlvmLibcStrToLDTest, SmallNormalTests) {
169   run_test("3.37e-4932", 10, uint64_t(0),
170            (__uint128_t(0x1804cf7) << 40) + __uint128_t(0x908850712),
171            (__uint128_t(0x10099ee12110a) << 64) +
172                __uint128_t(0xe24b75c0f50dc0c),
173            ERANGE, 0, 0);
174 }
175 
176 TEST_F(LlvmLibcStrToLDTest, ComplexHexadecimalTests) {
177   run_test("0x1p16383", 9, 0x7ff0000000000000,
178            (__uint128_t(0x7ffe800000) << 40),
179            (__uint128_t(0x7ffe000000000000) << 64), ERANGE);
180   run_test("0x123456789abcdef", 17, 0x43723456789abcdf,
181            (__uint128_t(0x403791a2b3) << 40) + __uint128_t(0xc4d5e6f780),
182            (__uint128_t(0x403723456789abcd) << 64) +
183                __uint128_t(0xef00000000000000));
184   run_test("0x123456789abcdef0123456789ABCDEF", 33, 0x47723456789abcdf,
185            (__uint128_t(0x407791a2b3) << 40) + __uint128_t(0xc4d5e6f781),
186            (__uint128_t(0x407723456789abcd) << 64) +
187                __uint128_t(0xef0123456789abce));
188 }
189 
190 TEST_F(LlvmLibcStrToLDTest, InfTests) {
191   run_test("INF", 3, 0x7ff0000000000000, (__uint128_t(0x7fff800000) << 40),
192            (__uint128_t(0x7fff000000000000) << 64));
193   run_test("INFinity", 8, 0x7ff0000000000000, (__uint128_t(0x7fff800000) << 40),
194            (__uint128_t(0x7fff000000000000) << 64));
195   run_test("-inf", 4, 0xfff0000000000000, (__uint128_t(0xffff800000) << 40),
196            (__uint128_t(0xffff000000000000) << 64));
197 }
198 
199 TEST_F(LlvmLibcStrToLDTest, NaNTests) {
200   run_test("NaN", 3, 0x7ff8000000000000, (__uint128_t(0x7fffc00000) << 40),
201            (__uint128_t(0x7fff800000000000) << 64));
202   run_test("-nAn", 4, 0xfff8000000000000, (__uint128_t(0xffffc00000) << 40),
203            (__uint128_t(0xffff800000000000) << 64));
204   run_test("NaN()", 5, 0x7ff8000000000000, (__uint128_t(0x7fffc00000) << 40),
205            (__uint128_t(0x7fff800000000000) << 64));
206   run_test("NaN(1234)", 9, 0x7ff80000000004d2,
207            (__uint128_t(0x7fffc00000) << 40) + __uint128_t(0x4d2),
208            (__uint128_t(0x7fff800000000000) << 64) + __uint128_t(0x4d2));
209   run_test("NaN(0xffffffffffff)", 19, 0x7ff8ffffffffffff,
210            (__uint128_t(0x7fffc000ff) << 40) + __uint128_t(0xffffffffff),
211            (__uint128_t(0x7fff800000000000) << 64) +
212                __uint128_t(0xffffffffffff));
213   run_test("NaN(0xfffffffffffff)", 20, 0x7fffffffffffffff,
214            (__uint128_t(0x7fffc00fff) << 40) + __uint128_t(0xffffffffff),
215            (__uint128_t(0x7fff800000000000) << 64) +
216                __uint128_t(0xfffffffffffff));
217   run_test("NaN(0xffffffffffffffff)", 23, 0x7fffffffffffffff,
218            (__uint128_t(0x7fffffffff) << 40) + __uint128_t(0xffffffffff),
219            (__uint128_t(0x7fff800000000000) << 64) +
220                __uint128_t(0xffffffffffffffff));
221   run_test("NaN( 1234)", 3, 0x7ff8000000000000,
222            (__uint128_t(0x7fffc00000) << 40),
223            (__uint128_t(0x7fff800000000000) << 64));
224 }
225 #endif
226