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