diff --git a/include/boost/charconv/to_chars.hpp b/include/boost/charconv/to_chars.hpp index eefffbb..1b88418 100644 --- a/include/boost/charconv/to_chars.hpp +++ b/include/boost/charconv/to_chars.hpp @@ -474,12 +474,15 @@ to_chars_result to_chars_hex(char* first, char* last, Real value, int precision) } // Handle edge cases first + BOOST_ATTRIBUTE_UNUSED char* ptr; switch (std::fpclassify(value)) { case FP_INFINITE: - return {last, EOVERFLOW}; + BOOST_FALLTHROUGH; case FP_NAN: - return {last, EINVAL}; + // The dragonbox impl will return the correct type of NaN + ptr = boost::charconv::detail::to_chars(value, first); + return { ptr, 0 }; case FP_ZERO: std::memcpy(first, "0p+0", 4); return {first + 4, 0}; diff --git a/test/to_chars_float_STL_comp.cpp b/test/to_chars_float_STL_comp.cpp index e069a0f..0693bad 100644 --- a/test/to_chars_float_STL_comp.cpp +++ b/test/to_chars_float_STL_comp.cpp @@ -77,7 +77,7 @@ template void random_test(boost::charconv::chars_format fmt = boost::charconv::chars_format::general) { std::mt19937_64 gen(42); - std::uniform_real_distribution dist(0, std::numeric_limits::max()); + std::uniform_real_distribution dist(std::numeric_limits::lowest(), std::numeric_limits::max()); for (std::size_t i = 0; i < 100'000; ++i) { @@ -86,11 +86,11 @@ void random_test(boost::charconv::chars_format fmt = boost::charconv::chars_form } template -void non_finite_test() +void non_finite_test(boost::charconv::chars_format fmt = boost::charconv::chars_format::general) { - test_spot(std::numeric_limits::infinity()); - test_spot(-std::numeric_limits::infinity()); - test_spot(std::numeric_limits::quiet_NaN()); + test_spot(std::numeric_limits::infinity(), fmt); + test_spot(-std::numeric_limits::infinity(), fmt); + test_spot(std::numeric_limits::quiet_NaN(), fmt); #if (defined(__clang__) && __clang_major__ >= 16) || defined(_MSC_VER) // @@ -98,7 +98,7 @@ void non_finite_test() // // -qNaN = -nan(ind) // - test_spot(-std::numeric_limits::quiet_NaN()); + test_spot(-std::numeric_limits::quiet_NaN(), fmt); #endif #if (defined(__clang__) && __clang_major__ >= 16) @@ -108,8 +108,8 @@ void non_finite_test() // sNaN = nan(snan) // -sNaN = -nan(snan) // - test_spot(std::numeric_limits::signaling_NaN()); - test_spot(-std::numeric_limits::signaling_NaN()); + test_spot(std::numeric_limits::signaling_NaN(), fmt); + test_spot(-std::numeric_limits::signaling_NaN(), fmt); #endif } @@ -122,7 +122,7 @@ void fixed_test() std::mt19937_64 gen(42); std::uniform_real_distribution dist(1, upper_bound); - for (std::size_t i = 0; i < 1000; ++i) + for (std::size_t i = 0; i < 100'000; ++i) { test_spot(dist(gen), boost::charconv::chars_format::fixed); } @@ -146,8 +146,13 @@ int main() fixed_test(); fixed_test(); + // Various non-finite values non_finite_test(); non_finite_test(); + non_finite_test(boost::charconv::chars_format::scientific); + non_finite_test(boost::charconv::chars_format::scientific); + non_finite_test(boost::charconv::chars_format::hex); + non_finite_test(boost::charconv::chars_format::hex); return boost::report_errors(); }