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