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