From 4e3036327220ffea9e8b1e7bab9c82cf5118a76e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 18 May 2020 17:36:13 -0700 Subject: [PATCH] Add charconv test cases (#835) * Fix GH-331 ": Test plain shortest's large integer fallback". * Add rounding test cases. --- ..._general_precision_to_chars_test_cases.hpp | 23 ++++++++++++++++++ ...ntific_precision_to_chars_test_cases_1.hpp | 24 +++++++++++++++++++ .../double_to_chars_test_cases.hpp | 8 +++++++ .../float_to_chars_test_cases.hpp | 8 +++++++ 4 files changed, 63 insertions(+) diff --git a/tests/std/tests/P0067R5_charconv/double_general_precision_to_chars_test_cases.hpp b/tests/std/tests/P0067R5_charconv/double_general_precision_to_chars_test_cases.hpp index 46ec3bc7a..49cddcfad 100644 --- a/tests/std/tests/P0067R5_charconv/double_general_precision_to_chars_test_cases.hpp +++ b/tests/std/tests/P0067R5_charconv/double_general_precision_to_chars_test_cases.hpp @@ -5025,4 +5025,27 @@ inline constexpr DoublePrecisionToCharsTestCase double_general_precision_to_char "17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955863276687817154045895" "35143824642343213268894641827684675467035375169860499105765512820762454900903893289440758685084551339423045832" "36903222948165808559332123348274797826204144723168738177180919299881250404026184124858368"}, + + // The UCRT had trouble with rounding this value. charconv was never affected, but let's test it anyways. + {0x1.88e2d605edc3dp+345, chars_format::general, 105, + "109995565999999994887854821710219658911365648587951921896774663603198787416706536331386569598149846892544"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 19, "1.099955659999999949e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 18, "1.09995565999999995e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 17, "1.0999556599999999e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 16, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 15, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 14, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 13, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 12, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 11, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 10, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 9, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 8, "1.0999557e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 7, "1.099956e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 6, "1.09996e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 5, "1.1e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 4, "1.1e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 3, "1.1e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 2, "1.1e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::general, 1, "1e+104"}, }; diff --git a/tests/std/tests/P0067R5_charconv/double_scientific_precision_to_chars_test_cases_1.hpp b/tests/std/tests/P0067R5_charconv/double_scientific_precision_to_chars_test_cases_1.hpp index 625746411..3699ccf4f 100644 --- a/tests/std/tests/P0067R5_charconv/double_scientific_precision_to_chars_test_cases_1.hpp +++ b/tests/std/tests/P0067R5_charconv/double_scientific_precision_to_chars_test_cases_1.hpp @@ -287,4 +287,28 @@ inline constexpr DoublePrecisionToCharsTestCase double_scientific_precision_to_c {1e-63, chars_format::scientific, 1, "1.0e-63"}, {1e+83, chars_format::scientific, 0, "1e+83"}, {1e+83, chars_format::scientific, 1, "1.0e+83"}, + + // The UCRT had trouble with rounding this value. charconv was never affected, but let's test it anyways. + {0x1.88e2d605edc3dp+345, chars_format::scientific, 104, + "1.09995565999999994887854821710219658911365648587951921896774663603198787416706536331386569598149846892544e+" + "104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 18, "1.099955659999999949e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 17, "1.09995565999999995e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 16, "1.0999556599999999e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 15, "1.099955660000000e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 14, "1.09995566000000e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 13, "1.0999556600000e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 12, "1.099955660000e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 11, "1.09995566000e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 10, "1.0999556600e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 9, "1.099955660e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 8, "1.09995566e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 7, "1.0999557e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 6, "1.099956e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 5, "1.09996e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 4, "1.1000e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 3, "1.100e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 2, "1.10e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 1, "1.1e+104"}, + {0x1.88e2d605edc3dp+345, chars_format::scientific, 0, "1e+104"}, }; diff --git a/tests/std/tests/P0067R5_charconv/double_to_chars_test_cases.hpp b/tests/std/tests/P0067R5_charconv/double_to_chars_test_cases.hpp index 110eb156c..5b5e41b6d 100644 --- a/tests/std/tests/P0067R5_charconv/double_to_chars_test_cases.hpp +++ b/tests/std/tests/P0067R5_charconv/double_to_chars_test_cases.hpp @@ -2787,6 +2787,14 @@ inline constexpr DoubleToCharsTestCase double_to_chars_test_cases[] = { {1.234e9, chars_format{}, "1.234e+09"}, {1.234e10, chars_format{}, "1.234e+10"}, + // GH-331 ": Test plain shortest's large integer fallback" + // The exactly-representable integer 123456789012345683968 is 21 digits, but scientific shortest needs 22 + // characters. Therefore, the plain overload must select fixed notation. Because this 21-digit number exceeds the + // 17-digit round-trip limit, we can't use Ryu - we need to activate the large integer fallback (Ryu Printf for + // double). + {123456789012345683968.0, chars_format::scientific, "1.2345678901234568e+20"}, + {123456789012345683968.0, chars_format{}, "123456789012345683968"}, + // Exact value is 1.9156918820264798304697...e-56, incorrectly rounded by dtoa_milo() (Grisu2). {0x1.e0ffed391517ep-186, chars_format::scientific, "1.9156918820264798e-56"}, diff --git a/tests/std/tests/P0067R5_charconv/float_to_chars_test_cases.hpp b/tests/std/tests/P0067R5_charconv/float_to_chars_test_cases.hpp index afd42680b..3c2d67f79 100644 --- a/tests/std/tests/P0067R5_charconv/float_to_chars_test_cases.hpp +++ b/tests/std/tests/P0067R5_charconv/float_to_chars_test_cases.hpp @@ -497,6 +497,14 @@ inline constexpr FloatToCharsTestCase float_to_chars_test_cases[] = { {1.234e9f, chars_format{}, "1.234e+09"}, {1.234e10f, chars_format{}, "1.234e+10"}, + // GH-331 ": Test plain shortest's large integer fallback" + // The exactly-representable integer 123456790528 is 12 digits, but scientific shortest needs 13 characters. + // Therefore, the plain overload must select fixed notation. Because this 12-digit number exceeds the 9-digit + // round-trip limit, we can't use Ryu - we need to activate the large integer fallback (currently, long division for + // float). + {123456790528.0f, chars_format::scientific, "1.2345679e+11"}, + {123456790528.0f, chars_format{}, "123456790528"}, + // Test hexfloat corner cases. {0x1.728p+0f, chars_format::hex, "1.728p+0"}, // instead of "2.e5p-1" {0x0.000002p-126f, chars_format::hex, "0.000002p-126"}, // instead of "1p-149", min subnormal