|
| 1 | +#include "str_to_fp_test.h" |
| 2 | + |
| 3 | +namespace LIBC_NAMESPACE { |
| 4 | +using LlvmLibcStrToDblTest = LlvmLibcStrToFloatTest<double>; |
| 5 | + |
| 6 | +TEST_F(LlvmLibcStrToDblTest, ClingerFastPathFloat64Simple) { |
| 7 | + clinger_fast_path_test(123, 0, 0xEC00000000000, 1029); |
| 8 | + clinger_fast_path_test(1234567890123456, 1, 0x5ee2a2eb5a5c0, 1076); |
| 9 | + clinger_fast_path_test(1234567890, -10, 0xf9add3739635f, 1019); |
| 10 | +} |
| 11 | + |
| 12 | +TEST_F(LlvmLibcStrToDblTest, ClingerFastPathFloat64ExtendedExp) { |
| 13 | + clinger_fast_path_test(1, 30, 0x93e5939a08cea, 1122); |
| 14 | + clinger_fast_path_test(1, 37, 0xe17b84357691b, 1145); |
| 15 | + clinger_fast_path_fails_test(10, 37); |
| 16 | + clinger_fast_path_fails_test(1, 100); |
| 17 | +} |
| 18 | + |
| 19 | +TEST_F(LlvmLibcStrToDblTest, ClingerFastPathFloat64NegativeExp) { |
| 20 | + clinger_fast_path_test(1, -10, 0xb7cdfd9d7bdbb, 989); |
| 21 | + clinger_fast_path_test(1, -20, 0x79ca10c924223, 956); |
| 22 | + clinger_fast_path_fails_test(1, -25); |
| 23 | +} |
| 24 | + |
| 25 | +TEST_F(LlvmLibcStrToDblTest, EiselLemireFloat64Simple) { |
| 26 | + eisel_lemire_test(12345678901234567890u, 1, 0x1AC53A7E04BCDA, 1089); |
| 27 | + eisel_lemire_test(123, 0, 0x1EC00000000000, 1029); |
| 28 | + eisel_lemire_test(12345678901234568192u, 0, 0x156A95319D63E2, 1086); |
| 29 | +} |
| 30 | + |
| 31 | +TEST_F(LlvmLibcStrToDblTest, EiselLemireFloat64SpecificFailures) { |
| 32 | + // These test cases have caused failures in the past. |
| 33 | + eisel_lemire_test(358416272, -33, 0x1BBB2A68C9D0B9, 941); |
| 34 | + eisel_lemire_test(2166568064000000238u, -9, 0x10246690000000, 1054); |
| 35 | + eisel_lemire_test(2794967654709307187u, 1, 0x183e132bc608c8, 1087); |
| 36 | + eisel_lemire_test(2794967654709307188u, 1, 0x183e132bc608c9, 1087); |
| 37 | +} |
| 38 | + |
| 39 | +// Check the fallback states for the algorithm: |
| 40 | +TEST_F(LlvmLibcStrToDblTest, EiselLemireFallbackStates) { |
| 41 | + // This number can't be evaluated by Eisel-Lemire since it's exactly 1024 away |
| 42 | + // from both of its closest floating point approximations |
| 43 | + // (12345678901234548736 and 12345678901234550784) |
| 44 | + ASSERT_FALSE( |
| 45 | + internal::eisel_lemire<double>({12345678901234549760u, 0}).has_value()); |
| 46 | +} |
| 47 | + |
| 48 | +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicWholeNumbers) { |
| 49 | + simple_decimal_conversion_test("123456789012345678900", 0x1AC53A7E04BCDA, |
| 50 | + 1089); |
| 51 | + simple_decimal_conversion_test("123", 0x1EC00000000000, 1029); |
| 52 | + simple_decimal_conversion_test("12345678901234549760", 0x156A95319D63D8, |
| 53 | + 1086); |
| 54 | +} |
| 55 | + |
| 56 | +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicDecimals) { |
| 57 | + simple_decimal_conversion_test("1.2345", 0x13c083126e978d, 1023); |
| 58 | + simple_decimal_conversion_test(".2345", 0x1e04189374bc6a, 1020); |
| 59 | + simple_decimal_conversion_test(".299792458", 0x132fccb4aca314, 1021); |
| 60 | +} |
| 61 | + |
| 62 | +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicExponents) { |
| 63 | + simple_decimal_conversion_test("1e10", 0x12a05f20000000, 1056); |
| 64 | + simple_decimal_conversion_test("1e-10", 0x1b7cdfd9d7bdbb, 989); |
| 65 | + simple_decimal_conversion_test("1e300", 0x17e43c8800759c, 2019); |
| 66 | + simple_decimal_conversion_test("1e-300", 0x156e1fc2f8f359, 26); |
| 67 | +} |
| 68 | + |
| 69 | +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicSubnormals) { |
| 70 | + simple_decimal_conversion_test("1e-320", 0x7e8, 0, ERANGE); |
| 71 | + simple_decimal_conversion_test("1e-308", 0x730d67819e8d2, 0, ERANGE); |
| 72 | + simple_decimal_conversion_test("2.9e-308", 0x14da6df5e4bcc8, 1); |
| 73 | +} |
| 74 | + |
| 75 | +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64SubnormalRounding) { |
| 76 | + |
| 77 | + // Technically you can keep adding digits until you hit the truncation limit, |
| 78 | + // but this is the shortest string that results in the maximum subnormal that |
| 79 | + // I found. |
| 80 | + simple_decimal_conversion_test("2.225073858507201e-308", 0xfffffffffffff, 0, |
| 81 | + ERANGE); |
| 82 | + |
| 83 | + // Same here, if you were to extend the max subnormal out for another 800 |
| 84 | + // digits, incrementing any one of those digits would create a normal number. |
| 85 | + simple_decimal_conversion_test("2.2250738585072012e-308", 0x10000000000000, |
| 86 | + 1); |
| 87 | +} |
| 88 | + |
| 89 | +TEST(LlvmLibcStrToDblTest, SimpleDecimalConversionExtraTypes) { |
| 90 | + uint64_t double_output_mantissa = 0; |
| 91 | + uint32_t output_exp2 = 0; |
| 92 | + |
| 93 | + libc_errno = 0; |
| 94 | + auto double_result = |
| 95 | + internal::simple_decimal_conversion<double>("123456789012345678900"); |
| 96 | + |
| 97 | + double_output_mantissa = double_result.num.mantissa; |
| 98 | + output_exp2 = double_result.num.exponent; |
| 99 | + |
| 100 | + EXPECT_EQ(double_output_mantissa, uint64_t(0x1AC53A7E04BCDA)); |
| 101 | + EXPECT_EQ(output_exp2, uint32_t(1089)); |
| 102 | + EXPECT_EQ(double_result.error, 0); |
| 103 | +} |
| 104 | + |
| 105 | +} // namespace LIBC_NAMESPACE |
0 commit comments