@@ -310,11 +310,45 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, c
310
310
const auto digits_to_remove {significand_digits - (local_precision + 2 )};
311
311
significand /= pow10 (static_cast <typename TargetDecimalType::significand_type>(digits_to_remove));
312
312
significand_digits -= digits_to_remove;
313
+ const auto original_sig {significand};
313
314
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
+ }
314
331
}
315
332
else if (significand_digits > local_precision + 1 )
316
333
{
334
+ const auto original_sig = significand;
317
335
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
+ }
318
352
}
319
353
}
320
354
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
495
529
num_dig -= static_cast <int >(zeros_removal.number_of_removed_zeros );
496
530
}
497
531
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
+
498
553
// Make sure the result will fit in the buffer
499
554
const std::ptrdiff_t total_length = total_buffer_length<TargetDecimalType>(num_dig, exponent, is_neg) + num_leading_zeros;
500
555
if (total_length > buffer_size)
@@ -556,7 +611,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const
556
611
{
557
612
return {r.ptr , std::errc ()};
558
613
}
559
- else if (abs_value >= 1 )
614
+ else if (abs_value >= 1 || (significand == 1U && exponent == 0 ) )
560
615
{
561
616
if (exponent < 0 && -exponent < buffer_size)
562
617
{
0 commit comments