xref: /aosp_15_r20/external/llvm-libc/src/stdio/printf_core/float_dec_converter.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Decimal Float Converter for printf ----------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_H
10 #define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_H
11 
12 #include "src/__support/CPP/string_view.h"
13 #include "src/__support/FPUtil/FPBits.h"
14 #include "src/__support/FPUtil/rounding_mode.h"
15 #include "src/__support/big_int.h" // is_big_int_v
16 #include "src/__support/float_to_string.h"
17 #include "src/__support/integer_to_string.h"
18 #include "src/__support/libc_assert.h"
19 #include "src/__support/macros/config.h"
20 #include "src/stdio/printf_core/converter_utils.h"
21 #include "src/stdio/printf_core/core_structs.h"
22 #include "src/stdio/printf_core/float_inf_nan_converter.h"
23 #include "src/stdio/printf_core/writer.h"
24 
25 #include <inttypes.h>
26 #include <stddef.h>
27 
28 namespace LIBC_NAMESPACE_DECL {
29 namespace printf_core {
30 
31 using StorageType = fputil::FPBits<long double>::StorageType;
32 using DecimalString = IntegerToString<intmax_t>;
33 using ExponentString =
34     IntegerToString<intmax_t, radix::Dec::WithWidth<2>::WithSign>;
35 
36 // Returns true if value is divisible by 2^p.
37 template <typename T>
38 LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_integral_v<T> || is_big_int_v<T>,
39                                        bool>
multiple_of_power_of_2(T value,uint32_t p)40 multiple_of_power_of_2(T value, uint32_t p) {
41   return (value & ((T(1) << p) - 1)) == 0;
42 }
43 
44 constexpr size_t BLOCK_SIZE = 9;
45 constexpr uint32_t MAX_BLOCK = 999999999;
46 
47 // constexpr size_t BLOCK_SIZE = 18;
48 // constexpr uint32_t MAX_BLOCK = 999999999999999999;
49 constexpr char DECIMAL_POINT = '.';
50 
get_round_direction(int last_digit,bool truncated,Sign sign)51 LIBC_INLINE RoundDirection get_round_direction(int last_digit, bool truncated,
52                                                Sign sign) {
53   switch (fputil::quick_get_round()) {
54   case FE_TONEAREST:
55     // Round to nearest, if it's exactly halfway then round to even.
56     if (last_digit != 5) {
57       return last_digit > 5 ? RoundDirection::Up : RoundDirection::Down;
58     } else {
59       return !truncated ? RoundDirection::Even : RoundDirection::Up;
60     }
61   case FE_DOWNWARD:
62     if (sign.is_neg() && (truncated || last_digit > 0)) {
63       return RoundDirection::Up;
64     } else {
65       return RoundDirection::Down;
66     }
67   case FE_UPWARD:
68     if (sign.is_pos() && (truncated || last_digit > 0)) {
69       return RoundDirection::Up;
70     } else {
71       return RoundDirection::Down;
72     }
73     return sign.is_neg() ? RoundDirection::Down : RoundDirection::Up;
74   case FE_TOWARDZERO:
75     return RoundDirection::Down;
76   default:
77     return RoundDirection::Down;
78   }
79 }
80 
81 template <typename T>
82 LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_integral_v<T> || is_big_int_v<T>,
83                                        bool>
zero_after_digits(int32_t base_2_exp,int32_t digits_after_point,T mantissa,const int32_t mant_width)84 zero_after_digits(int32_t base_2_exp, int32_t digits_after_point, T mantissa,
85                   const int32_t mant_width) {
86   const int32_t required_twos = -base_2_exp - digits_after_point - 1;
87   // Add 8 to mant width since this is a loose bound.
88   const bool has_trailing_zeros =
89       required_twos <= 0 ||
90       (required_twos < (mant_width + 8) &&
91        multiple_of_power_of_2(mantissa, static_cast<uint32_t>(required_twos)));
92   return has_trailing_zeros;
93 }
94 
95 class PaddingWriter {
96   bool left_justified = false;
97   bool leading_zeroes = false;
98   char sign_char = 0;
99   size_t min_width = 0;
100 
101 public:
PaddingWriter()102   LIBC_INLINE PaddingWriter() {}
PaddingWriter(const FormatSection & to_conv,char init_sign_char)103   LIBC_INLINE PaddingWriter(const FormatSection &to_conv, char init_sign_char)
104       : left_justified((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) > 0),
105         leading_zeroes((to_conv.flags & FormatFlags::LEADING_ZEROES) > 0),
106         sign_char(init_sign_char),
107         min_width(to_conv.min_width > 0 ? to_conv.min_width : 0) {}
108 
write_left_padding(Writer * writer,size_t total_digits)109   LIBC_INLINE int write_left_padding(Writer *writer, size_t total_digits) {
110     // The pattern is (spaces) (sign) (zeroes), but only one of spaces and
111     // zeroes can be written, and only if the padding amount is positive.
112     int padding_amount =
113         static_cast<int>(min_width - total_digits - (sign_char > 0 ? 1 : 0));
114     if (left_justified || padding_amount < 0) {
115       if (sign_char > 0) {
116         RET_IF_RESULT_NEGATIVE(writer->write(sign_char));
117       }
118       return 0;
119     }
120     if (!leading_zeroes) {
121       RET_IF_RESULT_NEGATIVE(writer->write(' ', padding_amount));
122     }
123     if (sign_char > 0) {
124       RET_IF_RESULT_NEGATIVE(writer->write(sign_char));
125     }
126     if (leading_zeroes) {
127       RET_IF_RESULT_NEGATIVE(writer->write('0', padding_amount));
128     }
129     return 0;
130   }
131 
write_right_padding(Writer * writer,size_t total_digits)132   LIBC_INLINE int write_right_padding(Writer *writer, size_t total_digits) {
133     // If and only if the conversion is left justified, there may be trailing
134     // spaces.
135     int padding_amount =
136         static_cast<int>(min_width - total_digits - (sign_char > 0 ? 1 : 0));
137     if (left_justified && padding_amount > 0) {
138       RET_IF_RESULT_NEGATIVE(writer->write(' ', padding_amount));
139     }
140     return 0;
141   }
142 };
143 
144 /*
145   We only need to round a given segment if all of the segments below it are
146   the max (or this is the last segment). This means that we don't have to
147   write those initially, we can just keep the most recent non-maximal
148   segment and a counter of the number of maximal segments. When we reach a
149   non-maximal segment, we write the stored segment as well as as many 9s as
150   are necessary. Alternately, if we reach the end and have to round up, then
151   we round the stored segment, and write zeroes following it. If this
152   crosses the decimal point, then we have to shift it one space to the
153   right.
154   This FloatWriter class does the buffering and counting, and writes to the
155   output when necessary.
156 */
157 class FloatWriter {
158   char block_buffer[BLOCK_SIZE]; // The buffer that holds a block.
159   size_t buffered_digits = 0;    // The number of digits held in the buffer.
160   bool has_written = false;      // True once any digits have been output.
161   size_t max_block_count = 0; // The # of blocks of all 9s currently buffered.
162   size_t total_digits = 0;    // The number of digits that will be output.
163   size_t digits_before_decimal = 0; // The # of digits to write before the '.'
164   size_t total_digits_written = 0;  // The # of digits that have been output.
165   bool has_decimal_point;           // True if the number has a decimal point.
166   Writer *writer;                   // Writes to the final output.
167   PaddingWriter padding_writer; // Handles prefixes/padding, uses total_digits.
168 
169   LIBC_INLINE int flush_buffer(bool round_up_max_blocks = false) {
170     const char MAX_BLOCK_DIGIT = (round_up_max_blocks ? '0' : '9');
171 
172     // Write the most recent buffered block, and mark has_written
173     if (!has_written) {
174       has_written = true;
175       RET_IF_RESULT_NEGATIVE(
176           padding_writer.write_left_padding(writer, total_digits));
177     }
178 
179     // if the decimal point is the next character, or is in the range covered
180     // by the buffered block, write the appropriate digits and the decimal
181     // point.
182     if (total_digits_written < digits_before_decimal &&
183         total_digits_written + buffered_digits >= digits_before_decimal &&
184         has_decimal_point) {
185       size_t digits_to_write = digits_before_decimal - total_digits_written;
186       if (digits_to_write > 0) {
187         // Write the digits before the decimal point.
188         RET_IF_RESULT_NEGATIVE(writer->write({block_buffer, digits_to_write}));
189       }
190       RET_IF_RESULT_NEGATIVE(writer->write(DECIMAL_POINT));
191       if (buffered_digits - digits_to_write > 0) {
192         // Write the digits after the decimal point.
193         RET_IF_RESULT_NEGATIVE(
194             writer->write({block_buffer + digits_to_write,
195                            (buffered_digits - digits_to_write)}));
196       }
197       // add 1 for the decimal point
198       total_digits_written += buffered_digits + 1;
199       // Mark the buffer as empty.
200       buffered_digits = 0;
201     }
202 
203     // Clear the buffered digits.
204     if (buffered_digits > 0) {
205       RET_IF_RESULT_NEGATIVE(writer->write({block_buffer, buffered_digits}));
206       total_digits_written += buffered_digits;
207       buffered_digits = 0;
208     }
209 
210     // if the decimal point is the next character, or is in the range covered
211     // by the max blocks, write the appropriate digits and the decimal point.
212     if (total_digits_written < digits_before_decimal &&
213         total_digits_written + BLOCK_SIZE * max_block_count >=
214             digits_before_decimal &&
215         has_decimal_point) {
216       size_t digits_to_write = digits_before_decimal - total_digits_written;
217       if (digits_to_write > 0) {
218         RET_IF_RESULT_NEGATIVE(writer->write(MAX_BLOCK_DIGIT, digits_to_write));
219       }
220       RET_IF_RESULT_NEGATIVE(writer->write(DECIMAL_POINT));
221       if ((BLOCK_SIZE * max_block_count) - digits_to_write > 0) {
222         RET_IF_RESULT_NEGATIVE(writer->write(
223             MAX_BLOCK_DIGIT, (BLOCK_SIZE * max_block_count) - digits_to_write));
224       }
225       // add 1 for the decimal point
226       total_digits_written += BLOCK_SIZE * max_block_count + 1;
227       // clear the buffer of max blocks
228       max_block_count = 0;
229     }
230 
231     // Clear the buffer of max blocks
232     if (max_block_count > 0) {
233       RET_IF_RESULT_NEGATIVE(
234           writer->write(MAX_BLOCK_DIGIT, max_block_count * BLOCK_SIZE));
235       total_digits_written += max_block_count * BLOCK_SIZE;
236       max_block_count = 0;
237     }
238     return 0;
239   }
240 
241   // -exponent will never overflow because all long double types we support
242   // have at most 15 bits of mantissa and the C standard defines an int as
243   // being at least 16 bits.
244   static_assert(fputil::FPBits<long double>::EXP_LEN < (sizeof(int) * 8));
245 
246 public:
FloatWriter(Writer * init_writer,bool init_has_decimal_point,const PaddingWriter & init_padding_writer)247   LIBC_INLINE FloatWriter(Writer *init_writer, bool init_has_decimal_point,
248                           const PaddingWriter &init_padding_writer)
249       : has_decimal_point(init_has_decimal_point), writer(init_writer),
250         padding_writer(init_padding_writer) {}
251 
init(size_t init_total_digits,size_t init_digits_before_decimal)252   LIBC_INLINE void init(size_t init_total_digits,
253                         size_t init_digits_before_decimal) {
254     total_digits = init_total_digits;
255     digits_before_decimal = init_digits_before_decimal;
256   }
257 
258   LIBC_INLINE void write_first_block(BlockInt block, bool exp_format = false) {
259     const DecimalString buf(block);
260     const cpp::string_view int_to_str = buf.view();
261     size_t digits_buffered = int_to_str.size();
262     // Block Buffer is guaranteed to not overflow since block cannot have more
263     // than BLOCK_SIZE digits.
264     // TODO: Replace with memcpy
265     for (size_t count = 0; count < digits_buffered; ++count) {
266       block_buffer[count] = int_to_str[count];
267     }
268     buffered_digits = digits_buffered;
269 
270     // In the exponent format (%e) we know how many digits will be written even
271     // before calculating any blocks, whereas the decimal format (%f) has to
272     // write all of the blocks that would come before the decimal place.
273     if (!exp_format) {
274       total_digits += digits_buffered;
275       digits_before_decimal += digits_buffered;
276     }
277   }
278 
write_middle_block(BlockInt block)279   LIBC_INLINE int write_middle_block(BlockInt block) {
280     if (block == MAX_BLOCK) { // Buffer max blocks in case of rounding
281       ++max_block_count;
282     } else { // If a non-max block has been found
283       RET_IF_RESULT_NEGATIVE(flush_buffer());
284 
285       // Now buffer the current block. We add 1 + MAX_BLOCK to force the
286       // leading zeroes, and drop the leading one. This is probably inefficient,
287       // but it works. See https://xkcd.com/2021/
288       const DecimalString buf(block + (MAX_BLOCK + 1));
289       const cpp::string_view int_to_str = buf.view();
290       // TODO: Replace with memcpy
291       for (size_t count = 0; count < BLOCK_SIZE; ++count) {
292         block_buffer[count] = int_to_str[count + 1];
293       }
294 
295       buffered_digits = BLOCK_SIZE;
296     }
297     return 0;
298   }
299 
300   LIBC_INLINE int write_last_block(BlockInt block, size_t block_digits,
301                                    RoundDirection round, int exponent = 0,
302                                    char exp_char = '\0') {
303     bool has_exp = (exp_char != '\0');
304 
305     char end_buff[BLOCK_SIZE];
306 
307     {
308       const DecimalString buf(block + (MAX_BLOCK + 1));
309       const cpp::string_view int_to_str = buf.view();
310 
311       // copy the last block_digits characters into the start of end_buff.
312       // TODO: Replace with memcpy
313       for (size_t count = 0; count < block_digits; ++count) {
314         end_buff[count] = int_to_str[count + 1 + (BLOCK_SIZE - block_digits)];
315       }
316     }
317 
318     char low_digit = '0';
319     if (block_digits > 0) {
320       low_digit = end_buff[block_digits - 1];
321     } else if (max_block_count > 0) {
322       low_digit = '9';
323     } else if (buffered_digits > 0) {
324       low_digit = block_buffer[buffered_digits - 1];
325     }
326 
327     bool round_up_max_blocks = false;
328 
329     // Round up
330     if (round == RoundDirection::Up ||
331         (round == RoundDirection::Even && low_digit % 2 != 0)) {
332       bool has_carry = true;
333       round_up_max_blocks = true; // if we're rounding up, we might need to
334                                   // round up the max blocks that are buffered.
335 
336       // handle the low block that we're adding
337       for (int count = static_cast<int>(block_digits) - 1;
338            count >= 0 && has_carry; --count) {
339         if (end_buff[count] == '9') {
340           end_buff[count] = '0';
341         } else {
342           end_buff[count] += 1;
343           has_carry = false;
344           round_up_max_blocks = false; // If the low block isn't all nines, then
345                                        // the max blocks aren't rounded up.
346         }
347       }
348       // handle the high block that's buffered
349       for (int count = static_cast<int>(buffered_digits) - 1;
350            count >= 0 && has_carry; --count) {
351         if (block_buffer[count] == '9') {
352           block_buffer[count] = '0';
353         } else {
354           block_buffer[count] += 1;
355           has_carry = false;
356         }
357       }
358 
359       // has_carry should only be true here if every previous digit is 9, which
360       // implies that the number has never been written.
361       if (has_carry /* && !has_written */) {
362         if (has_exp) { // This is in %e style
363           // Since this is exponential notation, we don't write any more digits
364           // but we do increment the exponent.
365           ++exponent;
366 
367           const ExponentString buf(exponent);
368           const cpp::string_view int_to_str = buf.view();
369 
370           // TODO: also change this to calculate the width of the number more
371           // efficiently.
372           size_t exponent_width = int_to_str.size();
373           size_t number_digits =
374               buffered_digits + (max_block_count * BLOCK_SIZE) + block_digits;
375 
376           // Here we have to recalculate the total number of digits since the
377           // exponent's width may have changed. We're only adding 1 to exponent
378           // width since exp_str appends the sign.
379           total_digits =
380               (has_decimal_point ? 1 : 0) + number_digits + 1 + exponent_width;
381 
382           // Normally write_left_padding is called by flush_buffer but since
383           // we're rounding up all of the digits, the ones in the buffer are
384           // wrong and can't be flushed.
385           RET_IF_RESULT_NEGATIVE(
386               padding_writer.write_left_padding(writer, total_digits));
387           // Now we know we need to print a leading 1, the decimal point, and
388           // then zeroes after it.
389           RET_IF_RESULT_NEGATIVE(writer->write('1'));
390           // digits_before_decimal - 1 to account for the leading '1'
391           if (has_decimal_point) {
392             RET_IF_RESULT_NEGATIVE(writer->write(DECIMAL_POINT));
393             // This is just the length of the number, not including the decimal
394             // point, or exponent.
395 
396             if (number_digits > 1) {
397               RET_IF_RESULT_NEGATIVE(writer->write('0', number_digits - 1));
398             }
399           }
400           RET_IF_RESULT_NEGATIVE(writer->write(exp_char));
401           RET_IF_RESULT_NEGATIVE(writer->write(int_to_str));
402 
403           total_digits_written = total_digits;
404           return WRITE_OK;
405         } else { // This is in %f style
406           ++total_digits;
407           ++digits_before_decimal;
408           // Normally write_left_padding is called by flush_buffer but since
409           // we're rounding up all of the digits, the ones in the buffer are
410           // wrong and can't be flushed.
411           RET_IF_RESULT_NEGATIVE(
412               padding_writer.write_left_padding(writer, total_digits));
413           // Now we know we need to print a leading 1, zeroes up to the decimal
414           // point, the decimal point, and then finally digits after it.
415           RET_IF_RESULT_NEGATIVE(writer->write('1'));
416           // digits_before_decimal - 1 to account for the leading '1'
417           RET_IF_RESULT_NEGATIVE(writer->write('0', digits_before_decimal - 1));
418           if (has_decimal_point) {
419             RET_IF_RESULT_NEGATIVE(writer->write(DECIMAL_POINT));
420             // add one to digits_before_decimal to account for the decimal point
421             // itself.
422             if (total_digits > digits_before_decimal + 1) {
423               RET_IF_RESULT_NEGATIVE(writer->write(
424                   '0', total_digits - (digits_before_decimal + 1)));
425             }
426           }
427           total_digits_written = total_digits;
428           return WRITE_OK;
429         }
430       }
431     }
432     // Either we intend to round down, or the rounding up is complete. Flush the
433     // buffers.
434 
435     RET_IF_RESULT_NEGATIVE(flush_buffer(round_up_max_blocks));
436 
437     // And then write the final block. It's written via the buffer so that if
438     // this is also the first block, the decimal point will be placed correctly.
439 
440     // TODO: Replace with memcpy
441     for (size_t count = 0; count < block_digits; ++count) {
442       block_buffer[count] = end_buff[count];
443     }
444     buffered_digits = block_digits;
445     RET_IF_RESULT_NEGATIVE(flush_buffer());
446 
447     if (has_exp) {
448       RET_IF_RESULT_NEGATIVE(writer->write(exp_char));
449       const ExponentString buf(exponent);
450       RET_IF_RESULT_NEGATIVE(writer->write(buf.view()));
451     }
452     total_digits_written = total_digits;
453 
454     return WRITE_OK;
455   }
456 
write_zeroes(uint32_t num_zeroes)457   LIBC_INLINE int write_zeroes(uint32_t num_zeroes) {
458     RET_IF_RESULT_NEGATIVE(flush_buffer());
459     RET_IF_RESULT_NEGATIVE(writer->write('0', num_zeroes));
460     return 0;
461   }
462 
right_pad()463   LIBC_INLINE int right_pad() {
464     return padding_writer.write_right_padding(writer, total_digits);
465   }
466 };
467 
468 // This implementation is based on the Ryu Printf algorithm by Ulf Adams:
469 // Ulf Adams. 2019. Ryū revisited: printf floating point conversion.
470 // Proc. ACM Program. Lang. 3, OOPSLA, Article 169 (October 2019), 23 pages.
471 // https://doi.org/10.1145/3360595
472 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
convert_float_decimal_typed(Writer * writer,const FormatSection & to_conv,fputil::FPBits<T> float_bits)473 LIBC_INLINE int convert_float_decimal_typed(Writer *writer,
474                                             const FormatSection &to_conv,
475                                             fputil::FPBits<T> float_bits) {
476   // signed because later we use -FRACTION_LEN
477   constexpr int32_t FRACTION_LEN = fputil::FPBits<T>::FRACTION_LEN;
478   int exponent = float_bits.get_explicit_exponent();
479 
480   char sign_char = 0;
481 
482   if (float_bits.is_neg())
483     sign_char = '-';
484   else if ((to_conv.flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN)
485     sign_char = '+'; // FORCE_SIGN has precedence over SPACE_PREFIX
486   else if ((to_conv.flags & FormatFlags::SPACE_PREFIX) ==
487            FormatFlags::SPACE_PREFIX)
488     sign_char = ' ';
489 
490   // If to_conv doesn't specify a precision, the precision defaults to 6.
491   const unsigned int precision = to_conv.precision < 0 ? 6 : to_conv.precision;
492   bool has_decimal_point =
493       (precision > 0) || ((to_conv.flags & FormatFlags::ALTERNATE_FORM) != 0);
494 
495   // nonzero is false until a nonzero digit is found. It is used to determine if
496   // leading zeroes should be printed, since before the first digit they are
497   // ignored.
498   bool nonzero = false;
499 
500   PaddingWriter padding_writer(to_conv, sign_char);
501   FloatWriter float_writer(writer, has_decimal_point, padding_writer);
502   FloatToString<T> float_converter(float_bits.get_val());
503 
504   const size_t positive_blocks = float_converter.get_positive_blocks();
505 
506   // This loop iterates through the number a block at a time until it finds a
507   // block that is not zero or it hits the decimal point. This is because all
508   // zero blocks before the first nonzero digit or the decimal point are
509   // ignored (no leading zeroes, at least at this stage).
510   for (int32_t i = static_cast<int32_t>(positive_blocks) - 1; i >= 0; --i) {
511     BlockInt digits = float_converter.get_positive_block(i);
512     if (nonzero) {
513       RET_IF_RESULT_NEGATIVE(float_writer.write_middle_block(digits));
514     } else if (digits != 0) {
515       size_t blocks_before_decimal = i;
516       float_writer.init((blocks_before_decimal * BLOCK_SIZE) +
517                             (has_decimal_point ? 1 : 0) + precision,
518                         blocks_before_decimal * BLOCK_SIZE);
519       float_writer.write_first_block(digits);
520 
521       nonzero = true;
522     }
523   }
524 
525   // if we haven't yet found a valid digit, buffer a zero.
526   if (!nonzero) {
527     float_writer.init((has_decimal_point ? 1 : 0) + precision, 0);
528     float_writer.write_first_block(0);
529   }
530 
531   if (exponent < FRACTION_LEN) {
532     const uint32_t blocks = (precision / static_cast<uint32_t>(BLOCK_SIZE)) + 1;
533     uint32_t i = 0;
534     // if all the blocks we should write are zero
535     if (blocks <= float_converter.zero_blocks_after_point()) {
536       i = blocks; // just write zeroes up to precision
537       RET_IF_RESULT_NEGATIVE(float_writer.write_zeroes(precision));
538     } else if (i < float_converter.zero_blocks_after_point()) {
539       // else if there are some blocks that are zeroes
540       i = static_cast<uint32_t>(float_converter.zero_blocks_after_point());
541       // write those blocks as zeroes.
542       RET_IF_RESULT_NEGATIVE(float_writer.write_zeroes(9 * i));
543     }
544     // for each unwritten block
545     for (; i < blocks; ++i) {
546       if (float_converter.is_lowest_block(i)) {
547         const uint32_t fill = precision - 9 * i;
548         RET_IF_RESULT_NEGATIVE(float_writer.write_zeroes(fill));
549         break;
550       }
551       BlockInt digits = float_converter.get_negative_block(i);
552       if (i < blocks - 1) {
553         RET_IF_RESULT_NEGATIVE(float_writer.write_middle_block(digits));
554       } else {
555 
556         const uint32_t maximum =
557             static_cast<uint32_t>(precision - BLOCK_SIZE * i);
558         uint32_t last_digit = 0;
559         for (uint32_t k = 0; k < BLOCK_SIZE - maximum; ++k) {
560           last_digit = digits % 10;
561           digits /= 10;
562         }
563         RoundDirection round;
564         const bool truncated = !zero_after_digits(
565             exponent - FRACTION_LEN, precision,
566             float_bits.get_explicit_mantissa(), FRACTION_LEN);
567         round = get_round_direction(last_digit, truncated, float_bits.sign());
568 
569         RET_IF_RESULT_NEGATIVE(
570             float_writer.write_last_block(digits, maximum, round));
571         break;
572       }
573     }
574   } else {
575     RET_IF_RESULT_NEGATIVE(float_writer.write_zeroes(precision));
576   }
577   RET_IF_RESULT_NEGATIVE(float_writer.right_pad());
578   return WRITE_OK;
579 }
580 
581 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
convert_float_dec_exp_typed(Writer * writer,const FormatSection & to_conv,fputil::FPBits<T> float_bits)582 LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer,
583                                             const FormatSection &to_conv,
584                                             fputil::FPBits<T> float_bits) {
585   // signed because later we use -FRACTION_LEN
586   constexpr int32_t FRACTION_LEN = fputil::FPBits<T>::FRACTION_LEN;
587   int exponent = float_bits.get_explicit_exponent();
588   StorageType mantissa = float_bits.get_explicit_mantissa();
589 
590   const char a = (to_conv.conv_name & 32) | 'A';
591 
592   char sign_char = 0;
593 
594   if (float_bits.is_neg())
595     sign_char = '-';
596   else if ((to_conv.flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN)
597     sign_char = '+'; // FORCE_SIGN has precedence over SPACE_PREFIX
598   else if ((to_conv.flags & FormatFlags::SPACE_PREFIX) ==
599            FormatFlags::SPACE_PREFIX)
600     sign_char = ' ';
601 
602   // If to_conv doesn't specify a precision, the precision defaults to 6.
603   const unsigned int precision = to_conv.precision < 0 ? 6 : to_conv.precision;
604   bool has_decimal_point =
605       (precision > 0) || ((to_conv.flags & FormatFlags::ALTERNATE_FORM) != 0);
606 
607   PaddingWriter padding_writer(to_conv, sign_char);
608   FloatWriter float_writer(writer, has_decimal_point, padding_writer);
609   FloatToString<T> float_converter(float_bits.get_val());
610 
611   size_t digits_written = 0;
612   int final_exponent = 0;
613 
614   // Here we would subtract 1 to account for the fact that block 0 counts as a
615   // positive block, but the loop below accounts for this by starting with
616   // subtracting 1 from cur_block.
617   int cur_block;
618 
619   if (exponent < 0) {
620     cur_block = -static_cast<int>(float_converter.zero_blocks_after_point());
621   } else {
622     cur_block = static_cast<int>(float_converter.get_positive_blocks());
623   }
624 
625   BlockInt digits = 0;
626 
627   // If the mantissa is 0, then the number is 0, meaning that looping until a
628   // non-zero block is found will loop forever. The first block is just 0.
629   if (mantissa != 0) {
630     // This loop finds the first block.
631     while (digits == 0) {
632       --cur_block;
633       digits = float_converter.get_block(cur_block);
634     }
635   } else {
636     cur_block = 0;
637   }
638 
639   const size_t block_width = IntegerToString<intmax_t>(digits).size();
640 
641   final_exponent = static_cast<int>(cur_block * BLOCK_SIZE) +
642                    static_cast<int>(block_width - 1);
643   int positive_exponent = final_exponent < 0 ? -final_exponent : final_exponent;
644 
645   size_t exponent_width = IntegerToString<intmax_t>(positive_exponent).size();
646 
647   // Calculate the total number of digits in the number.
648   // 1 - the digit before the decimal point
649   // 1 - the decimal point (optional)
650   // precision - the number of digits after the decimal point
651   // 1 - the 'e' at the start of the exponent
652   // 1 - the sign at the start of the exponent
653   // max(2, exp width) - the digits of the exponent, min 2.
654 
655   float_writer.init(1 + (has_decimal_point ? 1 : 0) + precision + 2 +
656                         (exponent_width < 2 ? 2 : exponent_width),
657                     1);
658 
659   // If this block is not the last block
660   if (block_width <= precision + 1) {
661     float_writer.write_first_block(digits, true);
662     digits_written += block_width;
663     --cur_block;
664   }
665 
666   // For each middle block.
667   for (; digits_written + BLOCK_SIZE < precision + 1; --cur_block) {
668     digits = float_converter.get_block(cur_block);
669 
670     RET_IF_RESULT_NEGATIVE(float_writer.write_middle_block(digits));
671     digits_written += BLOCK_SIZE;
672   }
673 
674   digits = float_converter.get_block(cur_block);
675 
676   size_t last_block_size = BLOCK_SIZE;
677 
678   // if the last block is also the first block, then ignore leading zeroes.
679   if (digits_written == 0) {
680     last_block_size = IntegerToString<intmax_t>(digits).size();
681   }
682 
683   // This tracks if the number is truncated, that meaning that the digits after
684   // last_digit are non-zero.
685   bool truncated = false;
686 
687   // This is the last block.
688   const size_t maximum = precision + 1 - digits_written;
689   uint32_t last_digit = 0;
690   for (uint32_t k = 0; k < last_block_size - maximum; ++k) {
691     if (last_digit > 0)
692       truncated = true;
693 
694     last_digit = digits % 10;
695     digits /= 10;
696   }
697 
698   // If the last block we read doesn't have the digit after the end of what
699   // we'll print, then we need to read the next block to get that digit.
700   if (maximum == last_block_size) {
701     --cur_block;
702     BlockInt extra_block = float_converter.get_block(cur_block);
703     last_digit = extra_block / ((MAX_BLOCK / 10) + 1);
704     if (extra_block % ((MAX_BLOCK / 10) + 1) > 0) {
705       truncated = true;
706     }
707   }
708 
709   RoundDirection round;
710 
711   // If we've already seen a truncated digit, then we don't need to check any
712   // more.
713   if (!truncated) {
714     // Check the blocks above the decimal point
715     if (cur_block >= 0) {
716       // Check every block until the decimal point for non-zero digits.
717       for (int cur_extra_block = cur_block - 1; cur_extra_block >= 0;
718            --cur_extra_block) {
719         BlockInt extra_block = float_converter.get_block(cur_extra_block);
720         if (extra_block > 0) {
721           truncated = true;
722           break;
723         }
724       }
725     }
726     // If it's still not truncated and there are digits below the decimal point
727     if (!truncated && exponent - FRACTION_LEN < 0) {
728       // Use the formula from %f.
729       truncated = !zero_after_digits(
730           exponent - FRACTION_LEN, precision - final_exponent,
731           float_bits.get_explicit_mantissa(), FRACTION_LEN);
732     }
733   }
734   round = get_round_direction(last_digit, truncated, float_bits.sign());
735 
736   RET_IF_RESULT_NEGATIVE(float_writer.write_last_block(
737       digits, maximum, round, final_exponent, a + 'E' - 'A'));
738 
739   RET_IF_RESULT_NEGATIVE(float_writer.right_pad());
740   return WRITE_OK;
741 }
742 
743 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
convert_float_dec_auto_typed(Writer * writer,const FormatSection & to_conv,fputil::FPBits<T> float_bits)744 LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer,
745                                              const FormatSection &to_conv,
746                                              fputil::FPBits<T> float_bits) {
747   // signed because later we use -FRACTION_LEN
748   constexpr int32_t FRACTION_LEN = fputil::FPBits<T>::FRACTION_LEN;
749   int exponent = float_bits.get_explicit_exponent();
750   StorageType mantissa = float_bits.get_explicit_mantissa();
751 
752   // From the standard: Let P (init_precision) equal the precision if nonzero, 6
753   // if the precision is omitted, or 1 if the precision is zero.
754   const unsigned int init_precision = to_conv.precision <= 0
755                                           ? (to_conv.precision == 0 ? 1 : 6)
756                                           : to_conv.precision;
757 
758   //  Then, if a conversion with style E would have an exponent of X
759   //  (base_10_exp):
760   int base_10_exp = 0;
761   // If P > X >= -4 the conversion is with style F and precision P - (X + 1).
762   // Otherwise, the conversion is with style E and precision P - 1.
763 
764   // For calculating the base 10 exponent, we need to process the number as if
765   // it has style E, so here we calculate the precision we'll use in that case.
766   const unsigned int exp_precision = init_precision - 1;
767 
768   FloatToString<T> float_converter(float_bits.get_val());
769 
770   // Here we would subtract 1 to account for the fact that block 0 counts as a
771   // positive block, but the loop below accounts for this by starting with
772   // subtracting 1 from cur_block.
773   int cur_block;
774 
775   if (exponent < 0) {
776     cur_block = -static_cast<int>(float_converter.zero_blocks_after_point());
777   } else {
778     cur_block = static_cast<int>(float_converter.get_positive_blocks());
779   }
780 
781   BlockInt digits = 0;
782 
783   // If the mantissa is 0, then the number is 0, meaning that looping until a
784   // non-zero block is found will loop forever.
785   if (mantissa != 0) {
786     // This loop finds the first non-zero block.
787     while (digits == 0) {
788       --cur_block;
789       digits = float_converter.get_block(cur_block);
790     }
791   } else {
792     // In the case of 0.0, then it's always decimal format. If we don't have alt
793     // form then the trailing zeroes are trimmed to make "0", else the precision
794     // is 1 less than specified by the user.
795     FormatSection new_conv = to_conv;
796     if ((to_conv.flags & FormatFlags::ALTERNATE_FORM) != 0) {
797       // This is a style F conversion, making the precision P - 1 - X, but since
798       // this is for the number 0, X (the base 10 exponent) is always 0.
799       new_conv.precision = init_precision - 1;
800     } else {
801       new_conv.precision = 0;
802     }
803     return convert_float_decimal_typed<T>(writer, new_conv, float_bits);
804   }
805 
806   const size_t block_width = IntegerToString<intmax_t>(digits).size();
807 
808   size_t digits_checked = 0;
809   // TODO: look into unifying trailing_zeroes and trailing_nines. The number can
810   // end in a nine or a zero, but not both.
811   size_t trailing_zeroes = 0;
812   size_t trailing_nines = 0;
813 
814   base_10_exp = static_cast<int>(cur_block * BLOCK_SIZE) +
815                 static_cast<int>(block_width - 1);
816 
817   // If the first block is not also the last block
818   if (block_width <= exp_precision + 1) {
819     const DecimalString buf(digits);
820     const cpp::string_view int_to_str = buf.view();
821 
822     for (size_t i = 0; i < block_width; ++i) {
823       if (int_to_str[i] == '9') {
824         ++trailing_nines;
825         trailing_zeroes = 0;
826       } else if (int_to_str[i] == '0') {
827         ++trailing_zeroes;
828         trailing_nines = 0;
829       } else {
830         trailing_nines = 0;
831         trailing_zeroes = 0;
832       }
833     }
834     digits_checked += block_width;
835     --cur_block;
836   }
837 
838   // Handle middle blocks
839   for (; digits_checked + BLOCK_SIZE < exp_precision + 1; --cur_block) {
840     digits = float_converter.get_block(cur_block);
841     digits_checked += BLOCK_SIZE;
842     if (digits == MAX_BLOCK) {
843       trailing_nines += 9;
844       trailing_zeroes = 0;
845     } else if (digits == 0) {
846       trailing_zeroes += 9;
847       trailing_nines = 0;
848     } else {
849       // The block is neither all nines nor all zeroes, so we need to figure out
850       // what it ends with.
851       trailing_nines = 0;
852       trailing_zeroes = 0;
853       BlockInt copy_of_digits = digits;
854       BlockInt cur_last_digit = copy_of_digits % 10;
855       // We only care if it ends in nines or zeroes.
856       while (copy_of_digits > 0 &&
857              (cur_last_digit == 9 || cur_last_digit == 0)) {
858         // If the next digit is not the same as the previous one, then there are
859         // no more contiguous trailing digits.
860         if (copy_of_digits % 10 != cur_last_digit) {
861           break;
862         }
863         if (cur_last_digit == 9) {
864           ++trailing_nines;
865         } else if (cur_last_digit == 0) {
866           ++trailing_zeroes;
867         } else {
868           break;
869         }
870         copy_of_digits /= 10;
871       }
872     }
873   }
874 
875   // Handle the last block
876 
877   digits = float_converter.get_block(cur_block);
878 
879   size_t last_block_size = BLOCK_SIZE;
880 
881   const DecimalString buf(digits);
882   const cpp::string_view int_to_str = buf.view();
883 
884   size_t implicit_leading_zeroes = BLOCK_SIZE - int_to_str.size();
885 
886   // if the last block is also the first block, then ignore leading zeroes.
887   if (digits_checked == 0) {
888     last_block_size = int_to_str.size();
889     implicit_leading_zeroes = 0;
890   }
891 
892   unsigned int digits_requested =
893       (exp_precision + 1) - static_cast<unsigned int>(digits_checked);
894 
895   int digits_to_check =
896       digits_requested - static_cast<int>(implicit_leading_zeroes);
897   if (digits_to_check < 0) {
898     digits_to_check = 0;
899   }
900 
901   // If the block is not the maximum size, that means it has leading
902   // zeroes, and zeroes are not nines.
903   if (implicit_leading_zeroes > 0) {
904     trailing_nines = 0;
905   }
906 
907   // But leading zeroes are zeroes (that could be trailing). We take the
908   // minimum of the leading zeroes and digits requested because if there are
909   // more requested digits than leading zeroes we shouldn't count those.
910   trailing_zeroes +=
911       (implicit_leading_zeroes > digits_requested ? digits_requested
912                                                   : implicit_leading_zeroes);
913 
914   // Check the upper digits of this block.
915   for (int i = 0; i < digits_to_check; ++i) {
916     if (int_to_str[i] == '9') {
917       ++trailing_nines;
918       trailing_zeroes = 0;
919     } else if (int_to_str[i] == '0') {
920       ++trailing_zeroes;
921       trailing_nines = 0;
922     } else {
923       trailing_nines = 0;
924       trailing_zeroes = 0;
925     }
926   }
927 
928   bool truncated = false;
929 
930   // Find the digit after the lowest digit that we'll actually print to
931   // determine the rounding.
932   const uint32_t maximum =
933       exp_precision + 1 - static_cast<uint32_t>(digits_checked);
934   uint32_t last_digit = 0;
935   for (uint32_t k = 0; k < last_block_size - maximum; ++k) {
936     if (last_digit > 0)
937       truncated = true;
938 
939     last_digit = digits % 10;
940     digits /= 10;
941   }
942 
943   // If the last block we read doesn't have the digit after the end of what
944   // we'll print, then we need to read the next block to get that digit.
945   if (maximum == last_block_size) {
946     --cur_block;
947     BlockInt extra_block = float_converter.get_block(cur_block);
948     last_digit = extra_block / ((MAX_BLOCK / 10) + 1);
949 
950     if (extra_block % ((MAX_BLOCK / 10) + 1) > 0)
951       truncated = true;
952   }
953 
954   // TODO: unify this code across the three float conversions.
955   RoundDirection round;
956 
957   // If we've already seen a truncated digit, then we don't need to check any
958   // more.
959   if (!truncated) {
960     // Check the blocks above the decimal point
961     if (cur_block >= 0) {
962       // Check every block until the decimal point for non-zero digits.
963       for (int cur_extra_block = cur_block - 1; cur_extra_block >= 0;
964            --cur_extra_block) {
965         BlockInt extra_block = float_converter.get_block(cur_extra_block);
966         if (extra_block > 0) {
967           truncated = true;
968           break;
969         }
970       }
971     }
972     // If it's still not truncated and there are digits below the decimal point
973     if (!truncated && exponent - FRACTION_LEN < 0) {
974       // Use the formula from %f.
975       truncated = !zero_after_digits(
976           exponent - FRACTION_LEN, exp_precision - base_10_exp,
977           float_bits.get_explicit_mantissa(), FRACTION_LEN);
978     }
979   }
980 
981   round = get_round_direction(last_digit, truncated, float_bits.sign());
982 
983   bool round_up;
984   if (round == RoundDirection::Up) {
985     round_up = true;
986   } else if (round == RoundDirection::Down) {
987     round_up = false;
988   } else {
989     // RoundDirection is even, so check the lowest digit that will be printed.
990     uint32_t low_digit;
991 
992     // maximum is the number of digits that will remain in digits after getting
993     // last_digit. If it's greater than zero, we can just check the lowest digit
994     // in digits.
995     if (maximum > 0) {
996       low_digit = digits % 10;
997     } else {
998       // Else if there are trailing nines, then the low digit is a nine, same
999       // with zeroes.
1000       if (trailing_nines > 0) {
1001         low_digit = 9;
1002       } else if (trailing_zeroes > 0) {
1003         low_digit = 0;
1004       } else {
1005         // If there are no trailing zeroes or nines, then the round direction
1006         // doesn't actually matter here. Since this conversion passes off the
1007         // value to another one for final conversion, rounding only matters to
1008         // determine if the exponent is higher than expected (with an all nine
1009         // number) or to determine the trailing zeroes to trim. In this case
1010         // low_digit is set to 0, but it could be set to any number.
1011 
1012         low_digit = 0;
1013       }
1014     }
1015     round_up = (low_digit % 2) != 0;
1016   }
1017 
1018   digits_checked += digits_requested;
1019   LIBC_ASSERT(digits_checked == init_precision);
1020   // At this point we should have checked all the digits requested by the
1021   // precision. We may increment this number 1 more if we round up all of the
1022   // digits, but at this point in the code digits_checked should always equal
1023   // init_precision.
1024 
1025   if (round_up) {
1026     // If all the digits that would be printed are nines, then rounding up means
1027     // that the base 10 exponent is one higher and all those nines turn to
1028     // zeroes (e.g. 999 -> 1000).
1029     if (trailing_nines == init_precision) {
1030       ++base_10_exp;
1031       trailing_zeroes = digits_checked;
1032       ++digits_checked;
1033     } else {
1034       // If there are trailing nines, they turn into trailing zeroes when
1035       // they're rounded up.
1036       if (trailing_nines > 0) {
1037         trailing_zeroes += trailing_nines;
1038       } else if (trailing_zeroes > 0) {
1039         // If there are trailing zeroes, then the last digit will be rounded up
1040         // to a 1 so they aren't trailing anymore.
1041         trailing_zeroes = 0;
1042       }
1043     }
1044   }
1045 
1046   // if P > X >= -4, the conversion is with style f (or F) and precision equals
1047   //  P - (X + 1).
1048   if (static_cast<int>(init_precision) > base_10_exp && base_10_exp >= -4) {
1049     FormatSection new_conv = to_conv;
1050     const int conv_precision = init_precision - (base_10_exp + 1);
1051 
1052     if ((to_conv.flags & FormatFlags::ALTERNATE_FORM) != 0) {
1053       new_conv.precision = conv_precision;
1054     } else {
1055       // If alt form isn't set, then we need to determine the number of trailing
1056       // zeroes and set the precision such that they are removed.
1057 
1058       /*
1059       Here's a diagram of an example:
1060 
1061       printf("%.15g", 22.25);
1062 
1063                             +--- init_precision = 15
1064                             |
1065                             +-------------------+
1066                             |                   |
1067                             |  ++--- trimmed_precision = 2
1068                             |  ||               |
1069                             22.250000000000000000
1070                             ||   |              |
1071                             ++   +--------------+
1072                              |   |
1073        base_10_exp + 1 = 2 --+   +--- trailing_zeroes = 11
1074       */
1075       int trimmed_precision = static_cast<int>(
1076           digits_checked - (base_10_exp + 1) - trailing_zeroes);
1077       if (trimmed_precision < 0) {
1078         trimmed_precision = 0;
1079       }
1080       new_conv.precision = (trimmed_precision > conv_precision)
1081                                ? conv_precision
1082                                : trimmed_precision;
1083     }
1084 
1085     return convert_float_decimal_typed<T>(writer, new_conv, float_bits);
1086   } else {
1087     // otherwise, the conversion is with style e (or E) and precision equals
1088     // P - 1
1089     const int conv_precision = init_precision - 1;
1090     FormatSection new_conv = to_conv;
1091     if ((to_conv.flags & FormatFlags::ALTERNATE_FORM) != 0) {
1092       new_conv.precision = conv_precision;
1093     } else {
1094       // If alt form isn't set, then we need to determine the number of trailing
1095       // zeroes and set the precision such that they are removed.
1096       int trimmed_precision =
1097           static_cast<int>(digits_checked - 1 - trailing_zeroes);
1098       if (trimmed_precision < 0) {
1099         trimmed_precision = 0;
1100       }
1101       new_conv.precision = (trimmed_precision > conv_precision)
1102                                ? conv_precision
1103                                : trimmed_precision;
1104     }
1105     return convert_float_dec_exp_typed<T>(writer, new_conv, float_bits);
1106   }
1107 }
1108 
1109 // TODO: unify the float converters to remove the duplicated checks for inf/nan.
convert_float_decimal(Writer * writer,const FormatSection & to_conv)1110 LIBC_INLINE int convert_float_decimal(Writer *writer,
1111                                       const FormatSection &to_conv) {
1112   if (to_conv.length_modifier == LengthModifier::L) {
1113     fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
1114     fputil::FPBits<long double> float_bits(float_raw);
1115     if (!float_bits.is_inf_or_nan()) {
1116       return convert_float_decimal_typed<long double>(writer, to_conv,
1117                                                       float_bits);
1118     }
1119   } else {
1120     fputil::FPBits<double>::StorageType float_raw =
1121         static_cast<fputil::FPBits<double>::StorageType>(to_conv.conv_val_raw);
1122     fputil::FPBits<double> float_bits(float_raw);
1123     if (!float_bits.is_inf_or_nan()) {
1124       return convert_float_decimal_typed<double>(writer, to_conv, float_bits);
1125     }
1126   }
1127 
1128   return convert_inf_nan(writer, to_conv);
1129 }
1130 
convert_float_dec_exp(Writer * writer,const FormatSection & to_conv)1131 LIBC_INLINE int convert_float_dec_exp(Writer *writer,
1132                                       const FormatSection &to_conv) {
1133   if (to_conv.length_modifier == LengthModifier::L) {
1134     fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
1135     fputil::FPBits<long double> float_bits(float_raw);
1136     if (!float_bits.is_inf_or_nan()) {
1137       return convert_float_dec_exp_typed<long double>(writer, to_conv,
1138                                                       float_bits);
1139     }
1140   } else {
1141     fputil::FPBits<double>::StorageType float_raw =
1142         static_cast<fputil::FPBits<double>::StorageType>(to_conv.conv_val_raw);
1143     fputil::FPBits<double> float_bits(float_raw);
1144     if (!float_bits.is_inf_or_nan()) {
1145       return convert_float_dec_exp_typed<double>(writer, to_conv, float_bits);
1146     }
1147   }
1148 
1149   return convert_inf_nan(writer, to_conv);
1150 }
1151 
convert_float_dec_auto(Writer * writer,const FormatSection & to_conv)1152 LIBC_INLINE int convert_float_dec_auto(Writer *writer,
1153                                        const FormatSection &to_conv) {
1154   if (to_conv.length_modifier == LengthModifier::L) {
1155     fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
1156     fputil::FPBits<long double> float_bits(float_raw);
1157     if (!float_bits.is_inf_or_nan()) {
1158       return convert_float_dec_auto_typed<long double>(writer, to_conv,
1159                                                        float_bits);
1160     }
1161   } else {
1162     fputil::FPBits<double>::StorageType float_raw =
1163         static_cast<fputil::FPBits<double>::StorageType>(to_conv.conv_val_raw);
1164     fputil::FPBits<double> float_bits(float_raw);
1165     if (!float_bits.is_inf_or_nan()) {
1166       return convert_float_dec_auto_typed<double>(writer, to_conv, float_bits);
1167     }
1168   }
1169 
1170   return convert_inf_nan(writer, to_conv);
1171 }
1172 
1173 } // namespace printf_core
1174 } // namespace LIBC_NAMESPACE_DECL
1175 
1176 #endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_H
1177