Skip to content

Commit 4233caf

Browse files
reorganize and comment to clarify design
1 parent d5439cc commit 4233caf

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

libc/src/__support/float_to_string.h

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,10 @@ template <> class FloatToString<long double> {
648648
static constexpr size_t EXTRA_INT_WIDTH =
649649
internal::div_ceil(sizeof(long double) * 8, 64) * 64;
650650

651-
cpp::UInt<FLOAT_AS_INT_WIDTH + EXTRA_INT_WIDTH> float_as_int = 0;
651+
// float_as_fixed represents the floating point number as a fixed point number
652+
// with the point EXTRA_INT_WIDTH bits from the left of the number. This can
653+
// store any number with a negative exponent.
654+
cpp::UInt<FLOAT_AS_INT_WIDTH + EXTRA_INT_WIDTH> float_as_fixed = 0;
652655
int int_block_index = 0;
653656

654657
static constexpr size_t BLOCK_BUFFER_LEN =
@@ -675,20 +678,25 @@ template <> class FloatToString<long double> {
675678
}
676679
}
677680

681+
// init_convert initializes float_as_int, cur_block, and block_buffer based on
682+
// the mantissa and exponent of the initial number. Calling it will always
683+
// return the class to the starting state.
678684
LIBC_INLINE constexpr void init_convert() {
679-
// This initializes float_as_int, cur_block, and block_buffer.
680-
681-
float_as_int = mantissa;
682-
683685
// No calculation necessary for the 0 case.
684686
if (mantissa == 0 && exponent == 0) {
685687
return;
686688
}
687689

688690
if (exponent > 0) {
689691
// if the exponent is positive, then the number is fully above the decimal
690-
// point. Shift left by exponent to get the integer representation of this
691-
// number.
692+
// point. In this case we represent the float as an integer, then divide
693+
// by 10^BLOCK_SIZE and take the remainder as our next block. This
694+
// generates the digits from right to left, but the digits will be written
695+
// from left to right, so it caches the results so they can be read in
696+
// reverse order.
697+
698+
cpp::UInt<FLOAT_AS_INT_WIDTH + EXTRA_INT_WIDTH> float_as_int = mantissa;
699+
692700
float_as_int.shift_left(exponent);
693701
int_block_index = 0;
694702

@@ -701,17 +709,18 @@ template <> class FloatToString<long double> {
701709

702710
} else {
703711
// if the exponent is not positive, then the number is at least partially
704-
// below the decimal point. Shift left to make the int a fixed point
705-
// representation with the decimal point after the top EXTRA_INT_WIDTH
706-
// bits.
712+
// below the decimal point. In this case we represent the float as a fixed
713+
// point number with the decimal point after the top EXTRA_INT_WIDTH bits.
714+
float_as_fixed = mantissa;
715+
707716
const int SHIFT_AMOUNT = FLOAT_AS_INT_WIDTH + exponent;
708717
static_assert(EXTRA_INT_WIDTH >= sizeof(long double) * 8);
709-
float_as_int.shift_left(SHIFT_AMOUNT);
718+
float_as_fixed.shift_left(SHIFT_AMOUNT);
710719

711720
// If there are still digits above the decimal point, handle those.
712-
if (float_as_int.clz() < EXTRA_INT_WIDTH) {
721+
if (float_as_fixed.clz() < EXTRA_INT_WIDTH) {
713722
cpp::UInt<EXTRA_INT_WIDTH> above_decimal_point =
714-
float_as_int >> FLOAT_AS_INT_WIDTH;
723+
float_as_fixed >> FLOAT_AS_INT_WIDTH;
715724

716725
size_t positive_int_block_index = 0;
717726
while (above_decimal_point > 0) {
@@ -722,7 +731,7 @@ template <> class FloatToString<long double> {
722731
block_buffer_valid = positive_int_block_index;
723732

724733
// Zero all digits above the decimal point.
725-
zero_leading_digits(float_as_int);
734+
zero_leading_digits(float_as_fixed);
726735
int_block_index = 0;
727736
}
728737
}
@@ -822,14 +831,14 @@ template <> class FloatToString<long double> {
822831
// If we are currently before the requested block. Step until we reach the
823832
// requested block. This is likely to only be one step.
824833
while (block_index < int_block_index) {
825-
zero_leading_digits(float_as_int);
826-
float_as_int.mul(1000000000);
834+
zero_leading_digits(float_as_fixed);
835+
float_as_fixed.mul(1000000000);
827836
--int_block_index;
828837
}
829838

830839
// We're currently on the requested block, return the current block.
831840
BlockInt cur_block =
832-
static_cast<BlockInt>(float_as_int >> FLOAT_AS_INT_WIDTH);
841+
static_cast<BlockInt>(float_as_fixed >> FLOAT_AS_INT_WIDTH);
833842
return cur_block;
834843
}
835844

0 commit comments

Comments
 (0)