1 //===-- Decimal Float Converter for printf ----------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_H
10 #define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_H
12 #include "src/__support/CPP/string_view.h"
13 #include "src/__support/FPUtil/FEnvImpl.h"
14 #include "src/__support/FPUtil/FPBits.h"
15 #include "src/__support/FPUtil/FloatProperties.h"
16 #include "src/__support/FPUtil/rounding_mode.h"
17 #include "src/__support/UInt.h"
18 #include "src/__support/UInt128.h"
19 #include "src/__support/common.h"
20 #include "src/__support/float_to_string.h"
21 #include "src/__support/integer_to_string.h"
22 #include "src/__support/libc_assert.h"
23 #include "src/stdio/printf_core/converter_utils.h"
24 #include "src/stdio/printf_core/core_structs.h"
25 #include "src/stdio/printf_core/float_inf_nan_converter.h"
26 #include "src/stdio/printf_core/writer.h"
31 namespace __llvm_libc
{
32 namespace printf_core
{
34 using MantissaInt
= fputil::FPBits
<long double>::UIntType
;
35 using DecimalString
= IntegerToString
<intmax_t>;
36 using ExponentString
=
37 IntegerToString
<intmax_t, radix::Dec::WithWidth
<2>::WithSign
>;
39 // Returns true if value is divisible by 2^p.
41 LIBC_INLINE
constexpr cpp::enable_if_t
<cpp::is_integral_v
<T
>, bool>
42 multiple_of_power_of_2(T value
, uint32_t p
) {
43 return (value
& ((T(1) << p
) - 1)) == 0;
46 constexpr size_t BLOCK_SIZE
= 9;
47 constexpr uint32_t MAX_BLOCK
= 999999999;
49 // constexpr size_t BLOCK_SIZE = 18;
50 // constexpr uint32_t MAX_BLOCK = 999999999999999999;
51 constexpr char DECIMAL_POINT
= '.';
53 // This is used to represent which direction the number should be rounded.
54 enum class RoundDirection
{ Up
, Down
, Even
};
56 LIBC_INLINE RoundDirection
get_round_direction(int last_digit
, bool truncated
,
58 switch (fputil::quick_get_round()) {
60 // Round to nearest, if it's exactly halfway then round to even.
61 if (last_digit
!= 5) {
62 return last_digit
> 5 ? RoundDirection::Up
: RoundDirection::Down
;
64 return !truncated
? RoundDirection::Even
: RoundDirection::Up
;
67 if (is_negative
&& (truncated
|| last_digit
> 0)) {
68 return RoundDirection::Up
;
70 return RoundDirection::Down
;
73 if (!is_negative
&& (truncated
|| last_digit
> 0)) {
74 return RoundDirection::Up
;
76 return RoundDirection::Down
;
78 return is_negative
? RoundDirection::Down
: RoundDirection::Up
;
80 return RoundDirection::Down
;
82 return RoundDirection::Down
;
87 LIBC_INLINE
constexpr cpp::enable_if_t
<cpp::is_integral_v
<T
>, bool>
88 zero_after_digits(int32_t base_2_exp
, int32_t digits_after_point
, T mantissa
) {
89 const int32_t required_twos
= -base_2_exp
- digits_after_point
- 1;
90 const bool has_trailing_zeros
=
92 (required_twos
< 60 &&
93 multiple_of_power_of_2(mantissa
, static_cast<uint32_t>(required_twos
)));
94 return has_trailing_zeros
;
98 bool left_justified
= false;
99 bool leading_zeroes
= false;
101 size_t min_width
= 0;
105 PaddingWriter(const FormatSection
&to_conv
, char init_sign_char
)
106 : left_justified((to_conv
.flags
& FormatFlags::LEFT_JUSTIFIED
) > 0),
107 leading_zeroes((to_conv
.flags
& FormatFlags::LEADING_ZEROES
) > 0),
108 sign_char(init_sign_char
),
109 min_width(to_conv
.min_width
> 0 ? to_conv
.min_width
: 0) {}
111 int write_left_padding(Writer
*writer
, size_t total_digits
) {
112 // The pattern is (spaces) (sign) (zeroes), but only one of spaces and
113 // zeroes can be written, and only if the padding amount is positive.
115 static_cast<int>(min_width
- total_digits
- (sign_char
> 0 ? 1 : 0));
116 if (left_justified
|| padding_amount
< 0) {
118 RET_IF_RESULT_NEGATIVE(writer
->write(sign_char
));
122 if (!leading_zeroes
) {
123 RET_IF_RESULT_NEGATIVE(writer
->write(' ', padding_amount
));
126 RET_IF_RESULT_NEGATIVE(writer
->write(sign_char
));
128 if (leading_zeroes
) {
129 RET_IF_RESULT_NEGATIVE(writer
->write('0', padding_amount
));
134 int write_right_padding(Writer
*writer
, size_t total_digits
) {
135 // If and only if the conversion is left justified, there may be trailing
138 static_cast<int>(min_width
- total_digits
- (sign_char
> 0 ? 1 : 0));
139 if (left_justified
&& padding_amount
> 0) {
140 RET_IF_RESULT_NEGATIVE(writer
->write(' ', padding_amount
));
147 We only need to round a given segment if all of the segments below it are
148 the max (or this is the last segment). This means that we don't have to
149 write those initially, we can just keep the most recent non-maximal
150 segment and a counter of the number of maximal segments. When we reach a
151 non-maximal segment, we write the stored segment as well as as many 9s as
152 are necessary. Alternately, if we reach the end and have to round up, then
153 we round the stored segment, and write zeroes following it. If this
154 crosses the decimal point, then we have to shift it one space to the
156 This FloatWriter class does the buffering and counting, and writes to the
157 output when necessary.
160 char block_buffer
[BLOCK_SIZE
]; // The buffer that holds a block.
161 size_t buffered_digits
= 0; // The number of digits held in the buffer.
162 bool has_written
= false; // True once any digits have been output.
163 size_t max_block_count
= 0; // The # of blocks of all 9s currently buffered.
164 size_t total_digits
= 0; // The number of digits that will be output.
165 size_t digits_before_decimal
= 0; // The # of digits to write before the '.'
166 size_t total_digits_written
= 0; // The # of digits that have been output.
167 bool has_decimal_point
; // True if the number has a decimal point.
168 Writer
*writer
; // Writes to the final output.
169 PaddingWriter padding_writer
; // Handles prefixes/padding, uses total_digits.
171 int flush_buffer(bool round_up_max_blocks
= false) {
172 const char MAX_BLOCK_DIGIT
= (round_up_max_blocks
? '0' : '9');
174 // Write the most recent buffered block, and mark has_written
177 RET_IF_RESULT_NEGATIVE(
178 padding_writer
.write_left_padding(writer
, total_digits
));
181 // if the decimal point is the next character, or is in the range covered
182 // by the buffered block, write the appropriate digits and the decimal
184 if (total_digits_written
< digits_before_decimal
&&
185 total_digits_written
+ buffered_digits
>= digits_before_decimal
&&
187 size_t digits_to_write
= digits_before_decimal
- total_digits_written
;
188 if (digits_to_write
> 0) {
189 // Write the digits before the decimal point.
190 RET_IF_RESULT_NEGATIVE(writer
->write({block_buffer
, digits_to_write
}));
192 RET_IF_RESULT_NEGATIVE(writer
->write(DECIMAL_POINT
));
193 if (buffered_digits
- digits_to_write
> 0) {
194 // Write the digits after the decimal point.
195 RET_IF_RESULT_NEGATIVE(
196 writer
->write({block_buffer
+ digits_to_write
,
197 (buffered_digits
- digits_to_write
)}));
199 // add 1 for the decimal point
200 total_digits_written
+= buffered_digits
+ 1;
201 // Mark the buffer as empty.
205 // Clear the buffered digits.
206 if (buffered_digits
> 0) {
207 RET_IF_RESULT_NEGATIVE(writer
->write({block_buffer
, buffered_digits
}));
208 total_digits_written
+= buffered_digits
;
212 // if the decimal point is the next character, or is in the range covered
213 // by the max blocks, write the appropriate digits and the decimal point.
214 if (total_digits_written
< digits_before_decimal
&&
215 total_digits_written
+ BLOCK_SIZE
* max_block_count
>=
216 digits_before_decimal
&&
218 size_t digits_to_write
= digits_before_decimal
- total_digits_written
;
219 if (digits_to_write
> 0) {
220 RET_IF_RESULT_NEGATIVE(writer
->write(MAX_BLOCK_DIGIT
, digits_to_write
));
222 RET_IF_RESULT_NEGATIVE(writer
->write(DECIMAL_POINT
));
223 if ((BLOCK_SIZE
* max_block_count
) - digits_to_write
> 0) {
224 RET_IF_RESULT_NEGATIVE(writer
->write(
225 MAX_BLOCK_DIGIT
, (BLOCK_SIZE
* max_block_count
) - digits_to_write
));
227 // add 1 for the decimal point
228 total_digits_written
+= BLOCK_SIZE
* max_block_count
+ 1;
229 // clear the buffer of max blocks
233 // Clear the buffer of max blocks
234 if (max_block_count
> 0) {
235 RET_IF_RESULT_NEGATIVE(
236 writer
->write(MAX_BLOCK_DIGIT
, max_block_count
* BLOCK_SIZE
));
237 total_digits_written
+= max_block_count
* BLOCK_SIZE
;
243 // -exponent will never overflow because all long double types we support
244 // have at most 15 bits of mantissa and the C standard defines an int as
245 // being at least 16 bits.
246 static_assert(fputil::FloatProperties
<long double>::EXPONENT_WIDTH
<
250 FloatWriter(Writer
*init_writer
, bool init_has_decimal_point
,
251 const PaddingWriter
&init_padding_writer
)
252 : has_decimal_point(init_has_decimal_point
), writer(init_writer
),
253 padding_writer(init_padding_writer
) {}
255 void init(size_t init_total_digits
, size_t init_digits_before_decimal
) {
256 total_digits
= init_total_digits
;
257 digits_before_decimal
= init_digits_before_decimal
;
260 void write_first_block(BlockInt block
, bool exp_format
= false) {
261 const DecimalString
buf(block
);
262 const cpp::string_view int_to_str
= buf
.view();
263 size_t digits_buffered
= int_to_str
.size();
264 // Block Buffer is guaranteed to not overflow since block cannot have more
265 // than BLOCK_SIZE digits.
266 // TODO: Replace with memcpy
267 for (size_t count
= 0; count
< digits_buffered
; ++count
) {
268 block_buffer
[count
] = int_to_str
[count
];
270 buffered_digits
= digits_buffered
;
272 // In the exponent format (%e) we know how many digits will be written even
273 // before calculating any blocks, whereas the decimal format (%f) has to
274 // write all of the blocks that would come before the decimal place.
276 total_digits
+= digits_buffered
;
277 digits_before_decimal
+= digits_buffered
;
281 int write_middle_block(BlockInt block
) {
282 if (block
== MAX_BLOCK
) { // Buffer max blocks in case of rounding
284 } else { // If a non-max block has been found
285 RET_IF_RESULT_NEGATIVE(flush_buffer());
287 // Now buffer the current block. We add 1 + MAX_BLOCK to force the
288 // leading zeroes, and drop the leading one. This is probably inefficient,
289 // but it works. See https://xkcd.com/2021/
290 const DecimalString
buf(block
+ (MAX_BLOCK
+ 1));
291 const cpp::string_view int_to_str
= buf
.view();
292 // TODO: Replace with memcpy
293 for (size_t count
= 0; count
< BLOCK_SIZE
; ++count
) {
294 block_buffer
[count
] = int_to_str
[count
+ 1];
297 buffered_digits
= BLOCK_SIZE
;
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');
307 char end_buff
[BLOCK_SIZE
];
310 const DecimalString
buf(block
+ (MAX_BLOCK
+ 1));
311 const cpp::string_view int_to_str
= buf
.view();
313 // copy the last block_digits characters into the start of end_buff.
314 // TODO: Replace with memcpy
315 for (size_t count
= 0; count
< block_digits
; ++count
) {
316 end_buff
[count
] = int_to_str
[count
+ 1 + (BLOCK_SIZE
- block_digits
)];
320 char low_digit
= '0';
321 if (block_digits
> 0) {
322 low_digit
= end_buff
[block_digits
- 1];
323 } else if (max_block_count
> 0) {
325 } else if (buffered_digits
> 0) {
326 low_digit
= block_buffer
[buffered_digits
- 1];
329 bool round_up_max_blocks
= false;
332 if (round
== RoundDirection::Up
||
333 (round
== RoundDirection::Even
&& low_digit
% 2 != 0)) {
334 bool has_carry
= true;
335 round_up_max_blocks
= true; // if we're rounding up, we might need to
336 // round up the max blocks that are buffered.
338 // handle the low block that we're adding
339 for (int count
= static_cast<int>(block_digits
) - 1;
340 count
>= 0 && has_carry
; --count
) {
341 if (end_buff
[count
] == '9') {
342 end_buff
[count
] = '0';
344 end_buff
[count
] += 1;
346 round_up_max_blocks
= false; // If the low block isn't all nines, then
347 // the max blocks aren't rounded up.
350 // handle the high block that's buffered
351 for (int count
= static_cast<int>(buffered_digits
) - 1;
352 count
>= 0 && has_carry
; --count
) {
353 if (block_buffer
[count
] == '9') {
354 block_buffer
[count
] = '0';
356 block_buffer
[count
] += 1;
361 // has_carry should only be true here if every previous digit is 9, which
362 // implies that the number has never been written.
363 if (has_carry
/* && !has_written */) {
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.
369 const ExponentString
buf(exponent
);
370 const cpp::string_view int_to_str
= buf
.view();
372 // TODO: also change this to calculate the width of the number more
374 size_t exponent_width
= int_to_str
.size();
375 size_t number_digits
=
376 buffered_digits
+ (max_block_count
* BLOCK_SIZE
) + block_digits
;
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.
382 (has_decimal_point
? 1 : 0) + number_digits
+ 1 + exponent_width
;
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.
398 if (number_digits
> 1) {
399 RET_IF_RESULT_NEGATIVE(writer
->write('0', number_digits
- 1));
402 RET_IF_RESULT_NEGATIVE(writer
->write(exp_char
));
403 RET_IF_RESULT_NEGATIVE(writer
->write(int_to_str
));
405 total_digits_written
= total_digits
;
407 } else { // This is in %f style
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
424 if (total_digits
> digits_before_decimal
+ 1) {
425 RET_IF_RESULT_NEGATIVE(writer
->write(
426 '0', total_digits
- (digits_before_decimal
+ 1)));
429 total_digits_written
= total_digits
;
434 // Either we intend to round down, or the rounding up is complete. Flush the
437 RET_IF_RESULT_NEGATIVE(flush_buffer(round_up_max_blocks
));
439 // And then write the final block. It's written via the buffer so that if
440 // this is also the first block, the decimal point will be placed correctly.
442 // TODO: Replace with memcpy
443 for (size_t count
= 0; count
< block_digits
; ++count
) {
444 block_buffer
[count
] = end_buff
[count
];
446 buffered_digits
= block_digits
;
447 RET_IF_RESULT_NEGATIVE(flush_buffer());
450 RET_IF_RESULT_NEGATIVE(writer
->write(exp_char
));
451 const ExponentString
buf(exponent
);
452 RET_IF_RESULT_NEGATIVE(writer
->write(buf
.view()));
454 total_digits_written
= total_digits
;
459 int write_zeroes(uint32_t num_zeroes
) {
460 RET_IF_RESULT_NEGATIVE(flush_buffer());
461 RET_IF_RESULT_NEGATIVE(writer
->write('0', num_zeroes
));
466 return padding_writer
.write_right_padding(writer
, total_digits
);
470 // This implementation is based on the Ryu Printf algorithm by Ulf Adams:
471 // Ulf Adams. 2019. Ryū revisited: printf floating point conversion.
472 // Proc. ACM Program. Lang. 3, OOPSLA, Article 169 (October 2019), 23 pages.
473 // https://doi.org/10.1145/3360595
474 template <typename T
, cpp::enable_if_t
<cpp::is_floating_point_v
<T
>, int> = 0>
475 LIBC_INLINE
int convert_float_decimal_typed(Writer
*writer
,
476 const FormatSection
&to_conv
,
477 fputil::FPBits
<T
> float_bits
) {
478 // signed because later we use -MANT_WIDTH
479 constexpr int32_t MANT_WIDTH
= fputil::MantissaWidth
<T
>::VALUE
;
480 bool is_negative
= float_bits
.get_sign();
481 int exponent
= float_bits
.get_explicit_exponent();
487 else if ((to_conv
.flags
& FormatFlags::FORCE_SIGN
) == FormatFlags::FORCE_SIGN
)
488 sign_char
= '+'; // FORCE_SIGN has precedence over SPACE_PREFIX
489 else if ((to_conv
.flags
& FormatFlags::SPACE_PREFIX
) ==
490 FormatFlags::SPACE_PREFIX
)
493 // If to_conv doesn't specify a precision, the precision defaults to 6.
494 const unsigned int precision
= to_conv
.precision
< 0 ? 6 : to_conv
.precision
;
495 bool has_decimal_point
=
496 (precision
> 0) || ((to_conv
.flags
& FormatFlags::ALTERNATE_FORM
) != 0);
498 // nonzero is false until a nonzero digit is found. It is used to determine if
499 // leading zeroes should be printed, since before the first digit they are
501 bool nonzero
= false;
503 PaddingWriter
padding_writer(to_conv
, sign_char
);
504 FloatWriter
float_writer(writer
, has_decimal_point
, padding_writer
);
505 FloatToString
<T
> float_converter(static_cast<T
>(float_bits
));
507 const size_t positive_blocks
= float_converter
.get_positive_blocks();
509 if (positive_blocks
>= 0) {
510 // This loop iterates through the number a block at a time until it finds a
511 // block that is not zero or it hits the decimal point. This is because all
512 // zero blocks before the first nonzero digit or the decimal point are
513 // ignored (no leading zeroes, at least at this stage).
514 int32_t i
= static_cast<int32_t>(positive_blocks
) - 1;
515 for (; i
>= 0; --i
) {
516 BlockInt digits
= float_converter
.get_positive_block(i
);
518 RET_IF_RESULT_NEGATIVE(float_writer
.write_middle_block(digits
));
519 } else if (digits
!= 0) {
520 size_t blocks_before_decimal
= i
;
521 float_writer
.init((blocks_before_decimal
* BLOCK_SIZE
) +
522 (has_decimal_point
? 1 : 0) + precision
,
523 blocks_before_decimal
* BLOCK_SIZE
);
524 float_writer
.write_first_block(digits
);
531 // if we haven't yet found a valid digit, buffer a zero.
533 float_writer
.init((has_decimal_point
? 1 : 0) + precision
, 0);
534 float_writer
.write_first_block(0);
537 if (exponent
< MANT_WIDTH
) {
538 const uint32_t blocks
= (precision
/ BLOCK_SIZE
) + 1;
540 // if all the blocks we should write are zero
541 if (blocks
<= float_converter
.zero_blocks_after_point()) {
542 i
= blocks
; // just write zeroes up to precision
543 RET_IF_RESULT_NEGATIVE(float_writer
.write_zeroes(precision
));
544 } else if (i
< float_converter
.zero_blocks_after_point()) {
545 // else if there are some blocks that are zeroes
546 i
= static_cast<uint32_t>(float_converter
.zero_blocks_after_point());
547 // write those blocks as zeroes.
548 RET_IF_RESULT_NEGATIVE(float_writer
.write_zeroes(9 * i
));
550 // for each unwritten block
551 for (; i
< blocks
; ++i
) {
552 if (float_converter
.is_lowest_block(i
)) {
553 const uint32_t fill
= precision
- 9 * i
;
554 RET_IF_RESULT_NEGATIVE(float_writer
.write_zeroes(fill
));
557 BlockInt digits
= float_converter
.get_negative_block(i
);
558 if (i
< blocks
- 1) {
559 RET_IF_RESULT_NEGATIVE(float_writer
.write_middle_block(digits
));
562 const uint32_t maximum
= precision
- BLOCK_SIZE
* i
;
563 uint32_t last_digit
= 0;
564 for (uint32_t k
= 0; k
< BLOCK_SIZE
- maximum
; ++k
) {
565 last_digit
= digits
% 10;
568 RoundDirection round
;
569 const bool truncated
=
570 !zero_after_digits(exponent
- MANT_WIDTH
, precision
,
571 float_bits
.get_explicit_mantissa());
572 round
= get_round_direction(last_digit
, truncated
, is_negative
);
574 RET_IF_RESULT_NEGATIVE(
575 float_writer
.write_last_block(digits
, maximum
, round
));
580 RET_IF_RESULT_NEGATIVE(float_writer
.write_zeroes(precision
));
582 RET_IF_RESULT_NEGATIVE(float_writer
.right_pad());
586 template <typename T
, cpp::enable_if_t
<cpp::is_floating_point_v
<T
>, int> = 0>
587 LIBC_INLINE
int convert_float_dec_exp_typed(Writer
*writer
,
588 const FormatSection
&to_conv
,
589 fputil::FPBits
<T
> float_bits
) {
590 // signed because later we use -MANT_WIDTH
591 constexpr int32_t MANT_WIDTH
= fputil::MantissaWidth
<T
>::VALUE
;
592 bool is_negative
= float_bits
.get_sign();
593 int exponent
= float_bits
.get_explicit_exponent();
594 MantissaInt mantissa
= float_bits
.get_explicit_mantissa();
596 const char a
= (to_conv
.conv_name
& 32) | 'A';
602 else if ((to_conv
.flags
& FormatFlags::FORCE_SIGN
) == FormatFlags::FORCE_SIGN
)
603 sign_char
= '+'; // FORCE_SIGN has precedence over SPACE_PREFIX
604 else if ((to_conv
.flags
& FormatFlags::SPACE_PREFIX
) ==
605 FormatFlags::SPACE_PREFIX
)
608 // If to_conv doesn't specify a precision, the precision defaults to 6.
609 const unsigned int precision
= to_conv
.precision
< 0 ? 6 : to_conv
.precision
;
610 bool has_decimal_point
=
611 (precision
> 0) || ((to_conv
.flags
& FormatFlags::ALTERNATE_FORM
) != 0);
613 PaddingWriter
padding_writer(to_conv
, sign_char
);
614 FloatWriter
float_writer(writer
, has_decimal_point
, padding_writer
);
615 FloatToString
<T
> float_converter(static_cast<T
>(float_bits
));
617 size_t digits_written
= 0;
618 int final_exponent
= 0;
620 // Here we would subtract 1 to account for the fact that block 0 counts as a
621 // positive block, but the loop below accounts for this by starting with
622 // subtracting 1 from cur_block.
626 cur_block
= -static_cast<int>(float_converter
.zero_blocks_after_point());
628 cur_block
= static_cast<int>(float_converter
.get_positive_blocks());
633 // If the mantissa is 0, then the number is 0, meaning that looping until a
634 // non-zero block is found will loop forever. The first block is just 0.
636 // This loop finds the first block.
637 while (digits
== 0) {
639 digits
= float_converter
.get_block(cur_block
);
645 const size_t block_width
= IntegerToString
<intmax_t>(digits
).size();
647 final_exponent
= (cur_block
* BLOCK_SIZE
) + static_cast<int>(block_width
- 1);
648 int positive_exponent
= final_exponent
< 0 ? -final_exponent
: final_exponent
;
650 size_t exponent_width
= IntegerToString
<intmax_t>(positive_exponent
).size();
652 // Calculate the total number of digits in the number.
653 // 1 - the digit before the decimal point
654 // 1 - the decimal point (optional)
655 // precision - the number of digits after the decimal point
656 // 1 - the 'e' at the start of the exponent
657 // 1 - the sign at the start of the exponent
658 // max(2, exp width) - the digits of the exponent, min 2.
660 float_writer
.init(1 + (has_decimal_point
? 1 : 0) + precision
+ 2 +
661 (exponent_width
< 2 ? 2 : exponent_width
),
664 // If this block is not the last block
665 if (block_width
<= precision
+ 1) {
666 float_writer
.write_first_block(digits
, true);
667 digits_written
+= block_width
;
671 // For each middle block.
672 for (; digits_written
+ BLOCK_SIZE
< precision
+ 1; --cur_block
) {
673 digits
= float_converter
.get_block(cur_block
);
675 RET_IF_RESULT_NEGATIVE(float_writer
.write_middle_block(digits
));
676 digits_written
+= BLOCK_SIZE
;
679 digits
= float_converter
.get_block(cur_block
);
681 size_t last_block_size
= BLOCK_SIZE
;
683 // if the last block is also the first block, then ignore leading zeroes.
684 if (digits_written
== 0) {
685 last_block_size
= IntegerToString
<intmax_t>(digits
).size();
688 // This tracks if the number is truncated, that meaning that the digits after
689 // last_digit are non-zero.
690 bool truncated
= false;
692 // This is the last block.
693 const size_t maximum
= precision
+ 1 - digits_written
;
694 uint32_t last_digit
= 0;
695 for (uint32_t k
= 0; k
< last_block_size
- maximum
; ++k
) {
699 last_digit
= digits
% 10;
703 // If the last block we read doesn't have the digit after the end of what
704 // we'll print, then we need to read the next block to get that digit.
705 if (maximum
== last_block_size
) {
707 BlockInt extra_block
= float_converter
.get_block(cur_block
);
708 last_digit
= extra_block
/ ((MAX_BLOCK
/ 10) + 1);
709 if (extra_block
% ((MAX_BLOCK
/ 10) + 1) > 0) {
714 RoundDirection round
;
716 // If we've already seen a truncated digit, then we don't need to check any
719 // Check the blocks above the decimal point
720 if (cur_block
>= 0) {
721 // Check every block until the decimal point for non-zero digits.
722 for (int cur_extra_block
= cur_block
- 1; cur_extra_block
>= 0;
724 BlockInt extra_block
= float_converter
.get_block(cur_extra_block
);
725 if (extra_block
> 0) {
731 // If it's still not truncated and there are digits below the decimal point
732 if (!truncated
&& exponent
- MANT_WIDTH
< 0) {
733 // Use the formula from %f.
735 !zero_after_digits(exponent
- MANT_WIDTH
, precision
- final_exponent
,
736 float_bits
.get_explicit_mantissa());
739 round
= get_round_direction(last_digit
, truncated
, is_negative
);
741 RET_IF_RESULT_NEGATIVE(float_writer
.write_last_block(
742 digits
, maximum
, round
, final_exponent
, a
+ 'E' - 'A'));
744 RET_IF_RESULT_NEGATIVE(float_writer
.right_pad());
748 template <typename T
, cpp::enable_if_t
<cpp::is_floating_point_v
<T
>, int> = 0>
749 LIBC_INLINE
int convert_float_dec_auto_typed(Writer
*writer
,
750 const FormatSection
&to_conv
,
751 fputil::FPBits
<T
> float_bits
) {
752 // signed because later we use -MANT_WIDTH
753 constexpr int32_t MANT_WIDTH
= fputil::MantissaWidth
<T
>::VALUE
;
754 bool is_negative
= float_bits
.get_sign();
755 int exponent
= float_bits
.get_explicit_exponent();
756 MantissaInt mantissa
= float_bits
.get_explicit_mantissa();
758 // From the standard: Let P (init_precision) equal the precision if nonzero, 6
759 // if the precision is omitted, or 1 if the precision is zero.
760 const unsigned int init_precision
= to_conv
.precision
<= 0
761 ? (to_conv
.precision
== 0 ? 1 : 6)
764 // Then, if a conversion with style E would have an exponent of X
767 // If P > X >= -4 the conversion is with style F and precision P - (X + 1).
768 // Otherwise, the conversion is with style E and precision P - 1.
770 // For calculating the base 10 exponent, we need to process the number as if
771 // it has style E, so here we calculate the precision we'll use in that case.
772 const unsigned int exp_precision
= init_precision
- 1;
774 FloatToString
<T
> float_converter(static_cast<T
>(float_bits
));
776 // Here we would subtract 1 to account for the fact that block 0 counts as a
777 // positive block, but the loop below accounts for this by starting with
778 // subtracting 1 from cur_block.
782 cur_block
= -static_cast<int>(float_converter
.zero_blocks_after_point());
784 cur_block
= static_cast<int>(float_converter
.get_positive_blocks());
789 // If the mantissa is 0, then the number is 0, meaning that looping until a
790 // non-zero block is found will loop forever.
792 // This loop finds the first non-zero block.
793 while (digits
== 0) {
795 digits
= float_converter
.get_block(cur_block
);
798 // In the case of 0.0, then it's always decimal format. If we don't have alt
799 // form then the trailing zeroes are trimmed to make "0", else the precision
800 // is 1 less than specified by the user.
801 FormatSection new_conv
= to_conv
;
802 if ((to_conv
.flags
& FormatFlags::ALTERNATE_FORM
) != 0) {
803 // This is a style F conversion, making the precision P - 1 - X, but since
804 // this is for the number 0, X (the base 10 exponent) is always 0.
805 new_conv
.precision
= init_precision
- 1;
807 new_conv
.precision
= 0;
809 return convert_float_decimal_typed
<T
>(writer
, new_conv
, float_bits
);
812 const size_t block_width
= IntegerToString
<intmax_t>(digits
).size();
814 size_t digits_checked
= 0;
815 // TODO: look into unifying trailing_zeroes and trailing_nines. The number can
816 // end in a nine or a zero, but not both.
817 size_t trailing_zeroes
= 0;
818 size_t trailing_nines
= 0;
820 base_10_exp
= (cur_block
* BLOCK_SIZE
) + static_cast<int>(block_width
- 1);
822 // If the first block is not also the last block
823 if (block_width
<= exp_precision
+ 1) {
824 const DecimalString
buf(digits
);
825 const cpp::string_view int_to_str
= buf
.view();
827 for (size_t i
= 0; i
< block_width
; ++i
) {
828 if (int_to_str
[i
] == '9') {
831 } else if (int_to_str
[i
] == '0') {
839 digits_checked
+= block_width
;
843 // Handle middle blocks
844 for (; digits_checked
+ BLOCK_SIZE
< exp_precision
+ 1; --cur_block
) {
845 digits
= float_converter
.get_block(cur_block
);
846 digits_checked
+= BLOCK_SIZE
;
847 if (digits
== MAX_BLOCK
) {
850 } else if (digits
== 0) {
851 trailing_zeroes
+= 9;
854 // The block is neither all nines nor all zeroes, so we need to figure out
855 // what it ends with.
858 BlockInt copy_of_digits
= digits
;
859 int cur_last_digit
= copy_of_digits
% 10;
860 // We only care if it ends in nines or zeroes.
861 while (copy_of_digits
> 0 &&
862 (cur_last_digit
== 9 || cur_last_digit
== 0)) {
863 // If the next digit is not the same as the previous one, then there are
864 // no more contiguous trailing digits.
865 if ((copy_of_digits
% 10) != cur_last_digit
) {
868 if (cur_last_digit
== 9) {
870 } else if (cur_last_digit
== 0) {
875 copy_of_digits
/= 10;
880 // Handle the last block
882 digits
= float_converter
.get_block(cur_block
);
884 size_t last_block_size
= BLOCK_SIZE
;
886 const DecimalString
buf(digits
);
887 const cpp::string_view int_to_str
= buf
.view();
889 size_t implicit_leading_zeroes
= BLOCK_SIZE
- int_to_str
.size();
891 // if the last block is also the first block, then ignore leading zeroes.
892 if (digits_checked
== 0) {
893 last_block_size
= int_to_str
.size();
894 implicit_leading_zeroes
= 0;
897 unsigned int digits_requested
=
898 (exp_precision
+ 1) - static_cast<unsigned int>(digits_checked
);
900 int digits_to_check
=
901 digits_requested
- static_cast<int>(implicit_leading_zeroes
);
902 if (digits_to_check
< 0) {
906 // If the block is not the maximum size, that means it has leading
907 // zeroes, and zeroes are not nines.
908 if (implicit_leading_zeroes
> 0) {
912 // But leading zeroes are zeroes (that could be trailing). We take the
913 // minimum of the leading zeroes and digits requested because if there are
914 // more requested digits than leading zeroes we shouldn't count those.
916 (implicit_leading_zeroes
> digits_requested
? digits_requested
917 : implicit_leading_zeroes
);
919 // Check the upper digits of this block.
920 for (int i
= 0; i
< digits_to_check
; ++i
) {
921 if (int_to_str
[i
] == '9') {
924 } else if (int_to_str
[i
] == '0') {
933 bool truncated
= false;
935 // Find the digit after the lowest digit that we'll actually print to
936 // determine the rounding.
937 const uint32_t maximum
=
938 exp_precision
+ 1 - static_cast<uint32_t>(digits_checked
);
939 uint32_t last_digit
= 0;
940 for (uint32_t k
= 0; k
< last_block_size
- maximum
; ++k
) {
944 last_digit
= digits
% 10;
948 // If the last block we read doesn't have the digit after the end of what
949 // we'll print, then we need to read the next block to get that digit.
950 if (maximum
== last_block_size
) {
952 BlockInt extra_block
= float_converter
.get_block(cur_block
);
953 last_digit
= extra_block
/ ((MAX_BLOCK
/ 10) + 1);
955 if (extra_block
% ((MAX_BLOCK
/ 10) + 1) > 0)
959 // TODO: unify this code across the three float conversions.
960 RoundDirection round
;
962 // If we've already seen a truncated digit, then we don't need to check any
965 // Check the blocks above the decimal point
966 if (cur_block
>= 0) {
967 // Check every block until the decimal point for non-zero digits.
968 for (int cur_extra_block
= cur_block
- 1; cur_extra_block
>= 0;
970 BlockInt extra_block
= float_converter
.get_block(cur_extra_block
);
971 if (extra_block
> 0) {
977 // If it's still not truncated and there are digits below the decimal point
978 if (!truncated
&& exponent
- MANT_WIDTH
< 0) {
979 // Use the formula from %f.
981 !zero_after_digits(exponent
- MANT_WIDTH
, exp_precision
- base_10_exp
,
982 float_bits
.get_explicit_mantissa());
986 round
= get_round_direction(last_digit
, truncated
, is_negative
);
989 if (round
== RoundDirection::Up
) {
991 } else if (round
== RoundDirection::Down
) {
994 // RoundDirection is even, so check the lowest digit that will be printed.
997 // maximum is the number of digits that will remain in digits after getting
998 // last_digit. If it's greater than zero, we can just check the lowest digit
1001 low_digit
= digits
% 10;
1003 // Else if there are trailing nines, then the low digit is a nine, same
1005 if (trailing_nines
> 0) {
1007 } else if (trailing_zeroes
> 0) {
1010 // If there are no trailing zeroes or nines, then the round direction
1011 // doesn't actually matter here. Since this conversion passes off the
1012 // value to another one for final conversion, rounding only matters to
1013 // determine if the exponent is higher than expected (with an all nine
1014 // number) or to determine the trailing zeroes to trim. In this case
1015 // low_digit is set to 0, but it could be set to any number.
1020 round_up
= (low_digit
% 2) != 0;
1023 digits_checked
+= digits_requested
;
1024 LIBC_ASSERT(digits_checked
== init_precision
);
1025 // At this point we should have checked all the digits requested by the
1026 // precision. We may increment this number 1 more if we round up all of the
1027 // digits, but at this point in the code digits_checked should always equal
1031 // If all the digits that would be printed are nines, then rounding up means
1032 // that the base 10 exponent is one higher and all those nines turn to
1033 // zeroes (e.g. 999 -> 1000).
1034 if (trailing_nines
== init_precision
) {
1036 trailing_zeroes
= digits_checked
;
1039 // If there are trailing nines, they turn into trailing zeroes when
1040 // they're rounded up.
1041 if (trailing_nines
> 0) {
1042 trailing_zeroes
+= trailing_nines
;
1043 } else if (trailing_zeroes
> 0) {
1044 // If there are trailing zeroes, then the last digit will be rounded up
1045 // to a 1 so they aren't trailing anymore.
1046 trailing_zeroes
= 0;
1051 // if P > X >= -4, the conversion is with style f (or F) and precision equals
1053 if (static_cast<int>(init_precision
) > base_10_exp
&& base_10_exp
>= -4) {
1054 FormatSection new_conv
= to_conv
;
1055 const int conv_precision
= init_precision
- (base_10_exp
+ 1);
1057 if ((to_conv
.flags
& FormatFlags::ALTERNATE_FORM
) != 0) {
1058 new_conv
.precision
= conv_precision
;
1060 // If alt form isn't set, then we need to determine the number of trailing
1061 // zeroes and set the precision such that they are removed.
1064 Here's a diagram of an example:
1066 printf("%.15g", 22.25);
1068 +--- init_precision = 15
1070 +-------------------+
1072 | ++--- trimmed_precision = 2
1074 22.250000000000000000
1078 base_10_exp + 1 = 2 --+ +--- trailing_zeroes = 11
1080 int trimmed_precision
= static_cast<int>(
1081 digits_checked
- (base_10_exp
+ 1) - trailing_zeroes
);
1082 if (trimmed_precision
< 0) {
1083 trimmed_precision
= 0;
1085 new_conv
.precision
= (trimmed_precision
> conv_precision
)
1087 : trimmed_precision
;
1090 return convert_float_decimal_typed
<T
>(writer
, new_conv
, float_bits
);
1092 // otherwise, the conversion is with style e (or E) and precision equals
1094 const int conv_precision
= init_precision
- 1;
1095 FormatSection new_conv
= to_conv
;
1096 if ((to_conv
.flags
& FormatFlags::ALTERNATE_FORM
) != 0) {
1097 new_conv
.precision
= conv_precision
;
1099 // If alt form isn't set, then we need to determine the number of trailing
1100 // zeroes and set the precision such that they are removed.
1101 int trimmed_precision
=
1102 static_cast<int>(digits_checked
- 1 - trailing_zeroes
);
1103 if (trimmed_precision
< 0) {
1104 trimmed_precision
= 0;
1106 new_conv
.precision
= (trimmed_precision
> conv_precision
)
1108 : trimmed_precision
;
1110 return convert_float_dec_exp_typed
<T
>(writer
, new_conv
, float_bits
);
1114 // TODO: unify the float converters to remove the duplicated checks for inf/nan.
1115 LIBC_INLINE
int convert_float_decimal(Writer
*writer
,
1116 const FormatSection
&to_conv
) {
1117 if (to_conv
.length_modifier
== LengthModifier::L
) {
1118 fputil::FPBits
<long double>::UIntType float_raw
= to_conv
.conv_val_raw
;
1119 fputil::FPBits
<long double> float_bits(float_raw
);
1120 if (!float_bits
.is_inf_or_nan()) {
1121 return convert_float_decimal_typed
<long double>(writer
, to_conv
,
1125 fputil::FPBits
<double>::UIntType float_raw
=
1126 static_cast<fputil::FPBits
<double>::UIntType
>(to_conv
.conv_val_raw
);
1127 fputil::FPBits
<double> float_bits(float_raw
);
1128 if (!float_bits
.is_inf_or_nan()) {
1129 return convert_float_decimal_typed
<double>(writer
, to_conv
, float_bits
);
1133 return convert_inf_nan(writer
, to_conv
);
1136 LIBC_INLINE
int convert_float_dec_exp(Writer
*writer
,
1137 const FormatSection
&to_conv
) {
1138 if (to_conv
.length_modifier
== LengthModifier::L
) {
1139 fputil::FPBits
<long double>::UIntType float_raw
= to_conv
.conv_val_raw
;
1140 fputil::FPBits
<long double> float_bits(float_raw
);
1141 if (!float_bits
.is_inf_or_nan()) {
1142 return convert_float_dec_exp_typed
<long double>(writer
, to_conv
,
1146 fputil::FPBits
<double>::UIntType float_raw
=
1147 static_cast<fputil::FPBits
<double>::UIntType
>(to_conv
.conv_val_raw
);
1148 fputil::FPBits
<double> float_bits(float_raw
);
1149 if (!float_bits
.is_inf_or_nan()) {
1150 return convert_float_dec_exp_typed
<double>(writer
, to_conv
, float_bits
);
1154 return convert_inf_nan(writer
, to_conv
);
1157 LIBC_INLINE
int convert_float_dec_auto(Writer
*writer
,
1158 const FormatSection
&to_conv
) {
1159 if (to_conv
.length_modifier
== LengthModifier::L
) {
1160 fputil::FPBits
<long double>::UIntType float_raw
= to_conv
.conv_val_raw
;
1161 fputil::FPBits
<long double> float_bits(float_raw
);
1162 if (!float_bits
.is_inf_or_nan()) {
1163 return convert_float_dec_auto_typed
<long double>(writer
, to_conv
,
1167 fputil::FPBits
<double>::UIntType float_raw
=
1168 static_cast<fputil::FPBits
<double>::UIntType
>(to_conv
.conv_val_raw
);
1169 fputil::FPBits
<double> float_bits(float_raw
);
1170 if (!float_bits
.is_inf_or_nan()) {
1171 return convert_float_dec_auto_typed
<double>(writer
, to_conv
, float_bits
);
1175 return convert_inf_nan(writer
, to_conv
);
1178 } // namespace printf_core
1179 } // namespace __llvm_libc
1181 #endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_H