| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 3 | |
| 4 | #ifndef FLOAT_FROM_CHARS_TEST_CASES_HPP |
| 5 | #define FLOAT_FROM_CHARS_TEST_CASES_HPP |
| 6 | |
| 7 | #include <charconv> |
| 8 | #include <stddef.h> |
| 9 | #include <system_error> |
| 10 | using namespace std; |
| 11 | |
| 12 | inline constexpr FloatFromCharsTestCase float_from_chars_test_cases[] = { |
| 13 | {.input: "1.a0000400" , .fmt: chars_format::hex, .correct_idx: 10, .correct_ec: errc{}, .correct_value: 0x1.a00004p0f}, // exact |
| 14 | {.input: "1.a0000401" , .fmt: chars_format::hex, .correct_idx: 10, .correct_ec: errc{}, .correct_value: 0x1.a00004p0f}, // below midpoint, round down |
| 15 | {.input: "1.a0000500" , .fmt: chars_format::hex, .correct_idx: 10, .correct_ec: errc{}, .correct_value: 0x1.a00004p0f}, // midpoint, round down to even |
| 16 | {.input: "1.a0000501" , .fmt: chars_format::hex, .correct_idx: 10, .correct_ec: errc{}, .correct_value: 0x1.a00006p0f}, // above midpoint, round up |
| 17 | {.input: "1.a0000600" , .fmt: chars_format::hex, .correct_idx: 10, .correct_ec: errc{}, .correct_value: 0x1.a00006p0f}, // exact |
| 18 | {.input: "1.a0000601" , .fmt: chars_format::hex, .correct_idx: 10, .correct_ec: errc{}, .correct_value: 0x1.a00006p0f}, // below midpoint, round down |
| 19 | {.input: "1.a0000700" , .fmt: chars_format::hex, .correct_idx: 10, .correct_ec: errc{}, .correct_value: 0x1.a00008p0f}, // midpoint, round up to even |
| 20 | {.input: "1.a0000701" , .fmt: chars_format::hex, .correct_idx: 10, .correct_ec: errc{}, .correct_value: 0x1.a00008p0f}, // above midpoint, round up |
| 21 | |
| 22 | {.input: "1.0000040" , .fmt: chars_format::hex, .correct_idx: 9, .correct_ec: errc{}, .correct_value: 0x1.000004p0f}, // exact |
| 23 | {.input: "1.0000041" , .fmt: chars_format::hex, .correct_idx: 9, .correct_ec: errc{}, .correct_value: 0x1.000004p0f}, // below midpoint, round down |
| 24 | {.input: "1.0000050" , .fmt: chars_format::hex, .correct_idx: 9, .correct_ec: errc{}, .correct_value: 0x1.000004p0f}, // midpoint, round down to even |
| 25 | {.input: "1.0000051" , .fmt: chars_format::hex, .correct_idx: 9, .correct_ec: errc{}, .correct_value: 0x1.000006p0f}, // above midpoint, round up |
| 26 | {.input: "1.0000060" , .fmt: chars_format::hex, .correct_idx: 9, .correct_ec: errc{}, .correct_value: 0x1.000006p0f}, // exact |
| 27 | {.input: "1.0000061" , .fmt: chars_format::hex, .correct_idx: 9, .correct_ec: errc{}, .correct_value: 0x1.000006p0f}, // below midpoint, round down |
| 28 | {.input: "1.0000070" , .fmt: chars_format::hex, .correct_idx: 9, .correct_ec: errc{}, .correct_value: 0x1.000008p0f}, // midpoint, round up to even |
| 29 | {.input: "1.0000071" , .fmt: chars_format::hex, .correct_idx: 9, .correct_ec: errc{}, .correct_value: 0x1.000008p0f}, // above midpoint, round up |
| 30 | |
| 31 | {.input: "1.0000002384185791015625000000" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000004p0f}, // exact |
| 32 | {.input: "1.0000002421438694000244140625" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000004p0f}, // below midpoint, round down |
| 33 | {.input: "1.0000002980232238769531249999" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000004p0f}, // below midpoint, round down |
| 34 | {.input: "1.0000002980232238769531250000" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, |
| 35 | .correct_value: 0x1.000004p0f}, // midpoint, round down to even |
| 36 | {.input: "1.0000002980232238769531250001" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000006p0f}, // above midpoint, round up |
| 37 | {.input: "1.0000003017485141754150390625" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000006p0f}, // above midpoint, round up |
| 38 | {.input: "1.0000003576278686523437500000" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000006p0f}, // exact |
| 39 | {.input: "1.0000003613531589508056640625" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000006p0f}, // below midpoint, round down |
| 40 | {.input: "1.0000004172325134277343749999" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000006p0f}, // below midpoint, round down |
| 41 | {.input: "1.0000004172325134277343750000" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000008p0f}, // midpoint, round up to even |
| 42 | {.input: "1.0000004172325134277343750001" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000008p0f}, // above midpoint, round up |
| 43 | {.input: "1.0000004209578037261962890625" , .fmt: chars_format::general, .correct_idx: 30, .correct_ec: errc{}, .correct_value: 0x1.000008p0f}, // above midpoint, round up |
| 44 | |
| 45 | // VSO-838635 "<charconv>: from_chars() mishandles certain subnormals" |
| 46 | // This bug didn't actually affect float, but we should have similar test cases. |
| 47 | // These values change on half-ulp boundaries: |
| 48 | // 1 * 2^-150 ~= 7.01e-46 (half-ulp between zero and min subnormal) |
| 49 | // 2 * 2^-150 ~= 1.40e-45 (min subnormal) |
| 50 | // 3 * 2^-150 ~= 2.10e-45 (half-ulp between min subnormal and next subnormal) |
| 51 | // 4 * 2^-150 ~= 2.80e-45 (next subnormal) |
| 52 | {.input: "6." |
| 53 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 54 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 55 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 56 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 57 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 58 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 59 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 60 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 61 | "6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666" |
| 62 | "6666666666666666666e-46" , |
| 63 | .fmt: chars_format::scientific, .correct_idx: 1006, .correct_ec: errc::result_out_of_range, .correct_value: 0x0.000000p+0f}, |
| 64 | {.input: "7." |
| 65 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 66 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 67 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 68 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 69 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 70 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 71 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 72 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 73 | "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" |
| 74 | "7777777777777777777e-46" , |
| 75 | .fmt: chars_format::scientific, .correct_idx: 1006, .correct_ec: errc{}, .correct_value: 0x0.000002p-126f}, |
| 76 | {.input: "8." |
| 77 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 78 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 79 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 80 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 81 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 82 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 83 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 84 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 85 | "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888" |
| 86 | "8888888888888888888e-46" , |
| 87 | .fmt: chars_format::scientific, .correct_idx: 1006, .correct_ec: errc{}, .correct_value: 0x0.000002p-126f}, |
| 88 | {.input: "9." |
| 89 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 90 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 91 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 92 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 93 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 94 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 95 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 96 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 97 | "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" |
| 98 | "9999999999999999999e-46" , |
| 99 | .fmt: chars_format::scientific, .correct_idx: 1006, .correct_ec: errc{}, .correct_value: 0x0.000002p-126f}, |
| 100 | {.input: "1." |
| 101 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 102 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 103 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 104 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 105 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 106 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 107 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 108 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 109 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" |
| 110 | "1111111111111111111e-45" , |
| 111 | .fmt: chars_format::scientific, .correct_idx: 1006, .correct_ec: errc{}, .correct_value: 0x0.000002p-126f}, |
| 112 | {.input: "2." |
| 113 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 114 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 115 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 116 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 117 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 118 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 119 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 120 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 121 | "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" |
| 122 | "2222222222222222222e-45" , |
| 123 | .fmt: chars_format::scientific, .correct_idx: 1006, .correct_ec: errc{}, .correct_value: 0x0.000004p-126f}, |
| 124 | |
| 125 | // VSO-733765 "<charconv>: [Feedback] double std::from_chars behavior on exponent out of range" |
| 126 | // LWG-3081 "Floating point from_chars API does not distinguish between overflow and underflow" |
| 127 | // These test cases exercise every overflow/underflow codepath. |
| 128 | {.input: "1e+1000" , .fmt: chars_format::scientific, .correct_idx: 7, .correct_ec: errc::result_out_of_range, .correct_value: float_inf}, |
| 129 | {.input: "1e-1000" , .fmt: chars_format::scientific, .correct_idx: 7, .correct_ec: errc::result_out_of_range, .correct_value: 0.0f}, |
| 130 | {.input: "1.ffffffp+127" , .fmt: chars_format::hex, .correct_idx: 13, .correct_ec: errc::result_out_of_range, .correct_value: float_inf}, |
| 131 | {.input: "1e+2000" , .fmt: chars_format::scientific, .correct_idx: 7, .correct_ec: errc::result_out_of_range, .correct_value: float_inf}, |
| 132 | {.input: "1e-2000" , .fmt: chars_format::scientific, .correct_idx: 7, .correct_ec: errc::result_out_of_range, .correct_value: 0.0f}, |
| 133 | {.input: "1e+9999" , .fmt: chars_format::scientific, .correct_idx: 7, .correct_ec: errc::result_out_of_range, .correct_value: float_inf}, |
| 134 | {.input: "1e-9999" , .fmt: chars_format::scientific, .correct_idx: 7, .correct_ec: errc::result_out_of_range, .correct_value: 0.0f}, |
| 135 | {.input: "10e+5199" , .fmt: chars_format::scientific, .correct_idx: 8, .correct_ec: errc::result_out_of_range, .correct_value: float_inf}, |
| 136 | {.input: "0.001e-5199" , .fmt: chars_format::scientific, .correct_idx: 11, .correct_ec: errc::result_out_of_range, .correct_value: 0.0f}, |
| 137 | }; |
| 138 | |
| 139 | #endif // FLOAT_FROM_CHARS_TEST_CASES_HPP |
| 140 | |