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