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(inputMantissa: 123, inputExp10: 0, expectedOutputMantissa: 0xEC00000000000, expectedOutputExp2: 1029); |
8 | clinger_fast_path_test(inputMantissa: 1234567890123456, inputExp10: 1, expectedOutputMantissa: 0x5ee2a2eb5a5c0, expectedOutputExp2: 1076); |
9 | clinger_fast_path_test(inputMantissa: 1234567890, inputExp10: -10, expectedOutputMantissa: 0xf9add3739635f, expectedOutputExp2: 1019); |
10 | } |
11 | |
12 | TEST_F(LlvmLibcStrToDblTest, ClingerFastPathFloat64ExtendedExp) { |
13 | clinger_fast_path_test(inputMantissa: 1, inputExp10: 30, expectedOutputMantissa: 0x93e5939a08cea, expectedOutputExp2: 1122); |
14 | clinger_fast_path_test(inputMantissa: 1, inputExp10: 37, expectedOutputMantissa: 0xe17b84357691b, expectedOutputExp2: 1145); |
15 | clinger_fast_path_fails_test(inputMantissa: 10, inputExp10: 37); |
16 | clinger_fast_path_fails_test(inputMantissa: 1, inputExp10: 100); |
17 | } |
18 | |
19 | TEST_F(LlvmLibcStrToDblTest, ClingerFastPathFloat64NegativeExp) { |
20 | clinger_fast_path_test(inputMantissa: 1, inputExp10: -10, expectedOutputMantissa: 0xb7cdfd9d7bdbb, expectedOutputExp2: 989); |
21 | clinger_fast_path_test(inputMantissa: 1, inputExp10: -20, expectedOutputMantissa: 0x79ca10c924223, expectedOutputExp2: 956); |
22 | clinger_fast_path_fails_test(inputMantissa: 1, inputExp10: -25); |
23 | } |
24 | |
25 | TEST_F(LlvmLibcStrToDblTest, EiselLemireFloat64Simple) { |
26 | eisel_lemire_test(inputMantissa: 12345678901234567890u, inputExp10: 1, expectedOutputMantissa: 0x1AC53A7E04BCDA, expectedOutputExp2: 1089); |
27 | eisel_lemire_test(inputMantissa: 123, inputExp10: 0, expectedOutputMantissa: 0x1EC00000000000, expectedOutputExp2: 1029); |
28 | eisel_lemire_test(inputMantissa: 12345678901234568192u, inputExp10: 0, expectedOutputMantissa: 0x156A95319D63E2, expectedOutputExp2: 1086); |
29 | } |
30 | |
31 | TEST_F(LlvmLibcStrToDblTest, EiselLemireFloat64SpecificFailures) { |
32 | // These test cases have caused failures in the past. |
33 | eisel_lemire_test(inputMantissa: 358416272, inputExp10: -33, expectedOutputMantissa: 0x1BBB2A68C9D0B9, expectedOutputExp2: 941); |
34 | eisel_lemire_test(inputMantissa: 2166568064000000238u, inputExp10: -9, expectedOutputMantissa: 0x10246690000000, expectedOutputExp2: 1054); |
35 | eisel_lemire_test(inputMantissa: 2794967654709307187u, inputExp10: 1, expectedOutputMantissa: 0x183e132bc608c8, expectedOutputExp2: 1087); |
36 | eisel_lemire_test(inputMantissa: 2794967654709307188u, inputExp10: 1, expectedOutputMantissa: 0x183e132bc608c9, expectedOutputExp2: 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(numStart: "123456789012345678900" , expectedOutputMantissa: 0x1AC53A7E04BCDA, |
50 | expectedOutputExp2: 1089); |
51 | simple_decimal_conversion_test(numStart: "123" , expectedOutputMantissa: 0x1EC00000000000, expectedOutputExp2: 1029); |
52 | simple_decimal_conversion_test(numStart: "12345678901234549760" , expectedOutputMantissa: 0x156A95319D63D8, |
53 | expectedOutputExp2: 1086); |
54 | } |
55 | |
56 | TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicDecimals) { |
57 | simple_decimal_conversion_test(numStart: "1.2345" , expectedOutputMantissa: 0x13c083126e978d, expectedOutputExp2: 1023); |
58 | simple_decimal_conversion_test(numStart: ".2345" , expectedOutputMantissa: 0x1e04189374bc6a, expectedOutputExp2: 1020); |
59 | simple_decimal_conversion_test(numStart: ".299792458" , expectedOutputMantissa: 0x132fccb4aca314, expectedOutputExp2: 1021); |
60 | } |
61 | |
62 | TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicExponents) { |
63 | simple_decimal_conversion_test(numStart: "1e10" , expectedOutputMantissa: 0x12a05f20000000, expectedOutputExp2: 1056); |
64 | simple_decimal_conversion_test(numStart: "1e-10" , expectedOutputMantissa: 0x1b7cdfd9d7bdbb, expectedOutputExp2: 989); |
65 | simple_decimal_conversion_test(numStart: "1e300" , expectedOutputMantissa: 0x17e43c8800759c, expectedOutputExp2: 2019); |
66 | simple_decimal_conversion_test(numStart: "1e-300" , expectedOutputMantissa: 0x156e1fc2f8f359, expectedOutputExp2: 26); |
67 | } |
68 | |
69 | TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicSubnormals) { |
70 | simple_decimal_conversion_test(numStart: "1e-320" , expectedOutputMantissa: 0x7e8, expectedOutputExp2: 0, ERANGE); |
71 | simple_decimal_conversion_test(numStart: "1e-308" , expectedOutputMantissa: 0x730d67819e8d2, expectedOutputExp2: 0, ERANGE); |
72 | simple_decimal_conversion_test(numStart: "2.9e-308" , expectedOutputMantissa: 0x14da6df5e4bcc8, expectedOutputExp2: 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(numStart: "2.225073858507201e-308" , expectedOutputMantissa: 0xfffffffffffff, expectedOutputExp2: 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(numStart: "2.2250738585072012e-308" , expectedOutputMantissa: 0x10000000000000, |
86 | expectedOutputExp2: 1); |
87 | } |
88 | |
89 | TEST(LlvmLibcStrToDblTest, SimpleDecimalConversionExtraTypes) { |
90 | uint64_t double_output_mantissa = 0; |
91 | uint32_t output_exp2 = 0; |
92 | |
93 | LIBC_NAMESPACE::libc_errno = 0; |
94 | auto double_result = |
95 | internal::simple_decimal_conversion<double>(numStart: "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 |
106 | |