1 | #include "str_to_fp_test.h" |
2 | |
3 | #include "src/__support/integer_literals.h" |
4 | |
5 | namespace LIBC_NAMESPACE { |
6 | |
7 | using LlvmLibcStrToLongDblTest = LlvmLibcStrToFloatTest<long double>; |
8 | using LIBC_NAMESPACE::operator""_u128 ; |
9 | |
10 | #if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64) |
11 | |
12 | TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat64AsLongDouble) { |
13 | eisel_lemire_test(123, 0, 0x1EC00000000000, 1029); |
14 | } |
15 | |
16 | #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80) |
17 | |
18 | TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Simple) { |
19 | eisel_lemire_test(inputMantissa: 123, inputExp10: 0, expectedOutputMantissa: 0xf600000000000000, expectedOutputExp2: 16389); |
20 | eisel_lemire_test(inputMantissa: 12345678901234568192u, inputExp10: 0, expectedOutputMantissa: 0xab54a98ceb1f0c00, expectedOutputExp2: 16446); |
21 | } |
22 | |
23 | TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80LongerMantissa) { |
24 | eisel_lemire_test(inputMantissa: 0x12345678'12345678'12345678'12345678_u128, inputExp10: 0, |
25 | expectedOutputMantissa: 0x91a2b3c091a2b3c1, expectedOutputExp2: 16507); |
26 | eisel_lemire_test(inputMantissa: 0x12345678'12345678'12345678'12345678_u128, inputExp10: 300, |
27 | expectedOutputMantissa: 0xd97757de56adb65c, expectedOutputExp2: 17503); |
28 | eisel_lemire_test(inputMantissa: 0x12345678'12345678'12345678'12345678_u128, inputExp10: -300, |
29 | expectedOutputMantissa: 0xc30feb9a7618457d, expectedOutputExp2: 15510); |
30 | } |
31 | |
32 | // These tests check numbers at the edge of the DETAILED_POWERS_OF_TEN table. |
33 | // This doesn't reach very far into the range for long doubles, since it's sized |
34 | // for doubles and their 11 exponent bits, and not for long doubles and their |
35 | // 15 exponent bits. This is a known tradeoff, and was made because a proper |
36 | // long double table would be approximately 16 times longer (specifically the |
37 | // maximum exponent would need to be about 5000, leading to a 10,000 entry |
38 | // table). This would have significant memory and storage costs all the time to |
39 | // speed up a relatively uncommon path. |
40 | TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80TableLimits) { |
41 | eisel_lemire_test(inputMantissa: 1, inputExp10: 347, expectedOutputMantissa: 0xd13eb46469447567, expectedOutputExp2: 17535); |
42 | eisel_lemire_test(inputMantissa: 1, inputExp10: -348, expectedOutputMantissa: 0xfa8fd5a0081c0288, expectedOutputExp2: 15226); |
43 | } |
44 | |
45 | TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Fallback) { |
46 | // This number is halfway between two possible results, and the algorithm |
47 | // can't determine which is correct. |
48 | ASSERT_FALSE(internal::eisel_lemire<long double>({12345678901234567890u, 1}) |
49 | .has_value()); |
50 | |
51 | // These numbers' exponents are out of range for the current powers of ten |
52 | // table. |
53 | ASSERT_FALSE(internal::eisel_lemire<long double>({1, 1000}).has_value()); |
54 | ASSERT_FALSE(internal::eisel_lemire<long double>({1, -1000}).has_value()); |
55 | } |
56 | |
57 | #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128) |
58 | |
59 | TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128Simple) { |
60 | eisel_lemire_test(123, 0, 0x1ec00'00000000'00000000'00000000_u128, 16389); |
61 | eisel_lemire_test(12345678901234568192u, 0, |
62 | 0x156a9'5319d63e'18000000'00000000_u128, 16446); |
63 | } |
64 | |
65 | TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128LongerMantissa) { |
66 | eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 0, |
67 | 0x12345'67812345'67812345'67812345_u128, 16507); |
68 | eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 300, |
69 | 0x1b2ee'afbcad5b'6cb8b445'1dfcde19_u128, 17503); |
70 | eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, -300, |
71 | 0x1861f'd734ec30'8afa7189'f0f7595f_u128, 15510); |
72 | } |
73 | |
74 | TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128Fallback) { |
75 | ASSERT_FALSE(internal::eisel_lemire<long double>( |
76 | {0x5ce0e9a5'6015fec5'aadfa328'ae39b333_u128, 1}) |
77 | .has_value()); |
78 | } |
79 | |
80 | #else |
81 | #error "Unknown long double type" |
82 | #endif |
83 | |
84 | } // namespace LIBC_NAMESPACE |
85 | |