Warning: This file is not a C or C++ file. It does not have highlighting.
| 1 | //===-- Decimal Float Converter for printf (320-bit float) ------*- 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 | // This file implements an alternative to the Ryū printf algorithm in |
| 10 | // float_dec_converter.h. Instead of generating output digits 9 at a time on |
| 11 | // demand, in this implementation, a float is converted to decimal by computing |
| 12 | // just one power of 10 and multiplying/dividing the entire input by it, |
| 13 | // generating the whole string of decimal output digits in one go. |
| 14 | // |
| 15 | // This avoids the large constant lookup table of Ryū, making it more suitable |
| 16 | // for low-memory embedded contexts; but it's also faster than the fallback |
| 17 | // version of Ryū which computes table entries on demand using DyadicFloat, |
| 18 | // because those must calculate a potentially large power of 10 per 9-digit |
| 19 | // output block, whereas this computes just one, which does the whole job. |
| 20 | // |
| 21 | // The calculation is done in 320-bit DyadicFloat, which provides enough |
| 22 | // precision to generate 39 correct digits of output from any floating-point |
| 23 | // size up to and including 128-bit long double, because the rounding errors in |
| 24 | // computing the largest necessary power of 10 are still smaller than the |
| 25 | // distance (in the 320-bit float format) between adjacent 39-decimal-digit |
| 26 | // outputs. |
| 27 | // |
| 28 | // No further digits beyond the 39th are generated: if the printf format string |
| 29 | // asks for more precision than that, the answer is padded with 0s. This is a |
| 30 | // permitted option in IEEE 754-2019 (section 5.12.2): you're allowed to define |
| 31 | // a limit H on the number of decimal digits you can generate, and pad with 0s |
| 32 | // if asked for more than that, subject to the constraint that H must be |
| 33 | // consistent across all float formats you support (you can't use a smaller H |
| 34 | // for single precision than double or long double), and must be large enough |
| 35 | // that even in the largest supported precision the only numbers misrounded are |
| 36 | // ones extremely close to a rounding boundary. 39 digits is the smallest |
| 37 | // permitted value for an implementation supporting binary128. |
| 38 | // |
| 39 | //===----------------------------------------------------------------------===// |
| 40 | |
| 41 | #ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_LIMITED_H |
| 42 | #define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_LIMITED_H |
| 43 | |
| 44 | #include "src/__support/CPP/algorithm.h" |
| 45 | #include "src/__support/CPP/string.h" |
| 46 | #include "src/__support/CPP/string_view.h" |
| 47 | #include "src/__support/FPUtil/FPBits.h" |
| 48 | #include "src/__support/FPUtil/dyadic_float.h" |
| 49 | #include "src/__support/FPUtil/rounding_mode.h" |
| 50 | #include "src/__support/integer_to_string.h" |
| 51 | #include "src/__support/libc_assert.h" |
| 52 | #include "src/__support/macros/config.h" |
| 53 | #include "src/stdio/printf_core/core_structs.h" |
| 54 | #include "src/stdio/printf_core/float_inf_nan_converter.h" |
| 55 | #include "src/stdio/printf_core/writer.h" |
| 56 | |
| 57 | namespace LIBC_NAMESPACE_DECL { |
| 58 | namespace printf_core { |
| 59 | |
| 60 | enum class ConversionType { E, F, G }; |
| 61 | using StorageType = fputil::FPBits<long double>::StorageType; |
| 62 | |
| 63 | constexpr unsigned MAX_DIGITS = 39; |
| 64 | constexpr size_t DF_BITS = 320; |
| 65 | constexpr char DECIMAL_POINT = '.'; |
| 66 | |
| 67 | struct DigitsInput { |
| 68 | // Input mantissa, stored with the explicit leading 1 bit (if any) at the |
| 69 | // top. So either it has a value in the range [2^127,2^128) representing a |
| 70 | // real number in [1,2), or it has the value 0, representing 0. |
| 71 | UInt128 mantissa; |
| 72 | |
| 73 | // Input exponent, as a power of 2 to multiply into mantissa. |
| 74 | int exponent; |
| 75 | |
| 76 | // Input sign. |
| 77 | Sign sign; |
| 78 | |
| 79 | // Constructor which accepts a mantissa direct from a floating-point format, |
| 80 | // and shifts it up to the top of the UInt128 so that a function consuming |
| 81 | // this struct afterwards doesn't have to remember which format it came from. |
| 82 | DigitsInput(int32_t fraction_len, StorageType mantissa_, int exponent_, |
| 83 | Sign sign) |
| 84 | : mantissa(UInt128(mantissa_) << (127 - fraction_len)), |
| 85 | exponent(exponent_), sign(sign) { |
| 86 | if (!(mantissa & (UInt128(1) << 127)) && mantissa != 0) { |
| 87 | // Normalize a denormalized input. |
| 88 | int shift = cpp::countl_zero(mantissa); |
| 89 | mantissa <<= shift; |
| 90 | exponent -= shift; |
| 91 | } |
| 92 | } |
| 93 | }; |
| 94 | |
| 95 | struct DigitsOutput { |
| 96 | // Output from decimal_digits(). |
| 97 | // |
| 98 | // `digits` is a buffer containing nothing but ASCII digits. Even if the |
| 99 | // decimal point needs to appear somewhere in the final output string, it |
| 100 | // isn't represented in _this_ string; the client of this object will insert |
| 101 | // it in an appropriate place. `ndigits` gives the buffer size. |
| 102 | // |
| 103 | // `exponent` represents the exponent you would display if the decimal point |
| 104 | // comes after the first digit of decimal_digits, e.g. if digits == "1234" |
| 105 | // and exponent = 3 then this represents 1.234e3, or just the integer 1234. |
| 106 | size_t ndigits; |
| 107 | int exponent; |
| 108 | char digits[MAX_DIGITS + 1]; |
| 109 | }; |
| 110 | |
| 111 | // Estimate log10 of a power of 2, by multiplying its exponent by |
| 112 | // 1292913986/2^32. That is a rounded-down approximation to log10(2), accurate |
| 113 | // enough that for any binary exponent in the range of float128 it will give |
| 114 | // the correct value of floor(log10(2^n)). |
| 115 | LIBC_INLINE int estimate_log10(int exponent_of_2) { |
| 116 | return static_cast<int>((exponent_of_2 * 1292913986LL) >> 32); |
| 117 | } |
| 118 | |
| 119 | // Calculate the actual digits of a decimal representation of an FP number. |
| 120 | // |
| 121 | // If `e_mode` is true, then `precision` indicates the desired number of output |
| 122 | // decimal digits. On return, `decimal_digits` will be a string of length |
| 123 | // exactly `precision` starting with a nonzero digit; `decimal_exponent` will |
| 124 | // be filled in to indicate the exponent as shown above. |
| 125 | // |
| 126 | // If `e_mode` is false, then `precision` indicates the desired number of |
| 127 | // digits after the decimal point. On return, the last digit in the string |
| 128 | // `decimal_digits` has a place value of _at least_ 10^-precision. But also, at |
| 129 | // most `MAX_DIGITS` digits are returned, so the caller may need to pad it at |
| 130 | // the end with the appropriate number of extra 0s. |
| 131 | LIBC_INLINE |
| 132 | DigitsOutput decimal_digits(DigitsInput input, int precision, bool e_mode) { |
| 133 | if (input.mantissa == 0) { |
| 134 | // Special-case zero, by manually generating the right number of zero |
| 135 | // digits and setting an appropriate exponent. |
| 136 | DigitsOutput output; |
| 137 | if (!e_mode) { |
| 138 | // In F mode, it's enough to return an empty string of digits. That's the |
| 139 | // same thing we do when given a nonzero number that rounds down to 0. |
| 140 | output.ndigits = 0; |
| 141 | output.exponent = -precision - 1; |
| 142 | } else { |
| 143 | // In E mode, generate a string containing the expected number of 0s. |
| 144 | __builtin_memset(output.digits, '0', precision); |
| 145 | output.ndigits = precision; |
| 146 | output.exponent = 0; |
| 147 | } |
| 148 | return output; |
| 149 | } |
| 150 | |
| 151 | // Calculate bounds on log10 of the input value. Its binary exponent bounds |
| 152 | // the value between two powers of 2, and we use estimate_log10 to determine |
| 153 | // log10 of each of those. |
| 154 | // |
| 155 | // If a power of 10 falls in the interval between those powers of 2, then |
| 156 | // log10_input_min and log10_input_max will differ by 1, and the correct |
| 157 | // decimal exponent of the output will be one of those two values. If no |
| 158 | // power of 10 is in the interval, then these two values will be equal and |
| 159 | // there is only one choice for the decimal exponent. |
| 160 | int log10_input_min = estimate_log10(input.exponent - 1); |
| 161 | int log10_input_max = estimate_log10(input.exponent); |
| 162 | |
| 163 | // Make a DyadicFloat containing the value 10, to use as the base for |
| 164 | // exponentiation. |
| 165 | fputil::DyadicFloat<DF_BITS> ten(Sign::POS, 1, 5); |
| 166 | |
| 167 | // Compute the exponent of the lowest-order digit we want as output. In F |
| 168 | // mode this depends only on the desired precision. In E mode it's based on |
| 169 | // log10_input, which is (an estimate of) the exponent corresponding to the |
| 170 | // _high_-order decimal digit of the number. |
| 171 | int log10_low_digit = e_mode ? log10_input_min + 1 - precision : -precision; |
| 172 | |
| 173 | // The general plan is to calculate an integer whose decimal representation |
| 174 | // is precisely the string of output digits, by doing a DyadicFloat |
| 175 | // computation of (input_mantissa / 10^(log10_low_digit)) and then rounding |
| 176 | // that to an integer. |
| 177 | // |
| 178 | // The number of output decimal digits (if the mathematical result of this |
| 179 | // operation were computed without overflow) will be one of these: |
| 180 | // (log10_input_min - log10_low_digit + 1) |
| 181 | // (log10_input_max - log10_low_digit + 1) |
| 182 | // |
| 183 | // In E mode, this means we'll either get the correct number of output digits |
| 184 | // immediately, or else one too many (in which case we can correct for that |
| 185 | // at the rounding stage). But in F mode, if the number is very large |
| 186 | // compared to the number of decimal places the user asked for, we might be |
| 187 | // about to generate far too many digits and overflow our float format. In |
| 188 | // that case, reset to E mode immediately, to avoid having to detect the |
| 189 | // overflow _after_ the multiplication and retry. So if even the smaller |
| 190 | // number of possible output digits is too many, we might as well change our |
| 191 | // mind right now and switch into E mode. |
| 192 | if (log10_input_max - log10_low_digit + 1 > int(MAX_DIGITS)) { |
| 193 | precision = MAX_DIGITS; |
| 194 | e_mode = true; |
| 195 | log10_low_digit = log10_input_min + 1 - precision; |
| 196 | } |
| 197 | |
| 198 | // Now actually calculate (input_mantissa / 10^(log10_low_digit)). |
| 199 | // |
| 200 | // If log10_low_digit < 0, then we calculate 10^(-log10_low_digit) and |
| 201 | // multiply by it instead, so that the exponent is non-negative in all cases. |
| 202 | // This ensures that the power of 10 is always mathematically speaking an |
| 203 | // integer, so that it can be represented exactly in binary (without a |
| 204 | // recurring fraction), and when it's small enough to fit in DF_BITS, |
| 205 | // fputil::pow_n should return the exact answer, and then |
| 206 | // fputil::rounded_{div,mul} will introduce only the unavoidable rounding |
| 207 | // error of up to 1/2 ULP. |
| 208 | // |
| 209 | // Beyond that point, pow_n will be imprecise. But DF_BITS is set high enough |
| 210 | // that even for the most difficult cases in 128-bit long double, the extra |
| 211 | // precision in the calculation is enough to ensure we still get the right |
| 212 | // answer. |
| 213 | // |
| 214 | // If the output integer doesn't fit in DF_BITS, we set the `overflow` flag. |
| 215 | |
| 216 | // Calculate the power of 10 to divide or multiply by. |
| 217 | fputil::DyadicFloat<DF_BITS> power_of_10 = |
| 218 | fputil::pow_n(ten, cpp::abs(log10_low_digit)); |
| 219 | |
| 220 | // Convert the mantissa into a DyadicFloat, making sure it has the right |
| 221 | // sign, so that directed rounding will go in the right direction, if |
| 222 | // enabled. |
| 223 | fputil::DyadicFloat<DF_BITS> flt_mantissa( |
| 224 | input.sign, |
| 225 | input.exponent - |
| 226 | (cpp::numeric_limits<decltype(input.mantissa)>::digits - 1), |
| 227 | input.mantissa); |
| 228 | |
| 229 | // Divide or multiply, depending on whether log10_low_digit was positive |
| 230 | // or negative. |
| 231 | fputil::DyadicFloat<DF_BITS> flt_quotient = |
| 232 | log10_low_digit > 0 ? fputil::rounded_div(flt_mantissa, power_of_10) |
| 233 | : fputil::rounded_mul(flt_mantissa, power_of_10); |
| 234 | |
| 235 | // Convert to an integer. |
| 236 | int round_dir; |
| 237 | UInt<DF_BITS> integer = flt_quotient.as_mantissa_type_rounded(&round_dir); |
| 238 | |
| 239 | // And take the absolute value. |
| 240 | if (flt_quotient.sign.is_neg()) |
| 241 | integer = -integer; |
| 242 | |
| 243 | // Convert the mantissa integer into a string of decimal digits, and check |
| 244 | // to see if it's the right size. |
| 245 | const IntegerToString<decltype(integer), radix::Dec> buf{integer}; |
| 246 | cpp::string_view view = buf.view(); |
| 247 | |
| 248 | // Start making the output struct, by copying in the digits from the above |
| 249 | // object. At this stage we may also have one digit too many (but that's OK, |
| 250 | // there's space for it in the DigitsOutput buffer). |
| 251 | DigitsOutput output; |
| 252 | output.ndigits = view.size(); |
| 253 | __builtin_memcpy(output.digits, view.data(), output.ndigits); |
| 254 | |
| 255 | // Set up the output exponent, which is done differently depending on mode. |
| 256 | // Also, figure out whether we have one digit too many, and if so, set the |
| 257 | // `need_reround` flag and adjust the exponent appropriately. |
| 258 | bool need_reround = false; |
| 259 | if (e_mode) { |
| 260 | // In E mode, the output exponent is the exponent of the first decimal |
| 261 | // digit, which we already calculated. |
| 262 | output.exponent = log10_input_min; |
| 263 | |
| 264 | // In E mode, we're returning a fixed number of digits, given by |
| 265 | // `precision`, so if we have more than that, then we must shorten the |
| 266 | // buffer by one digit. |
| 267 | // |
| 268 | // If this happens, it's because the actual log10 of the input is |
| 269 | // log10_input_min + 1. Equivalently, we guessed we'd see something like |
| 270 | // X.YZe+NN and instead got WX.YZe+NN. So when we shorten the digit string |
| 271 | // by one, we'll also need to increment the output exponent. |
| 272 | if (output.ndigits > size_t(precision)) { |
| 273 | LIBC_ASSERT(output.ndigits == size_t(precision) + 1); |
| 274 | need_reround = true; |
| 275 | output.exponent++; |
| 276 | } |
| 277 | } else { |
| 278 | // In F mode, the output exponent is based on the place value of the _last_ |
| 279 | // digit, so we must recover the exponent of the first digit by adding |
| 280 | // the number of digits. |
| 281 | // |
| 282 | // Because this takes the length of the buffer into account, it sets the |
| 283 | // correct decimal exponent even if this digit string is one too long. So |
| 284 | // we don't need to adjust the exponent if we reround. |
| 285 | output.exponent = int(output.ndigits) - precision - 1; |
| 286 | |
| 287 | // In F mode, the number of returned digits isn't based on `precision`: |
| 288 | // it's variable, and we don't mind how many digits we get as long as it |
| 289 | // isn't beyond the limit MAX_DIGITS. If it is, we expect that it's only |
| 290 | // one digit too long, or else we'd have spotted the problem in advance and |
| 291 | // flipped into E mode already. |
| 292 | if (output.ndigits > MAX_DIGITS) { |
| 293 | LIBC_ASSERT(output.ndigits == MAX_DIGITS + 1); |
| 294 | need_reround = true; |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | if (need_reround) { |
| 299 | // If either of the branches above decided that we had one digit too many, |
| 300 | // we must now shorten the digit buffer by one. But we can't just truncate: |
| 301 | // we need to make sure the remaining n-1 digits are correctly rounded, as |
| 302 | // if we'd rounded just once from the original `flt_quotient`. |
| 303 | // |
| 304 | // In directed rounding modes this can't go wrong. If you had a real number |
| 305 | // x, and the first rounding produced floor(x), then the second rounding |
| 306 | // wants floor(x/10), and it doesn't matter if you actually compute |
| 307 | // floor(floor(x)/10): the result is the same, because each rounding |
| 308 | // boundary in the second rounding aligns with one in the first rounding, |
| 309 | // which nothing could have crossed. Similarly for rounding away from zero, |
| 310 | // with 'floor' replaced with 'ceil' throughout. |
| 311 | // |
| 312 | // In rounding to nearest, the danger is in the boundary case where the |
| 313 | // final digit of the original output is 5. Then if we just rerounded the |
| 314 | // digit string to remove the last digit, it would look like an exact |
| 315 | // halfway case, and we'd break the tie by choosing the even one of the two |
| 316 | // outputs. But if the original value before the first rounding was on one |
| 317 | // side or the other of 5, then that supersedes the 'round to even' tie |
| 318 | // break. So we need to consult `round_dir` from above, which tells us |
| 319 | // which way (if either) the value was adjusted during the first rounding. |
| 320 | // Effectively, we treat the last digit as 5+ε or 5-ε. |
| 321 | // |
| 322 | // To make this work in both directed modes and round-to-nearest mode |
| 323 | // without having to look up the rounding direction, a simple rule is: take |
| 324 | // account of round_dir if and only if the round digit (the one we're |
| 325 | // removing when shortening the buffer) is 5. In directed rounding modes |
| 326 | // this makes no difference. |
| 327 | |
| 328 | // Extract the two relevant digits. round_digit is the one we're removing; |
| 329 | // new_low_digit is the last one we're keeping, so we need to know if it's |
| 330 | // even or odd to handle exact tie cases (when round_dir == 0). |
| 331 | --output.ndigits; |
| 332 | int round_digit = internal::b36_char_to_int(output.digits[output.ndigits]); |
| 333 | int new_low_digit = |
| 334 | output.ndigits == 0 |
| 335 | ? 0 |
| 336 | : internal::b36_char_to_int(output.digits[output.ndigits - 1]); |
| 337 | |
| 338 | // Make a binary number that we can pass to `fputil::rounding_direction`. |
| 339 | // We put new_low_digit at bit 8, and imagine that we're rounding away the |
| 340 | // bottom 8 bits. Therefore round_digit must be "just below" bit 8, in the |
| 341 | // sense that we set the bottom 8 bits to (256/10 * round_digit) so that |
| 342 | // round_digit==5 corresponds to the binary half-way case of 0x80. |
| 343 | // |
| 344 | // Then we adjust by +1 or -1 based on round_dir if the round digit is 5, |
| 345 | // as described above. |
| 346 | // |
| 347 | // The subexpression `(round_digit * 0x19a) >> 4` is computing the |
| 348 | // expression (256/10 * round_digit) mentioned above, accurately enough to |
| 349 | // map 5 to exactly 128 but avoiding an integer division (for platforms |
| 350 | // where it's slow, e.g. not in hardware). |
| 351 | LIBC_NAMESPACE::UInt<64> round_word = (new_low_digit * 256) + |
| 352 | ((round_digit * 0x19a) >> 4) + |
| 353 | (round_digit == 5 ? -round_dir : 0); |
| 354 | |
| 355 | // Now we can call the existing binary rounding helper function, which |
| 356 | // takes account of the rounding mode. |
| 357 | if (fputil::rounding_direction(round_word, 8, flt_quotient.sign) > 0) { |
| 358 | // If that returned a positive answer, we must round the number up. |
| 359 | // |
| 360 | // The number is already in decimal, so we need to increment it one digit |
| 361 | // at a time. (A bit painful, but better than going back to the integer |
| 362 | // we made it from and doing the decimal conversion all over again.) |
| 363 | for (size_t i = output.ndigits; i-- > 0;) { |
| 364 | if (output.digits[i] != '9') { |
| 365 | output.digits[i] = static_cast<char>(internal::int_to_b36_char( |
| 366 | internal::b36_char_to_int(output.digits[i]) + 1)); |
| 367 | break; |
| 368 | } else { |
| 369 | output.digits[i] = '0'; |
| 370 | } |
| 371 | } |
| 372 | } |
| 373 | } |
| 374 | |
| 375 | return output; |
| 376 | } |
| 377 | |
| 378 | template <WriteMode write_mode> |
| 379 | LIBC_INLINE int |
| 380 | convert_float_inner(Writer<write_mode> *writer, const FormatSection &to_conv, |
| 381 | int32_t fraction_len, int exponent, StorageType mantissa, |
| 382 | Sign sign, ConversionType ctype) { |
| 383 | // If to_conv doesn't specify a precision, the precision defaults to 6. |
| 384 | unsigned precision = to_conv.precision < 0 ? 6 : to_conv.precision; |
| 385 | |
| 386 | // Decide if we're displaying a sign character, depending on the format flags |
| 387 | // and whether the input is negative. |
| 388 | char sign_char = 0; |
| 389 | if (sign.is_neg()) |
| 390 | sign_char = '-'; |
| 391 | else if ((to_conv.flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN) |
| 392 | sign_char = '+'; // FORCE_SIGN has precedence over SPACE_PREFIX |
| 393 | else if ((to_conv.flags & FormatFlags::SPACE_PREFIX) == |
| 394 | FormatFlags::SPACE_PREFIX) |
| 395 | sign_char = ' '; |
| 396 | |
| 397 | // Prepare the input to decimal_digits(). |
| 398 | DigitsInput input(fraction_len, mantissa, exponent, sign); |
| 399 | |
| 400 | // Call decimal_digits() in a different way, based on whether the format |
| 401 | // character is 'e', 'f', or 'g'. After this loop we expect to have filled |
| 402 | // in the following variables: |
| 403 | |
| 404 | // The decimal digits, and the exponent of the topmost one. |
| 405 | DigitsOutput output; |
| 406 | // The start and end of the digit string we're displaying, as indices into |
| 407 | // `output.digits`. The indices may be out of bounds in either direction, in |
| 408 | // which case digits beyond the bounds of the buffer should be displayed as |
| 409 | // zeroes. |
| 410 | // |
| 411 | // As usual, the index 'start' is included, and 'limit' is not. |
| 412 | int start, limit; |
| 413 | // The index of the digit that we display a decimal point immediately after. |
| 414 | // Again, represented as an index in `output.digits`, and may be out of |
| 415 | // bounds. |
| 416 | int pointpos; |
| 417 | // Whether we need to display an "e+NNN" exponent suffix at all. |
| 418 | bool show_exponent; |
| 419 | |
| 420 | switch (ctype) { |
| 421 | case ConversionType::E: |
| 422 | // In E mode, we display one digit more than the specified precision |
| 423 | // (`%.6e` means six digits _after_ the decimal point, like 1.123456e+00). |
| 424 | // |
| 425 | // Also, bound the number of digits we request at MAX_DIGITS. |
| 426 | output = decimal_digits(input, cpp::min(precision + 1, MAX_DIGITS), true); |
| 427 | |
| 428 | // We display digits from the start of the buffer, and always output |
| 429 | // `precision+1` of them (which will append zeroes if the user requested |
| 430 | // more than MAX_DIGITS). |
| 431 | start = 0; |
| 432 | limit = precision + 1; |
| 433 | |
| 434 | // The decimal point is always after the first digit of the buffer. |
| 435 | pointpos = start; |
| 436 | |
| 437 | // The exponent is always displayed explicitly. |
| 438 | show_exponent = true; |
| 439 | break; |
| 440 | case ConversionType::F: |
| 441 | // In F mode, we provide decimal_digits() with the unmodified input |
| 442 | // precision, and let it give us as many digits as we can. |
| 443 | output = decimal_digits(input, precision, false); |
| 444 | |
| 445 | // Initialize (start, limit) to display everything from the first nonzero |
| 446 | // digit (necessarily at the start of the output buffer) to the digit at |
| 447 | // the correct distance after the decimal point. |
| 448 | start = 0; |
| 449 | limit = 1 + output.exponent + precision; |
| 450 | |
| 451 | // But we must display at least one digit _before_ the decimal point, i.e. |
| 452 | // at least precision+1 digits in total. So if we're not already doing |
| 453 | // that, we must correct those values. |
| 454 | if (limit <= int(precision)) |
| 455 | start -= precision + 1 - limit; |
| 456 | |
| 457 | // The decimal point appears precisely 'precision' digits before the end of |
| 458 | // the digits we output. |
| 459 | pointpos = limit - 1 - precision; |
| 460 | |
| 461 | // The exponent is never displayed. |
| 462 | show_exponent = false; |
| 463 | break; |
| 464 | case ConversionType::G: |
| 465 | // In G mode, the precision says exactly how many significant digits you |
| 466 | // want. (In that respect it's subtly unlike E mode: %.6g means six digits |
| 467 | // _including_ the one before the point, whereas %.6e means six digits |
| 468 | // _excluding_ that one.) |
| 469 | // |
| 470 | // Also, a precision of 0 is treated the same as 1. |
| 471 | precision = cpp::max(precision, 1u); |
| 472 | output = decimal_digits(input, cpp::min(precision, MAX_DIGITS), true); |
| 473 | |
| 474 | // As in E mode, we default to displaying precisely the digits in the |
| 475 | // output buffer. |
| 476 | start = 0; |
| 477 | limit = precision; |
| 478 | |
| 479 | // If we're not in ALTERNATE_FORM mode, trailing zeroes on the mantissa are |
| 480 | // removed (although not to the extent of leaving no digits at all - if the |
| 481 | // entire output mantissa is all 0 then we keep a single zero digit). |
| 482 | if (!(to_conv.flags & FormatFlags::ALTERNATE_FORM)) { |
| 483 | // Start by removing trailing zeroes that were outside the buffer |
| 484 | // entirely. |
| 485 | limit = cpp::min(limit, int(output.ndigits)); |
| 486 | |
| 487 | // Then check the digits in the buffer and remove as many as possible. |
| 488 | while (limit > 1 && output.digits[limit - 1] == '0') |
| 489 | limit--; |
| 490 | } |
| 491 | |
| 492 | // Decide whether to display in %e style with an explicit exponent, or %f |
| 493 | // style with the decimal point after the units place. |
| 494 | // |
| 495 | // %e mode is used to avoid an excessive number of leading zeroes after the |
| 496 | // decimal point but before the first nonzero digit (specifically, 0.0001 |
| 497 | // is fine as it is, but 0.00001 prints as 1e-5), and also to avoid adding |
| 498 | // trailing zeroes if the last digit in the buffer is still higher than the |
| 499 | // units place. |
| 500 | // |
| 501 | // output.exponent is an int whereas precision is unsigned, so we must |
| 502 | // check output.exponent >= 0 before comparing it against precision to |
| 503 | // prevent a negative exponent from wrapping round to a large unsigned int. |
| 504 | if ((output.exponent >= 0 && output.exponent >= int(precision)) || |
| 505 | output.exponent < -4) { |
| 506 | // Display in %e style, so the point goes after the first digit and the |
| 507 | // exponent is shown. |
| 508 | pointpos = start; |
| 509 | show_exponent = true; |
| 510 | } else { |
| 511 | // Display in %f style, so the point goes at its true mathematical |
| 512 | // location and the exponent is not shown. |
| 513 | pointpos = output.exponent; |
| 514 | show_exponent = false; |
| 515 | |
| 516 | if (output.exponent < 0) { |
| 517 | // If the first digit is below the decimal point, add leading zeroes. |
| 518 | // (This _decreases_ start, because output.exponent is negative here.) |
| 519 | start += output.exponent; |
| 520 | } else if (limit <= output.exponent) { |
| 521 | // If the last digit is above the decimal point, add trailing zeroes. |
| 522 | // (This may involve putting back some zeroes that we trimmed in the |
| 523 | // loop above!) |
| 524 | limit = output.exponent + 1; |
| 525 | } |
| 526 | } |
| 527 | break; |
| 528 | } |
| 529 | |
| 530 | // Find out for sure whether we're displaying the decimal point, so that we |
| 531 | // can include it in the calculation of the total string length for padding. |
| 532 | // |
| 533 | // We never expect pointpos to be _before_ the start of the displayed range |
| 534 | // of digits. (If it had been, we'd have added leading zeroes.) But it might |
| 535 | // be beyond the end. |
| 536 | // |
| 537 | // We don't display the point if it appears immediately after the _last_ |
| 538 | // digit we display, except in ALTERNATE_FORM mode. |
| 539 | int last_point_digit = |
| 540 | (to_conv.flags & FormatFlags::ALTERNATE_FORM) ? limit - 1 : limit - 2; |
| 541 | bool show_point = pointpos <= last_point_digit; |
| 542 | |
| 543 | // Format the exponent suffix (e+NN, e-NN) into a buffer, or leave the buffer |
| 544 | // empty if we're not displaying one. |
| 545 | char expbuf[16]; // more than enough space for e+NNNN |
| 546 | size_t explen = 0; |
| 547 | if (show_exponent) { |
| 548 | const IntegerToString<decltype(output.exponent), |
| 549 | radix::Dec::WithWidth<2>::WithSign> |
| 550 | expcvt{output.exponent}; |
| 551 | cpp::string_view expview = expcvt.view(); |
| 552 | expbuf[0] = internal::islower(to_conv.conv_name) ? 'e' : 'E'; |
| 553 | explen = expview.size() + 1; |
| 554 | __builtin_memcpy(expbuf + 1, expview.data(), expview.size()); |
| 555 | } |
| 556 | |
| 557 | // Now we know enough to work out the length of the unpadded output: |
| 558 | // * whether to write a sign |
| 559 | // * how many mantissa digits to write |
| 560 | // * whether to write a decimal point |
| 561 | // * the length of the trailing exponent string. |
| 562 | size_t unpadded_len = |
| 563 | (sign_char != 0) + (limit - start) + show_point + explen; |
| 564 | |
| 565 | // Work out how much padding is needed. |
| 566 | size_t min_width = to_conv.min_width > 0 ? to_conv.min_width : 0; |
| 567 | size_t padding_amount = cpp::max(min_width, unpadded_len) - unpadded_len; |
| 568 | |
| 569 | // Work out what the padding looks like and where it appears. |
| 570 | enum class Padding { |
| 571 | LeadingSpace, // spaces at the start of the string |
| 572 | Zero, // zeroes between sign and mantissa |
| 573 | TrailingSpace, // spaces at the end of the string |
| 574 | } padding = Padding::LeadingSpace; |
| 575 | // The '-' flag for left-justification takes priority over the '0' flag |
| 576 | if (to_conv.flags & FormatFlags::LEFT_JUSTIFIED) |
| 577 | padding = Padding::TrailingSpace; |
| 578 | else if (to_conv.flags & FormatFlags::LEADING_ZEROES) |
| 579 | padding = Padding::Zero; |
| 580 | |
| 581 | // Finally, write all the output! |
| 582 | |
| 583 | // Leading-space padding, if any |
| 584 | if (padding == Padding::LeadingSpace) |
| 585 | RET_IF_RESULT_NEGATIVE(writer->write(' ', padding_amount)); |
| 586 | |
| 587 | // Sign, if any |
| 588 | if (sign_char) |
| 589 | RET_IF_RESULT_NEGATIVE(writer->write(sign_char)); |
| 590 | |
| 591 | // Zero padding, if any |
| 592 | if (padding == Padding::Zero) |
| 593 | RET_IF_RESULT_NEGATIVE(writer->write('0', padding_amount)); |
| 594 | |
| 595 | // Mantissa digits, maybe with a decimal point |
| 596 | for (int pos = start; pos < limit; ++pos) { |
| 597 | if (pos >= 0 && pos < int(output.ndigits)) { |
| 598 | // Fetch a digit from the buffer |
| 599 | RET_IF_RESULT_NEGATIVE(writer->write(output.digits[pos])); |
| 600 | } else { |
| 601 | // This digit is outside the buffer, so write a zero |
| 602 | RET_IF_RESULT_NEGATIVE(writer->write('0')); |
| 603 | } |
| 604 | |
| 605 | // Show the decimal point, if this is the digit it comes after |
| 606 | if (show_point && pos == pointpos) |
| 607 | RET_IF_RESULT_NEGATIVE(writer->write(DECIMAL_POINT)); |
| 608 | } |
| 609 | |
| 610 | // Exponent |
| 611 | RET_IF_RESULT_NEGATIVE(writer->write(cpp::string_view(expbuf, explen))); |
| 612 | |
| 613 | // Trailing-space padding, if any |
| 614 | if (padding == Padding::TrailingSpace) |
| 615 | RET_IF_RESULT_NEGATIVE(writer->write(' ', padding_amount)); |
| 616 | |
| 617 | return WRITE_OK; |
| 618 | } |
| 619 | |
| 620 | template <typename T, WriteMode write_mode, |
| 621 | cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0> |
| 622 | LIBC_INLINE int |
| 623 | convert_float_typed(Writer<write_mode> *writer, const FormatSection &to_conv, |
| 624 | fputil::FPBits<T> float_bits, ConversionType ctype) { |
| 625 | return convert_float_inner(writer, to_conv, float_bits.FRACTION_LEN, |
| 626 | float_bits.get_explicit_exponent(), |
| 627 | float_bits.get_explicit_mantissa(), |
| 628 | float_bits.sign(), ctype); |
| 629 | } |
| 630 | |
| 631 | template <WriteMode write_mode> |
| 632 | LIBC_INLINE int convert_float_outer(Writer<write_mode> *writer, |
| 633 | const FormatSection &to_conv, |
| 634 | ConversionType ctype) { |
| 635 | if (to_conv.length_modifier == LengthModifier::L) { |
| 636 | fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw; |
| 637 | fputil::FPBits<long double> float_bits(float_raw); |
| 638 | if (!float_bits.is_inf_or_nan()) { |
| 639 | return convert_float_typed<long double>(writer, to_conv, float_bits, |
| 640 | ctype); |
| 641 | } |
| 642 | } else { |
| 643 | fputil::FPBits<double>::StorageType float_raw = |
| 644 | static_cast<fputil::FPBits<double>::StorageType>(to_conv.conv_val_raw); |
| 645 | fputil::FPBits<double> float_bits(float_raw); |
| 646 | if (!float_bits.is_inf_or_nan()) { |
| 647 | return convert_float_typed<double>(writer, to_conv, float_bits, ctype); |
| 648 | } |
| 649 | } |
| 650 | |
| 651 | return convert_inf_nan(writer, to_conv); |
| 652 | } |
| 653 | |
| 654 | template <typename T, WriteMode write_mode, |
| 655 | cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0> |
| 656 | LIBC_INLINE int convert_float_decimal_typed(Writer<write_mode> *writer, |
| 657 | const FormatSection &to_conv, |
| 658 | fputil::FPBits<T> float_bits) { |
| 659 | return convert_float_typed<T>(writer, to_conv, float_bits, ConversionType::F); |
| 660 | } |
| 661 | |
| 662 | template <typename T, WriteMode write_mode, |
| 663 | cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0> |
| 664 | LIBC_INLINE int convert_float_dec_exp_typed(Writer<write_mode> *writer, |
| 665 | const FormatSection &to_conv, |
| 666 | fputil::FPBits<T> float_bits) { |
| 667 | return convert_float_typed<T>(writer, to_conv, float_bits, ConversionType::E); |
| 668 | } |
| 669 | |
| 670 | template <typename T, WriteMode write_mode, |
| 671 | cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0> |
| 672 | LIBC_INLINE int convert_float_dec_auto_typed(Writer<write_mode> *writer, |
| 673 | const FormatSection &to_conv, |
| 674 | fputil::FPBits<T> float_bits) { |
| 675 | return convert_float_typed<T>(writer, to_conv, float_bits, ConversionType::G); |
| 676 | } |
| 677 | |
| 678 | template <WriteMode write_mode> |
| 679 | LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer, |
| 680 | const FormatSection &to_conv) { |
| 681 | return convert_float_outer(writer, to_conv, ConversionType::F); |
| 682 | } |
| 683 | |
| 684 | template <WriteMode write_mode> |
| 685 | LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer, |
| 686 | const FormatSection &to_conv) { |
| 687 | return convert_float_outer(writer, to_conv, ConversionType::E); |
| 688 | } |
| 689 | |
| 690 | template <WriteMode write_mode> |
| 691 | LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> *writer, |
| 692 | const FormatSection &to_conv) { |
| 693 | return convert_float_outer(writer, to_conv, ConversionType::G); |
| 694 | } |
| 695 | |
| 696 | } // namespace printf_core |
| 697 | } // namespace LIBC_NAMESPACE_DECL |
| 698 | |
| 699 | #endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_LIMITED_H |
| 700 |
Warning: This file is not a C or C++ file. It does not have highlighting.
