#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(BOOST_HAS_FLOAT128) && defined(__STDCPP_FLOAT128_T__) && !defined(BOOST_NO_CXX17_HDR_CHARCONV) // coming soon https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113260 namespace std { inline from_chars_result from_chars(const char* first, const char* last, boost::math::cstdfloat::detail::float_internal128_t& value, chars_format fmt = chars_format::general) noexcept { return from_chars(first, last, reinterpret_cast(value), fmt); } inline to_chars_result to_chars(char* first, char* last, boost::math::cstdfloat::detail::float_internal128_t value, chars_format fmt, int precision) noexcept { return to_chars(first, last, float128_t(value), fmt, precision); } inline to_chars_result to_chars(char* first, char* last, boost::math::cstdfloat::detail::float_internal128_t value, chars_format fmt) noexcept { return to_chars(first, last, float128_t(value), fmt); } } // std #endif namespace test { using buffer_type = std::array; inline static constexpr std::string_view scientific{"scientific"}, general {"general "}, fixed {"fixed "}, hex {"hex "}; template inline std::string nameof() { return boost::core::demangle(typeid(Type).name()); } inline constexpr std::string_view to_string(const std::chars_format format) noexcept { switch (format) { case std::chars_format::scientific: return scientific; case std::chars_format::fixed: return fixed; case std::chars_format::hex: return hex; default: return general; } } inline constexpr boost::charconv::chars_format to_format(const std::chars_format format) noexcept { switch (format) { case std::chars_format::scientific: return boost::charconv::chars_format::scientific; case std::chars_format::fixed: return boost::charconv::chars_format::fixed; case std::chars_format::hex: return boost::charconv::chars_format::hex; default: return boost::charconv::chars_format::general; } } inline constexpr std::to_chars_result to_result(const boost::charconv::to_chars_result& result) noexcept { return {result.ptr, result.ec}; } inline void show_result(const std::string_view& info, const std::chars_format format, const buffer_type& buffer, const std::to_chars_result& result) { const size_t size = size_t(result.ptr - buffer.data()); std::cout << '(' << info << ", " << to_string(format) << ")\t"; if (size <= buffer.size()) { if (result.ec == std::errc{}) { std::cout << std::string_view{buffer.data(), result.ptr} << '\t'; } else { std::cout << "{}\t"; } } else { std::cout << "BOF!\t"; } std::cout << '(' << size << ", " << std::make_error_code(result.ec).message() << ")\n"; } template inline void show_format(buffer_type& buffer, const Type value, const std::chars_format format) { std::to_chars_result result; buffer.fill(0); result = std::to_chars(buffer.data(), buffer.data()+buffer.size(), value, format); show_result("std ", format, buffer, result); buffer.fill(0); result = to_result(boost::charconv::to_chars(buffer.data(), buffer.data()+buffer.size(), value, to_format(format))); show_result("boost", format, buffer, result); std::cout << '\n'; } template void show(const Type value) { buffer_type buffer; std::cout << nameof() << '\n'; show_format(buffer, value, std::chars_format::scientific); show_format(buffer, value, std::chars_format::fixed); show_format(buffer, value, std::chars_format::hex); show_format(buffer, value, std::chars_format::general); std::cout << '\n'; } } // test int main() { using T = std::float128_t; using L = std::numeric_limits; constexpr T //value = -L::quiet_NaN(); value = -35896.53987658756543653653365436f128; test::show(value); test::show(boost::float80_t(value)); test::show(std::float64_t(value)); test::show(std::float32_t(value)); test::show(std::float16_t(value)); test::show(std::bfloat16_t(value)); return EXIT_SUCCESS; }