mirror of
https://github.com/boostorg/charconv.git
synced 2026-02-14 00:32:11 +00:00
Fix scientific formatting when exponent is 0
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <boost/charconv/detail/dragonbox_common.hpp>
|
||||
#include <boost/charconv/detail/bit_layouts.hpp>
|
||||
#include <boost/charconv/detail/emulated128.hpp>
|
||||
#include <boost/charconv/chars_format.hpp>
|
||||
#include <boost/core/bit.hpp>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
@@ -2559,11 +2560,11 @@ BOOST_FORCEINLINE BOOST_CHARCONV_SAFEBUFFERS auto to_decimal(Float x, Policies..
|
||||
|
||||
namespace to_chars_detail {
|
||||
template <class Float, class FloatTraits>
|
||||
extern char* to_chars(typename FloatTraits::carrier_uint significand, int exponent, char* buffer) noexcept;
|
||||
extern char* to_chars(typename FloatTraits::carrier_uint significand, int exponent, char* buffer, chars_format fmt) noexcept;
|
||||
|
||||
// Avoid needless ABI overhead incurred by tag dispatch.
|
||||
template <class PolicyHolder, class Float, class FloatTraits>
|
||||
char* to_chars_n_impl(dragonbox_float_bits<Float, FloatTraits> br, char* buffer) noexcept
|
||||
char* to_chars_n_impl(dragonbox_float_bits<Float, FloatTraits> br, char* buffer, chars_format fmt) noexcept
|
||||
{
|
||||
const auto exponent_bits = br.extract_exponent_bits();
|
||||
const auto s = br.remove_exponent_bits(exponent_bits);
|
||||
@@ -2583,7 +2584,7 @@ namespace to_chars_detail {
|
||||
typename PolicyHolder::binary_to_decimal_rounding_policy{},
|
||||
typename PolicyHolder::cache_policy{});
|
||||
return to_chars_detail::to_chars<Float, FloatTraits>(result.significand,
|
||||
result.exponent, buffer);
|
||||
result.exponent, buffer, fmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2664,7 +2665,7 @@ namespace to_chars_detail {
|
||||
|
||||
// Returns the next-to-end position
|
||||
template <typename Float, typename FloatTraits = dragonbox_float_traits<Float>, typename... Policies>
|
||||
char* to_chars_n(Float x, char* buffer, BOOST_ATTRIBUTE_UNUSED Policies... policies) noexcept
|
||||
char* to_chars_n(Float x, char* buffer, chars_format fmt, BOOST_ATTRIBUTE_UNUSED Policies... policies) noexcept
|
||||
{
|
||||
using namespace policy_impl;
|
||||
|
||||
@@ -2686,14 +2687,14 @@ char* to_chars_n(Float x, char* buffer, BOOST_ATTRIBUTE_UNUSED Policies... polic
|
||||
|
||||
#endif
|
||||
|
||||
return to_chars_detail::to_chars_n_impl<policy_holder>(dragonbox_float_bits<Float, FloatTraits>(x), buffer);
|
||||
return to_chars_detail::to_chars_n_impl<policy_holder>(dragonbox_float_bits<Float, FloatTraits>(x), buffer, fmt);
|
||||
}
|
||||
|
||||
// Null-terminate and bypass the return value of fp_to_chars_n
|
||||
template <typename Float, typename FloatTraits = dragonbox_float_traits<Float>, typename... Policies>
|
||||
char* to_chars(Float x, char* buffer, Policies... policies) noexcept
|
||||
char* to_chars(Float x, char* buffer, chars_format fmt, Policies... policies) noexcept
|
||||
{
|
||||
auto ptr = to_chars_n<Float, FloatTraits>(x, buffer, policies...);
|
||||
auto ptr = to_chars_n<Float, FloatTraits>(x, buffer, fmt, policies...);
|
||||
*ptr = '\0';
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ to_chars_result to_chars_hex(char* first, char* last, Real value, int precision)
|
||||
BOOST_FALLTHROUGH;
|
||||
case FP_NAN:
|
||||
// The dragonbox impl will return the correct type of NaN
|
||||
ptr = boost::charconv::detail::to_chars(value, first);
|
||||
ptr = boost::charconv::detail::to_chars(value, first, chars_format::general);
|
||||
return { ptr, 0 };
|
||||
case FP_ZERO:
|
||||
if (std::signbit(value))
|
||||
@@ -692,13 +692,13 @@ to_chars_result to_chars_float_impl(char* first, char* last, Real value, chars_f
|
||||
}
|
||||
else
|
||||
{
|
||||
auto* ptr = boost::charconv::detail::to_chars(value, first);
|
||||
auto* ptr = boost::charconv::detail::to_chars(value, first, fmt);
|
||||
return { ptr, 0 };
|
||||
}
|
||||
}
|
||||
else if (fmt == boost::charconv::chars_format::scientific)
|
||||
{
|
||||
auto* ptr = boost::charconv::detail::to_chars(value, first);
|
||||
auto* ptr = boost::charconv::detail::to_chars(value, first, fmt);
|
||||
return { ptr, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det
|
||||
}
|
||||
|
||||
template <>
|
||||
char* to_chars<float, dragonbox_float_traits<float>>(std::uint32_t s32, int exponent, char* buffer) noexcept
|
||||
char* to_chars<float, dragonbox_float_traits<float>>(std::uint32_t s32, int exponent, char* buffer, chars_format fmt) noexcept
|
||||
{
|
||||
// Print significand.
|
||||
print_9_digits(s32, exponent, buffer);
|
||||
@@ -311,28 +311,30 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det
|
||||
buffer += 2;
|
||||
exponent = -exponent;
|
||||
}
|
||||
else if (exponent == 0)
|
||||
{
|
||||
if (fmt == chars_format::scientific)
|
||||
{
|
||||
std::memcpy(buffer, "e+00", 4);
|
||||
buffer += 4;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(buffer, "e+", 2);
|
||||
buffer += 2;
|
||||
}
|
||||
|
||||
if (exponent >= 10)
|
||||
{
|
||||
print_2_digits(std::uint32_t(exponent), buffer);
|
||||
buffer += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_1_digit(std::uint32_t(exponent), buffer);
|
||||
buffer += 1;
|
||||
}
|
||||
print_2_digits(std::uint32_t(exponent), buffer);
|
||||
buffer += 2;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <>
|
||||
char* to_chars<double, dragonbox_float_traits<double>>(const std::uint64_t significand, int exponent, char* buffer) noexcept {
|
||||
char* to_chars<double, dragonbox_float_traits<double>>(const std::uint64_t significand, int exponent, char* buffer, chars_format fmt) noexcept {
|
||||
// Print significand by decomposing it into a 9-digit block and a 8-digit block.
|
||||
std::uint32_t first_block;
|
||||
std::uint32_t second_block {};
|
||||
@@ -522,6 +524,12 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det
|
||||
}
|
||||
else if (exponent == 0)
|
||||
{
|
||||
if (fmt == chars_format::scientific)
|
||||
{
|
||||
std::memcpy(buffer, "e+00", 4);
|
||||
buffer += 4;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user