@@ -299,100 +299,11 @@ class FloatWriter {
299
299
return 0 ;
300
300
}
301
301
302
- int write_last_block_dec (BlockInt block, size_t block_digits,
303
- RoundDirection round) {
304
- char end_buff[BLOCK_SIZE];
305
-
306
- const DecimalString buf (block + (MAX_BLOCK + 1 ));
307
- const cpp::string_view int_to_str = buf.view ();
308
-
309
- // copy the last block_digits characters into the start of end_buff.
310
- // TODO: Replace with memcpy
311
- for (size_t count = 0 ; count < block_digits; ++count) {
312
- end_buff[count] = int_to_str[count + 1 + (BLOCK_SIZE - block_digits)];
313
- }
314
-
315
- char low_digit = ' 0' ;
316
- if (block_digits > 0 ) {
317
- low_digit = end_buff[block_digits - 1 ];
318
- } else if (max_block_count > 0 ) {
319
- low_digit = ' 9' ;
320
- } else if (buffered_digits > 0 ) {
321
- low_digit = block_buffer[buffered_digits - 1 ];
322
- }
323
-
324
- bool round_up_max_blocks = false ;
325
-
326
- // Round up
327
- if (round == RoundDirection::Up ||
328
- (round == RoundDirection::Even && low_digit % 2 != 0 )) {
329
- bool has_carry = true ;
330
- round_up_max_blocks = true ; // if we're rounding up, we might need to
331
- // round up the max blocks that are buffered.
332
- // handle the low block that we're adding
333
- for (int count = static_cast <int >(block_digits) - 1 ;
334
- count >= 0 && has_carry; --count) {
335
- if (end_buff[count] == ' 9' ) {
336
- end_buff[count] = ' 0' ;
337
- } else {
338
- end_buff[count] += 1 ;
339
- has_carry = false ;
340
- round_up_max_blocks = false ; // If the low block isn't all nines, then
341
- // the max blocks aren't rounded up.
342
- }
343
- }
344
- // handle the high block that's buffered
345
- for (int count = static_cast <int >(buffered_digits) - 1 ;
346
- count >= 0 && has_carry; --count) {
347
- if (block_buffer[count] == ' 9' ) {
348
- block_buffer[count] = ' 0' ;
349
- } else {
350
- block_buffer[count] += 1 ;
351
- has_carry = false ;
352
- }
353
- }
354
-
355
- // has_carry should only be true here if every previous digit is 9, which
356
- // implies that the number has never been written.
357
- if (has_carry /* && !has_written */ ) {
358
- ++total_digits;
359
- ++digits_before_decimal;
360
- // Normally write_left_padding is called by flush_buffer but since we're
361
- // rounding up all of the digits, the ones in the buffer are wrong and
362
- // can't be flushed.
363
- RET_IF_RESULT_NEGATIVE (
364
- padding_writer.write_left_padding (writer, total_digits));
365
- // Now we know we need to print a leading 1, zeroes up to the decimal
366
- // point, the decimal point, and then finally digits after it.
367
- RET_IF_RESULT_NEGATIVE (writer->write (' 1' ));
368
- // digits_before_decimal - 1 to account for the leading '1'
369
- RET_IF_RESULT_NEGATIVE (writer->write (' 0' , digits_before_decimal - 1 ));
370
- if (has_decimal_point) {
371
- RET_IF_RESULT_NEGATIVE (writer->write (DECIMAL_POINT));
372
- // add one to digits_before_decimal to account for the decimal point
373
- // itself.
374
- if (total_digits > digits_before_decimal + 1 ) {
375
- RET_IF_RESULT_NEGATIVE (
376
- writer->write (' 0' , total_digits - (digits_before_decimal + 1 )));
377
- }
378
- }
379
- total_digits_written = total_digits;
380
- return 0 ;
381
- }
382
- }
383
- // Either we intend to round down, or the rounding up is complete. Flush the
384
- // buffers.
385
-
386
- RET_IF_RESULT_NEGATIVE (flush_buffer (round_up_max_blocks));
302
+ int write_last_block (BlockInt block, size_t block_digits,
303
+ RoundDirection round, int exponent = 0 ,
304
+ char exp_char = ' \0 ' ) {
305
+ bool has_exp = (exp_char != ' \0 ' );
387
306
388
- // And then write the final block.
389
- RET_IF_RESULT_NEGATIVE (writer->write ({end_buff, block_digits}));
390
- total_digits_written += block_digits;
391
- return 0 ;
392
- }
393
-
394
- int write_last_block_exp (uint32_t block, size_t block_digits,
395
- RoundDirection round, int exponent, char exp_char) {
396
307
char end_buff[BLOCK_SIZE];
397
308
398
309
{
@@ -450,48 +361,74 @@ class FloatWriter {
450
361
// has_carry should only be true here if every previous digit is 9, which
451
362
// implies that the number has never been written.
452
363
if (has_carry /* && !has_written */ ) {
453
- // Since this is exponential notation, we don't write any more digits
454
- // but we do increment the exponent.
455
- ++exponent;
456
-
457
- const ExponentString buf (exponent);
458
- const cpp::string_view int_to_str = buf.view ();
459
-
460
- // TODO: also change this to calculate the width of the number more
461
- // efficiently.
462
- size_t exponent_width = int_to_str.size ();
463
- size_t number_digits =
464
- buffered_digits + (max_block_count * BLOCK_SIZE) + block_digits;
465
-
466
- // Here we have to recalculate the total number of digits since the
467
- // exponent's width may have changed. We're only adding 1 to exponent
468
- // width since exp_str appends the sign.
469
- total_digits =
470
- (has_decimal_point ? 1 : 0 ) + number_digits + 1 + exponent_width;
471
-
472
- // Normally write_left_padding is called by flush_buffer but since we're
473
- // rounding up all of the digits, the ones in the buffer are wrong and
474
- // can't be flushed.
475
- RET_IF_RESULT_NEGATIVE (
476
- padding_writer.write_left_padding (writer, total_digits));
477
- // Now we know we need to print a leading 1, the decimal point, and then
478
- // zeroes after it.
479
- RET_IF_RESULT_NEGATIVE (writer->write (' 1' ));
480
- // digits_before_decimal - 1 to account for the leading '1'
481
- if (has_decimal_point) {
482
- RET_IF_RESULT_NEGATIVE (writer->write (DECIMAL_POINT));
483
- // This is just the length of the number, not including the decimal
484
- // point, or exponent.
485
-
486
- if (number_digits > 1 ) {
487
- RET_IF_RESULT_NEGATIVE (writer->write (' 0' , number_digits - 1 ));
364
+ if (has_exp) { // This is in %e style
365
+ // Since this is exponential notation, we don't write any more digits
366
+ // but we do increment the exponent.
367
+ ++exponent;
368
+
369
+ const ExponentString buf (exponent);
370
+ const cpp::string_view int_to_str = buf.view ();
371
+
372
+ // TODO: also change this to calculate the width of the number more
373
+ // efficiently.
374
+ size_t exponent_width = int_to_str.size ();
375
+ size_t number_digits =
376
+ buffered_digits + (max_block_count * BLOCK_SIZE) + block_digits;
377
+
378
+ // Here we have to recalculate the total number of digits since the
379
+ // exponent's width may have changed. We're only adding 1 to exponent
380
+ // width since exp_str appends the sign.
381
+ total_digits =
382
+ (has_decimal_point ? 1 : 0 ) + number_digits + 1 + exponent_width;
383
+
384
+ // Normally write_left_padding is called by flush_buffer but since
385
+ // we're rounding up all of the digits, the ones in the buffer are
386
+ // wrong and can't be flushed.
387
+ RET_IF_RESULT_NEGATIVE (
388
+ padding_writer.write_left_padding (writer, total_digits));
389
+ // Now we know we need to print a leading 1, the decimal point, and
390
+ // then zeroes after it.
391
+ RET_IF_RESULT_NEGATIVE (writer->write (' 1' ));
392
+ // digits_before_decimal - 1 to account for the leading '1'
393
+ if (has_decimal_point) {
394
+ RET_IF_RESULT_NEGATIVE (writer->write (DECIMAL_POINT));
395
+ // This is just the length of the number, not including the decimal
396
+ // point, or exponent.
397
+
398
+ if (number_digits > 1 ) {
399
+ RET_IF_RESULT_NEGATIVE (writer->write (' 0' , number_digits - 1 ));
400
+ }
488
401
}
402
+ RET_IF_RESULT_NEGATIVE (writer->write (exp_char));
403
+ RET_IF_RESULT_NEGATIVE (writer->write (int_to_str));
404
+
405
+ total_digits_written = total_digits;
406
+ return WRITE_OK;
407
+ } else { // This is in %f style
408
+ ++total_digits;
409
+ ++digits_before_decimal;
410
+ // Normally write_left_padding is called by flush_buffer but since
411
+ // we're rounding up all of the digits, the ones in the buffer are
412
+ // wrong and can't be flushed.
413
+ RET_IF_RESULT_NEGATIVE (
414
+ padding_writer.write_left_padding (writer, total_digits));
415
+ // Now we know we need to print a leading 1, zeroes up to the decimal
416
+ // point, the decimal point, and then finally digits after it.
417
+ RET_IF_RESULT_NEGATIVE (writer->write (' 1' ));
418
+ // digits_before_decimal - 1 to account for the leading '1'
419
+ RET_IF_RESULT_NEGATIVE (writer->write (' 0' , digits_before_decimal - 1 ));
420
+ if (has_decimal_point) {
421
+ RET_IF_RESULT_NEGATIVE (writer->write (DECIMAL_POINT));
422
+ // add one to digits_before_decimal to account for the decimal point
423
+ // itself.
424
+ if (total_digits > digits_before_decimal + 1 ) {
425
+ RET_IF_RESULT_NEGATIVE (writer->write (
426
+ ' 0' , total_digits - (digits_before_decimal + 1 )));
427
+ }
428
+ }
429
+ total_digits_written = total_digits;
430
+ return WRITE_OK;
489
431
}
490
- RET_IF_RESULT_NEGATIVE (writer->write (exp_char));
491
- RET_IF_RESULT_NEGATIVE (writer->write (int_to_str));
492
-
493
- total_digits_written = total_digits;
494
- return WRITE_OK;
495
432
}
496
433
}
497
434
// Either we intend to round down, or the rounding up is complete. Flush the
@@ -509,10 +446,11 @@ class FloatWriter {
509
446
buffered_digits = block_digits;
510
447
RET_IF_RESULT_NEGATIVE (flush_buffer ());
511
448
512
- RET_IF_RESULT_NEGATIVE (writer->write (exp_char));
513
- const ExponentString buf (exponent);
514
- RET_IF_RESULT_NEGATIVE (writer->write (buf.view ()));
515
-
449
+ if (has_exp) {
450
+ RET_IF_RESULT_NEGATIVE (writer->write (exp_char));
451
+ const ExponentString buf (exponent);
452
+ RET_IF_RESULT_NEGATIVE (writer->write (buf.view ()));
453
+ }
516
454
total_digits_written = total_digits;
517
455
518
456
return WRITE_OK;
@@ -634,7 +572,7 @@ LIBC_INLINE int convert_float_decimal_typed(Writer *writer,
634
572
round = get_round_direction (last_digit, truncated, is_negative);
635
573
636
574
RET_IF_RESULT_NEGATIVE (
637
- float_writer.write_last_block_dec (digits, maximum, round));
575
+ float_writer.write_last_block (digits, maximum, round));
638
576
break ;
639
577
}
640
578
}
@@ -800,7 +738,7 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer,
800
738
}
801
739
round = get_round_direction (last_digit, truncated, is_negative);
802
740
803
- RET_IF_RESULT_NEGATIVE (float_writer.write_last_block_exp (
741
+ RET_IF_RESULT_NEGATIVE (float_writer.write_last_block (
804
742
digits, maximum, round, final_exponent, a + ' E' - ' A' ));
805
743
806
744
RET_IF_RESULT_NEGATIVE (float_writer.right_pad ());
0 commit comments