@@ -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