[NFC][Py Reformat] Added more commits to .git-blame-ignore-revs
[llvm-project.git] / libc / src / __support / float_to_string.h
blob09370148d803ae6d836d86fb4a61fbf402a24b6d
1 //===-- Utilities to convert floating point values to string ----*- 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 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC_SUPPORT_FLOAT_TO_STRING_H
10 #define LLVM_LIBC_SRC_SUPPORT_FLOAT_TO_STRING_H
12 #include <stdint.h>
14 #include "src/__support/CPP/type_traits.h"
15 #include "src/__support/FPUtil/FPBits.h"
16 #include "src/__support/UInt.h"
17 #include "src/__support/common.h"
18 #include "src/__support/libc_assert.h"
19 #include "src/__support/ryu_constants.h"
21 // This implementation is based on the Ryu Printf algorithm by Ulf Adams:
22 // Ulf Adams. 2019. Ryƫ revisited: printf floating point conversion.
23 // Proc. ACM Program. Lang. 3, OOPSLA, Article 169 (October 2019), 23 pages.
24 // https://doi.org/10.1145/3360595
26 // This version is modified to require significantly less memory (it doesn't use
27 // a large buffer to store the result).
29 // The general concept of this algorithm is as follows:
30 // We want to calculate a 9 digit segment of a floating point number using this
31 // formula: floor((mantissa * 2^exponent)/10^i) % 10^9.
32 // To do so normally would involve large integers (~1000 bits for doubles), so
33 // we use a shortcut. We can avoid calculating 2^exponent / 10^i by using a
34 // lookup table. The resulting intermediate value needs to be about 192 bits to
35 // store the result with enough precision. Since this is all being done with
36 // integers for appropriate precision, we would run into a problem if
37 // i > exponent since then 2^exponent / 10^i would be less than 1. To correct
38 // for this, the actual calculation done is 2^(exponent + c) / 10^i, and then
39 // when multiplying by the mantissa we reverse this by dividing by 2^c, like so:
40 // floor((mantissa * table[exponent][i])/(2^c)) % 10^9.
41 // This gives a 9 digit value, which is small enough to fit in a 32 bit integer,
42 // and that integer is converted into a string as normal, and called a block. In
43 // this implementation, the most recent block is buffered, so that if rounding
44 // is necessary the block can be adjusted before being written to the output.
45 // Any block that is all 9s adds one to the max block counter and doesn't clear
46 // the buffer because they can cause the block above them to be rounded up.
48 namespace __llvm_libc {
50 using BlockInt = uint32_t;
51 constexpr size_t BLOCK_SIZE = 9;
53 using MantissaInt = fputil::FPBits<long double>::UIntType;
55 constexpr size_t POW10_ADDITIONAL_BITS_CALC = 128;
56 constexpr size_t POW10_ADDITIONAL_BITS_TABLE = 120;
58 constexpr size_t MID_INT_SIZE = 192;
60 namespace internal {
62 // Returns floor(log_10(2^e)); requires 0 <= e <= 1650.
63 LIBC_INLINE constexpr uint32_t log10_pow2(const uint32_t e) {
64 // The first value this approximation fails for is 2^1651 which is just
65 // greater than 10^297.
66 LIBC_ASSERT(e >= 0 && e <= 1650 &&
67 "Incorrect exponent to perform log10_pow2 approximation.");
68 return (e * 78913) >> 18;
71 // Returns 1 + floor(log_10(2^e). This could technically be off by 1 if any
72 // power of 2 was also a power of 10, but since that doesn't exist this is
73 // always accurate. This is used to calculate the maximum number of base-10
74 // digits a given e-bit number could have.
75 LIBC_INLINE constexpr uint32_t ceil_log10_pow2(const uint32_t e) {
76 return log10_pow2(e) + 1;
79 // Returns the maximum number of 9 digit blocks a number described by the given
80 // index (which is ceil(exponent/16)) and mantissa width could need.
81 LIBC_INLINE constexpr uint32_t length_for_num(const uint32_t idx,
82 const uint32_t mantissa_width) {
83 //+8 to round up when dividing by 9
84 return (ceil_log10_pow2(16 * idx) + ceil_log10_pow2(mantissa_width) +
85 (BLOCK_SIZE - 1)) /
86 BLOCK_SIZE;
87 // return (ceil_log10_pow2(16 * idx + mantissa_width) + 8) / 9;
90 // The formula for the table when i is positive (or zero) is as follows:
91 // floor(10^(-9i) * 2^(e + c_1) + 1) % (10^9 * 2^c_1)
92 // Rewritten slightly we get:
93 // floor(5^(-9i) * 2^(e + c_1 - 9i) + 1) % (10^9 * 2^c_1)
95 // TODO: Fix long doubles (needs bigger table or alternate algorithm.)
96 // Currently the table values are generated, which is very slow.
97 template <size_t INT_SIZE>
98 LIBC_INLINE constexpr cpp::UInt<MID_INT_SIZE>
99 get_table_positive(int exponent, size_t i, const size_t constant) {
100 // INT_SIZE is the size of int that is used for the internal calculations of
101 // this function. It should be large enough to hold 2^(exponent+constant), so
102 // ~1000 for double and ~16000 for long double. Be warned that the time
103 // complexity of exponentiation is O(n^2 * log_2(m)) where n is the number of
104 // bits in the number being exponentiated and m is the exponent.
105 int shift_amount = exponent + constant - (9 * i);
106 if (shift_amount < 0) {
107 return 1;
109 cpp::UInt<INT_SIZE> num(0);
110 // MOD_SIZE is one of the limiting factors for how big the constant argument
111 // can get, since it needs to be small enough to fit in the result UInt,
112 // otherwise we'll get truncation on return.
113 const cpp::UInt<INT_SIZE> MOD_SIZE =
114 (cpp::UInt<INT_SIZE>(1) << constant) * 1000000000;
115 constexpr uint64_t FIVE_EXP_NINE = 1953125;
117 num = cpp::UInt<INT_SIZE>(1) << (shift_amount);
118 if (i > 0) {
119 cpp::UInt<INT_SIZE> fives(FIVE_EXP_NINE);
120 fives.pow_n(i);
121 num = num / fives;
124 num = num + 1;
125 if (num > MOD_SIZE) {
126 num = num % MOD_SIZE;
128 return num;
131 // The formula for the table when i is negative (or zero) is as follows:
132 // floor(10^(-9i) * 2^(c_0 - e)) % (10^9 * 2^c_0)
133 // Since we know i is always negative, we just take it as unsigned and treat it
134 // as negative. We do the same with exponent, while they're both always negative
135 // in theory, in practice they're converted to positive for simpler
136 // calculations.
137 // The formula being used looks more like this:
138 // floor(10^(9*(-i)) * 2^(c_0 + (-e))) % (10^9 * 2^c_0)
139 LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_negative(int exponent, size_t i,
140 const size_t constant) {
141 constexpr size_t INT_SIZE = 1024;
142 int shift_amount = constant - exponent;
143 cpp::UInt<INT_SIZE> num(1);
144 // const cpp::UInt<INT_SIZE> MOD_SIZE =
145 // (cpp::UInt<INT_SIZE>(1) << constant) * 1000000000;
147 constexpr uint64_t TEN_EXP_NINE = 1000000000;
148 constexpr uint64_t FIVE_EXP_NINE = 1953125;
149 size_t ten_blocks = i;
150 size_t five_blocks = 0;
151 if (shift_amount < 0) {
152 int block_shifts = (-shift_amount) / 9;
153 if (block_shifts < static_cast<int>(ten_blocks)) {
154 ten_blocks = ten_blocks - block_shifts;
155 five_blocks = block_shifts;
156 shift_amount = shift_amount + (block_shifts * 9);
157 } else {
158 ten_blocks = 0;
159 five_blocks = i;
160 shift_amount = shift_amount + (i * 9);
164 if (five_blocks > 0) {
165 cpp::UInt<INT_SIZE> fives(FIVE_EXP_NINE);
166 fives.pow_n(five_blocks);
167 num *= fives;
169 if (ten_blocks > 0) {
170 cpp::UInt<INT_SIZE> tens(TEN_EXP_NINE);
171 tens.pow_n(ten_blocks);
172 num *= tens;
175 if (shift_amount > 0) {
176 num = num << shift_amount;
177 } else {
178 num = num >> (-shift_amount);
180 // if (num > MOD_SIZE) {
181 // num = num % MOD_SIZE;
182 // }
183 return num;
186 LIBC_INLINE uint32_t fast_uint_mod_1e9(const cpp::UInt<MID_INT_SIZE> &val) {
187 // The formula for mult_const is:
188 // 1 + floor((2^(bits in target integer size + log_2(divider))) / divider)
189 // Where divider is 10^9 and target integer size is 128.
190 const cpp::UInt<MID_INT_SIZE> mult_const(
191 {0x31680A88F8953031u, 0x89705F4136B4A597u, 0});
192 const auto middle = (mult_const * val);
193 const uint64_t result = static_cast<uint64_t>(middle[2]);
194 const uint32_t shifted = result >> 29;
195 return static_cast<uint32_t>(val) - (1000000000 * shifted);
198 LIBC_INLINE uint32_t mul_shift_mod_1e9(const MantissaInt mantissa,
199 const cpp::UInt<MID_INT_SIZE> &large,
200 const int32_t shift_amount) {
201 constexpr size_t MANT_INT_SIZE = sizeof(MantissaInt) * 8;
202 cpp::UInt<MID_INT_SIZE + MANT_INT_SIZE> val(large);
203 // TODO: Find a better way to force __uint128_t to be UInt<128>
204 cpp::UInt<MANT_INT_SIZE> wide_mant(0);
205 wide_mant[0] = mantissa & (uint64_t(-1));
206 wide_mant[1] = mantissa >> 64;
207 val = (val * wide_mant) >> shift_amount;
208 return fast_uint_mod_1e9(val);
211 } // namespace internal
213 // Convert floating point values to their string representation.
214 // Because the result may not fit in a reasonably sized array, the caller must
215 // request blocks of digits and convert them from integers to strings themself.
216 // Blocks contain the most digits that can be stored in an BlockInt. This is 9
217 // digits for a 32 bit int and 18 digits for a 64 bit int.
218 // The intended use pattern is to create a FloatToString object of the
219 // appropriate type, then call get_positive_blocks to get an approximate number
220 // of blocks there are before the decimal point. Now the client code can start
221 // calling get_positive_block in a loop from the number of positive blocks to
222 // zero. This will give all digits before the decimal point. Then the user can
223 // start calling get_negative_block in a loop from 0 until the number of digits
224 // they need is reached. As an optimization, the client can use
225 // zero_blocks_after_point to find the number of blocks that are guaranteed to
226 // be zero after the decimal point and before the non-zero digits. Additionally,
227 // is_lowest_block will return if the current block is the lowest non-zero
228 // block.
229 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
230 class FloatToString {
231 fputil::FPBits<T> float_bits;
232 bool is_negative;
233 int exponent;
234 MantissaInt mantissa;
236 static constexpr int MANT_WIDTH = fputil::MantissaWidth<T>::VALUE;
237 static constexpr int EXP_BIAS = fputil::FPBits<T>::EXPONENT_BIAS;
239 // constexpr void init_convert();
241 public:
242 LIBC_INLINE constexpr FloatToString(T init_float) : float_bits(init_float) {
243 is_negative = float_bits.get_sign();
244 exponent = float_bits.get_exponent();
245 mantissa = float_bits.get_explicit_mantissa();
247 // Handle the exponent for numbers with a 0 exponent.
248 if (exponent == -EXP_BIAS) {
249 if (mantissa > 0) { // Subnormals
250 ++exponent;
251 } else { // Zeroes
252 exponent = 0;
256 // Adjust for the width of the mantissa.
257 exponent -= MANT_WIDTH;
259 // init_convert();
262 LIBC_INLINE constexpr bool is_nan() { return float_bits.is_nan(); }
263 LIBC_INLINE constexpr bool is_inf() { return float_bits.is_inf(); }
264 LIBC_INLINE constexpr bool is_inf_or_nan() {
265 return float_bits.is_inf_or_nan();
268 // get_block returns an integer that represents the digits in the requested
269 // block.
270 LIBC_INLINE constexpr BlockInt get_positive_block(int block_index) {
271 if (exponent >= -MANT_WIDTH) {
272 // idx is ceil(exponent/16) or 0 if exponent is negative. This is used to
273 // find the coarse section of the POW10_SPLIT table that will be used to
274 // calculate the 9 digit window, as well as some other related values.
275 const uint32_t idx =
276 exponent < 0 ? 0 : static_cast<uint32_t>(exponent + 15) / 16;
278 uint32_t temp_shift_amount =
279 POW10_ADDITIONAL_BITS_TABLE + (16 * idx) - exponent;
280 const uint32_t shift_amount = temp_shift_amount;
281 // shift_amount = -(c0 - exponent) = c_0 + 16 * ceil(exponent/16) -
282 // exponent
284 int32_t i = block_index;
285 cpp::UInt<MID_INT_SIZE> val;
286 val = POW10_SPLIT[POW10_OFFSET[idx] + i];
288 const uint32_t digits =
289 internal::mul_shift_mod_1e9(mantissa, val, (int32_t)(shift_amount));
290 return digits;
291 } else {
292 return 0;
296 LIBC_INLINE constexpr BlockInt get_negative_block(int block_index) {
297 if (exponent < 0) {
298 const int32_t idx = -exponent / 16;
299 uint32_t i = block_index;
300 // if the requested block is zero
301 if (i < MIN_BLOCK_2[idx]) {
302 return 0;
304 const int32_t shift_amount =
305 POW10_ADDITIONAL_BITS_TABLE + (-exponent - 16 * idx);
306 const uint32_t p = POW10_OFFSET_2[idx] + i - MIN_BLOCK_2[idx];
307 // If every digit after the requested block is zero.
308 if (p >= POW10_OFFSET_2[idx + 1]) {
309 return 0;
312 cpp::UInt<MID_INT_SIZE> table_val = POW10_SPLIT_2[p];
313 // cpp::UInt<MID_INT_SIZE> calculated_val =
314 // get_table_negative(idx * 16, i + 1, POW10_ADDITIONAL_BITS_CALC);
315 uint32_t digits =
316 internal::mul_shift_mod_1e9(mantissa, table_val, shift_amount);
317 return digits;
318 } else {
319 return 0;
323 LIBC_INLINE constexpr BlockInt get_block(int block_index) {
324 if (block_index >= 0) {
325 return get_positive_block(block_index);
326 } else {
327 return get_negative_block(-1 - block_index);
331 LIBC_INLINE constexpr size_t get_positive_blocks() {
332 if (exponent >= -MANT_WIDTH) {
333 const uint32_t idx =
334 exponent < 0 ? 0 : static_cast<uint32_t>(exponent + 15) / 16;
335 const uint32_t len = internal::length_for_num(idx, MANT_WIDTH);
336 return len;
337 } else {
338 return 0;
342 // This takes the index of a block after the decimal point (a negative block)
343 // and return if it's sure that all of the digits after it are zero.
344 LIBC_INLINE constexpr bool is_lowest_block(size_t block_index) {
345 const int32_t idx = -exponent / 16;
346 const uint32_t p = POW10_OFFSET_2[idx] + block_index - MIN_BLOCK_2[idx];
347 // If the remaining digits are all 0, then this is the lowest block.
348 return p >= POW10_OFFSET_2[idx + 1];
351 LIBC_INLINE constexpr size_t zero_blocks_after_point() {
352 return MIN_BLOCK_2[-exponent / 16];
356 // template <> constexpr void FloatToString<float>::init_convert() { ; }
358 // template <> constexpr void FloatToString<double>::init_convert() { ; }
360 // template <> constexpr void FloatToString<long double>::init_convert() {
361 // // TODO: More here.
362 // ;
363 // }
365 template <>
366 LIBC_INLINE constexpr size_t
367 FloatToString<long double>::zero_blocks_after_point() {
368 return 0;
371 template <>
372 LIBC_INLINE constexpr bool FloatToString<long double>::is_lowest_block(size_t) {
373 return false;
376 template <>
377 LIBC_INLINE constexpr BlockInt
378 FloatToString<long double>::get_positive_block(int block_index) {
379 if (exponent >= -MANT_WIDTH) {
380 const uint32_t pos_exp = (exponent < 0 ? 0 : exponent);
382 uint32_t temp_shift_amount =
383 POW10_ADDITIONAL_BITS_CALC + pos_exp - exponent;
384 const uint32_t shift_amount = temp_shift_amount;
385 // shift_amount = -(c0 - exponent) = c_0 + 16 * ceil(exponent/16) -
386 // exponent
388 int32_t i = block_index;
389 cpp::UInt<MID_INT_SIZE> val;
390 if (exponent + POW10_ADDITIONAL_BITS_CALC < 1024) {
391 val = internal::get_table_positive<1024>(pos_exp, i,
392 POW10_ADDITIONAL_BITS_CALC);
393 } else if (exponent + POW10_ADDITIONAL_BITS_CALC < 4096) {
394 val = internal::get_table_positive<4096>(pos_exp, i,
395 POW10_ADDITIONAL_BITS_CALC);
396 } else if (exponent + POW10_ADDITIONAL_BITS_CALC < 8192) {
397 val = internal::get_table_positive<8192>(pos_exp, i,
398 POW10_ADDITIONAL_BITS_CALC);
399 } else {
400 val = internal::get_table_positive<16384>(pos_exp, i,
401 POW10_ADDITIONAL_BITS_CALC);
404 const BlockInt digits =
405 internal::mul_shift_mod_1e9(mantissa, val, (int32_t)(shift_amount));
406 return digits;
407 } else {
408 return 0;
412 template <>
413 LIBC_INLINE constexpr BlockInt
414 FloatToString<long double>::get_negative_block(int block_index) {
415 if (exponent < 0) {
416 const int32_t idx = -exponent / 16;
417 uint32_t i = -1 - block_index;
418 // if the requested block is zero
419 if (i <= MIN_BLOCK_2[idx]) {
420 return 0;
422 const int32_t shift_amount =
423 POW10_ADDITIONAL_BITS_CALC + (-exponent - 16 * idx);
424 const uint32_t p = POW10_OFFSET_2[idx] + i - MIN_BLOCK_2[idx];
425 // If every digit after the requested block is zero.
426 if (p >= POW10_OFFSET_2[idx + 1]) {
427 return 0;
430 // cpp::UInt<MID_INT_SIZE> table_val = POW10_SPLIT_2[p];
431 cpp::UInt<MID_INT_SIZE> calculated_val = internal::get_table_negative(
432 idx * 16, i + 1, POW10_ADDITIONAL_BITS_CALC);
433 BlockInt digits =
434 internal::mul_shift_mod_1e9(mantissa, calculated_val, shift_amount);
435 return digits;
436 } else {
437 return 0;
441 } // namespace __llvm_libc
443 #endif // LLVM_LIBC_SRC_SUPPORT_FLOAT_TO_STRING_H