1 //===-- Unittests for str_to_float<long double> ---------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/__support/macros/config.h" 10 #include "str_to_fp_test.h" 11 12 #include "src/__support/integer_literals.h" 13 14 namespace LIBC_NAMESPACE_DECL { 15 16 using LlvmLibcStrToLongDblTest = LlvmLibcStrToFloatTest<long double>; 17 using LIBC_NAMESPACE::operator""_u128; 18 19 #if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64) 20 21 TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat64AsLongDouble) { 22 eisel_lemire_test(123, 0, 0x1EC00000000000, 1029); 23 } 24 25 #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80) 26 27 TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Simple) { 28 eisel_lemire_test(123, 0, 0xf600000000000000, 16389); 29 eisel_lemire_test(12345678901234568192u, 0, 0xab54a98ceb1f0c00, 16446); 30 } 31 32 TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80LongerMantissa) { 33 #if __SIZEOF_LONG_DOUBLE__ == 16 34 eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 0, 35 0x91a2b3c091a2b3c1, 16507); 36 eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 300, 37 0xd97757de56adb65c, 17503); 38 eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, -300, 39 0xc30feb9a7618457d, 15510); 40 #elif __SIZEOF_LONG_DOUBLE__ == 12 41 eisel_lemire_test(0x12345678'12345678'12345678_u96, 0, 0x91a2b3c091a2b3c1, 42 16475); 43 eisel_lemire_test(0x12345678'12345678'12345678_u96, 300, 0xd97757de56adb65c, 44 17471); 45 eisel_lemire_test(0x12345678'12345678'12345678_u96, -300, 0xc30feb9a7618457d, 46 15478); 47 #else 48 #error "unhandled long double type" 49 #endif 50 } 51 52 // These tests check numbers at the edge of the DETAILED_POWERS_OF_TEN table. 53 // This doesn't reach very far into the range for long doubles, since it's sized 54 // for doubles and their 11 exponent bits, and not for long doubles and their 55 // 15 exponent bits. This is a known tradeoff, and was made because a proper 56 // long double table would be approximately 16 times longer (specifically the 57 // maximum exponent would need to be about 5000, leading to a 10,000 entry 58 // table). This would have significant memory and storage costs all the time to 59 // speed up a relatively uncommon path. 60 TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80TableLimits) { 61 eisel_lemire_test(1, 347, 0xd13eb46469447567, 17535); 62 eisel_lemire_test(1, -348, 0xfa8fd5a0081c0288, 15226); 63 } 64 65 TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Fallback) { 66 // This number is halfway between two possible results, and the algorithm 67 // can't determine which is correct. 68 ASSERT_FALSE(internal::eisel_lemire<long double>({12345678901234567890u, 1}) 69 .has_value()); 70 71 // These numbers' exponents are out of range for the current powers of ten 72 // table. 73 ASSERT_FALSE(internal::eisel_lemire<long double>({1, 1000}).has_value()); 74 ASSERT_FALSE(internal::eisel_lemire<long double>({1, -1000}).has_value()); 75 } 76 77 TEST_F(LlvmLibcStrToLongDblTest, ClingerFastPathFloat80Simple) { 78 clinger_fast_path_test(123, 0, 0xf600000000000000, 16389); 79 clinger_fast_path_test(1234567, 1, 0xbc61460000000000, 16406); 80 clinger_fast_path_test(12345, -5, 0xfcd35a858793dd98, 16379); 81 } 82 83 #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128) 84 85 TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128Simple) { 86 eisel_lemire_test(123, 0, 0x1ec00'00000000'00000000'00000000_u128, 16389); 87 eisel_lemire_test(12345678901234568192u, 0, 88 0x156a9'5319d63e'18000000'00000000_u128, 16446); 89 } 90 91 TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128LongerMantissa) { 92 eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 0, 93 0x12345'67812345'67812345'67812345_u128, 16507); 94 eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 300, 95 0x1b2ee'afbcad5b'6cb8b445'1dfcde19_u128, 17503); 96 eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, -300, 97 0x1861f'd734ec30'8afa7189'f0f7595f_u128, 15510); 98 } 99 100 TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128Fallback) { 101 ASSERT_FALSE(internal::eisel_lemire<long double>( 102 {0x5ce0e9a5'6015fec5'aadfa328'ae39b333_u128, 1}) 103 .has_value()); 104 } 105 106 TEST_F(LlvmLibcStrToLongDblTest, ClingerFastPathFloat128Simple) { 107 clinger_fast_path_test(123, 0, 0x1ec00'00000000'00000000'00000000_u128, 108 16389); 109 clinger_fast_path_test(1234567, 1, 0x178c2'8c000000'00000000'00000000_u128, 110 16406); 111 clinger_fast_path_test(12345, -5, 0x1f9a6'b50b0f27'bb2fec56'd5cfaace_u128, 112 16379); 113 } 114 115 #else 116 #error "Unknown long double type" 117 #endif 118 119 } // namespace LIBC_NAMESPACE_DECL 120