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