1#include "str_to_fp_test.h"
2
3#include "src/__support/integer_literals.h"
4
5namespace LIBC_NAMESPACE {
6
7using LlvmLibcStrToLongDblTest = LlvmLibcStrToFloatTest<long double>;
8using LIBC_NAMESPACE::operator""_u128;
9
10#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
11
12TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat64AsLongDouble) {
13 eisel_lemire_test(123, 0, 0x1EC00000000000, 1029);
14}
15
16#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
17
18TEST_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
23TEST_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.
40TEST_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
45TEST_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
59TEST_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
65TEST_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
74TEST_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

source code of libc/test/src/__support/str_to_long_double_test.cpp