Skip to content

Commit 59bbbe7

Browse files
authored
Merge pull request #991 from cppalliance/develop
Merge to Master for v5.1.1
2 parents 588e26e + c5ff5c2 commit 59bbbe7

File tree

8 files changed

+433
-338
lines changed

8 files changed

+433
-338
lines changed

include/boost/decimal/charconv.hpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,45 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, c
310310
const auto digits_to_remove {significand_digits - (local_precision + 2)};
311311
significand /= pow10(static_cast<typename TargetDecimalType::significand_type>(digits_to_remove));
312312
significand_digits -= digits_to_remove;
313+
const auto original_sig {significand};
313314
fenv_round(significand);
315+
if (remove_trailing_zeros(original_sig + 1U).trimmed_number == 1U)
316+
{
317+
++exp;
318+
if (exp == 0)
319+
{
320+
*first++ = '1';
321+
if (local_precision > 0)
322+
{
323+
*first++ = '.';
324+
std::memset(first, '0', static_cast<std::size_t>(local_precision));
325+
first += local_precision;
326+
}
327+
std::memcpy(first, "e+00", 4u);
328+
return {first + 4u, std::errc()};
329+
}
330+
}
314331
}
315332
else if (significand_digits > local_precision + 1)
316333
{
334+
const auto original_sig = significand;
317335
fenv_round(significand);
336+
if (remove_trailing_zeros(original_sig + 1U).trimmed_number == 1U)
337+
{
338+
++exp;
339+
if (exp == 0)
340+
{
341+
*first++ = '1';
342+
if (local_precision > 0)
343+
{
344+
*first++ = '.';
345+
std::memset(first, '0', static_cast<std::size_t>(local_precision));
346+
first += local_precision;
347+
}
348+
std::memcpy(first, "e+00", 4u);
349+
return {first + 4u, std::errc()};
350+
}
351+
}
318352
}
319353
}
320354
else if (significand_digits < local_precision && fmt != chars_format::general)
@@ -495,6 +529,27 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const
495529
num_dig -= static_cast<int>(zeros_removal.number_of_removed_zeros);
496530
}
497531

532+
// We could have the case where we are rounding 0.9999 to 1.000
533+
if (-exponent >= 0 && -exponent < std::numeric_limits<target_decimal_significand_type>::digits10 &&
534+
significand == detail::pow10(static_cast<target_decimal_significand_type>(-exponent)) && fmt == chars_format::fixed)
535+
{
536+
*first++ = '1';
537+
if (local_precision > 0 && local_precision <= buffer_size)
538+
{
539+
*first++ = '.';
540+
std::memset(first, '0', static_cast<std::size_t>(local_precision));
541+
return {first + local_precision, std::errc{}};
542+
}
543+
else if (local_precision > buffer_size)
544+
{
545+
return {last, std::errc::value_too_large};
546+
}
547+
else
548+
{
549+
return {first, std::errc{}};
550+
}
551+
}
552+
498553
// Make sure the result will fit in the buffer
499554
const std::ptrdiff_t total_length = total_buffer_length<TargetDecimalType>(num_dig, exponent, is_neg) + num_leading_zeros;
500555
if (total_length > buffer_size)
@@ -556,7 +611,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const
556611
{
557612
return {r.ptr, std::errc()};
558613
}
559-
else if (abs_value >= 1)
614+
else if (abs_value >= 1 || (significand == 1U && exponent == 0))
560615
{
561616
if (exponent < 0 && -exponent < buffer_size)
562617
{

0 commit comments

Comments
 (0)