brintos

brintos / llvm-project-archived public Read only

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