Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / src / include / to_chars_floating_point.h
blobe2409338b9d1d72b148997e1e9cc87edecd6ce88
1 //===----------------------------------------------------------------------===//
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 // Copyright (c) Microsoft Corporation.
10 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12 // This implementation is dedicated to the memory of Mary and Thavatchai.
14 #ifndef _LIBCPP_SRC_INCLUDE_TO_CHARS_FLOATING_POINT_H
15 #define _LIBCPP_SRC_INCLUDE_TO_CHARS_FLOATING_POINT_H
17 // Avoid formatting to keep the changes with the original code minimal.
18 // clang-format off
20 #include <__algorithm/find.h>
21 #include <__algorithm/find_if.h>
22 #include <__algorithm/lower_bound.h>
23 #include <__algorithm/min.h>
24 #include <__assert>
25 #include <__config>
26 #include <__functional/operations.h>
27 #include <__iterator/access.h>
28 #include <__iterator/size.h>
29 #include <bit>
30 #include <cfloat>
31 #include <climits>
33 #include "include/ryu/ryu.h"
35 _LIBCPP_BEGIN_NAMESPACE_STD
37 namespace __itoa {
38 inline constexpr char _Charconv_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
39 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
40 static_assert(_VSTD::size(_Charconv_digits) == 36);
41 } // __itoa
43 // vvvvvvvvvv DERIVED FROM corecrt_internal_fltintrn.h vvvvvvvvvv
45 template <class _FloatingType>
46 struct _Floating_type_traits;
48 template <>
49 struct _Floating_type_traits<float> {
50 static constexpr int32_t _Mantissa_bits = FLT_MANT_DIG;
51 static constexpr int32_t _Exponent_bits = sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
53 static constexpr int32_t _Maximum_binary_exponent = FLT_MAX_EXP - 1;
54 static constexpr int32_t _Minimum_binary_exponent = FLT_MIN_EXP - 1;
56 static constexpr int32_t _Exponent_bias = 127;
58 static constexpr int32_t _Sign_shift = _Exponent_bits + _Mantissa_bits - 1;
59 static constexpr int32_t _Exponent_shift = _Mantissa_bits - 1;
61 using _Uint_type = uint32_t;
63 static constexpr uint32_t _Exponent_mask = (1u << _Exponent_bits) - 1;
64 static constexpr uint32_t _Normal_mantissa_mask = (1u << _Mantissa_bits) - 1;
65 static constexpr uint32_t _Denormal_mantissa_mask = (1u << (_Mantissa_bits - 1)) - 1;
66 static constexpr uint32_t _Special_nan_mantissa_mask = 1u << (_Mantissa_bits - 2);
67 static constexpr uint32_t _Shifted_sign_mask = 1u << _Sign_shift;
68 static constexpr uint32_t _Shifted_exponent_mask = _Exponent_mask << _Exponent_shift;
71 template <>
72 struct _Floating_type_traits<double> {
73 static constexpr int32_t _Mantissa_bits = DBL_MANT_DIG;
74 static constexpr int32_t _Exponent_bits = sizeof(double) * CHAR_BIT - DBL_MANT_DIG;
76 static constexpr int32_t _Maximum_binary_exponent = DBL_MAX_EXP - 1;
77 static constexpr int32_t _Minimum_binary_exponent = DBL_MIN_EXP - 1;
79 static constexpr int32_t _Exponent_bias = 1023;
81 static constexpr int32_t _Sign_shift = _Exponent_bits + _Mantissa_bits - 1;
82 static constexpr int32_t _Exponent_shift = _Mantissa_bits - 1;
84 using _Uint_type = uint64_t;
86 static constexpr uint64_t _Exponent_mask = (1ULL << _Exponent_bits) - 1;
87 static constexpr uint64_t _Normal_mantissa_mask = (1ULL << _Mantissa_bits) - 1;
88 static constexpr uint64_t _Denormal_mantissa_mask = (1ULL << (_Mantissa_bits - 1)) - 1;
89 static constexpr uint64_t _Special_nan_mantissa_mask = 1ULL << (_Mantissa_bits - 2);
90 static constexpr uint64_t _Shifted_sign_mask = 1ULL << _Sign_shift;
91 static constexpr uint64_t _Shifted_exponent_mask = _Exponent_mask << _Exponent_shift;
94 // ^^^^^^^^^^ DERIVED FROM corecrt_internal_fltintrn.h ^^^^^^^^^^
96 // FUNCTION to_chars (FLOATING-POINT TO STRING)
97 template <class _Floating>
98 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
99 to_chars_result _Floating_to_chars_hex_precision(
100 char* _First, char* const _Last, const _Floating _Value, int _Precision) noexcept {
102 // * Determine the effective _Precision.
103 // * Later, we'll decrement _Precision when printing each hexit after the decimal point.
105 // The hexits after the decimal point correspond to the explicitly stored fraction bits.
106 // float explicitly stores 23 fraction bits. 23 / 4 == 5.75, which is 6 hexits.
107 // double explicitly stores 52 fraction bits. 52 / 4 == 13, which is 13 hexits.
108 constexpr int _Full_precision = _IsSame<_Floating, float>::value ? 6 : 13;
109 constexpr int _Adjusted_explicit_bits = _Full_precision * 4;
111 if (_Precision < 0) {
112 // C11 7.21.6.1 "The fprintf function"/5: "A negative precision argument is taken as if the precision were
113 // omitted." /8: "if the precision is missing and FLT_RADIX is a power of 2, then the precision is sufficient
114 // for an exact representation of the value"
115 _Precision = _Full_precision;
118 // * Extract the _Ieee_mantissa and _Ieee_exponent.
119 using _Traits = _Floating_type_traits<_Floating>;
120 using _Uint_type = typename _Traits::_Uint_type;
122 const _Uint_type _Uint_value = _VSTD::bit_cast<_Uint_type>(_Value);
123 const _Uint_type _Ieee_mantissa = _Uint_value & _Traits::_Denormal_mantissa_mask;
124 const int32_t _Ieee_exponent = static_cast<int32_t>(_Uint_value >> _Traits::_Exponent_shift);
126 // * Prepare the _Adjusted_mantissa. This is aligned to hexit boundaries,
127 // * with the implicit bit restored (0 for zero values and subnormal values, 1 for normal values).
128 // * Also calculate the _Unbiased_exponent. This unifies the processing of zero, subnormal, and normal values.
129 _Uint_type _Adjusted_mantissa;
131 if constexpr (_IsSame<_Floating, float>::value) {
132 _Adjusted_mantissa = _Ieee_mantissa << 1; // align to hexit boundary (23 isn't divisible by 4)
133 } else {
134 _Adjusted_mantissa = _Ieee_mantissa; // already aligned (52 is divisible by 4)
137 int32_t _Unbiased_exponent;
139 if (_Ieee_exponent == 0) { // zero or subnormal
140 // implicit bit is 0
142 if (_Ieee_mantissa == 0) { // zero
143 // C11 7.21.6.1 "The fprintf function"/8: "If the value is zero, the exponent is zero."
144 _Unbiased_exponent = 0;
145 } else { // subnormal
146 _Unbiased_exponent = 1 - _Traits::_Exponent_bias;
148 } else { // normal
149 _Adjusted_mantissa |= _Uint_type{1} << _Adjusted_explicit_bits; // implicit bit is 1
150 _Unbiased_exponent = _Ieee_exponent - _Traits::_Exponent_bias;
153 // _Unbiased_exponent is within [-126, 127] for float, [-1022, 1023] for double.
155 // * Decompose _Unbiased_exponent into _Sign_character and _Absolute_exponent.
156 char _Sign_character;
157 uint32_t _Absolute_exponent;
159 if (_Unbiased_exponent < 0) {
160 _Sign_character = '-';
161 _Absolute_exponent = static_cast<uint32_t>(-_Unbiased_exponent);
162 } else {
163 _Sign_character = '+';
164 _Absolute_exponent = static_cast<uint32_t>(_Unbiased_exponent);
167 // _Absolute_exponent is within [0, 127] for float, [0, 1023] for double.
169 // * Perform a single bounds check.
171 int32_t _Exponent_length;
173 if (_Absolute_exponent < 10) {
174 _Exponent_length = 1;
175 } else if (_Absolute_exponent < 100) {
176 _Exponent_length = 2;
177 } else if constexpr (_IsSame<_Floating, float>::value) {
178 _Exponent_length = 3;
179 } else if (_Absolute_exponent < 1000) {
180 _Exponent_length = 3;
181 } else {
182 _Exponent_length = 4;
185 // _Precision might be enormous; avoid integer overflow by testing it separately.
186 ptrdiff_t _Buffer_size = _Last - _First;
188 if (_Buffer_size < _Precision) {
189 return {_Last, errc::value_too_large};
192 _Buffer_size -= _Precision;
194 const int32_t _Length_excluding_precision = 1 // leading hexit
195 + static_cast<int32_t>(_Precision > 0) // possible decimal point
196 // excluding `+ _Precision`, hexits after decimal point
197 + 2 // "p+" or "p-"
198 + _Exponent_length; // exponent
200 if (_Buffer_size < _Length_excluding_precision) {
201 return {_Last, errc::value_too_large};
205 // * Perform rounding when we've been asked to omit hexits.
206 if (_Precision < _Full_precision) {
207 // _Precision is within [0, 5] for float, [0, 12] for double.
209 // _Dropped_bits is within [4, 24] for float, [4, 52] for double.
210 const int _Dropped_bits = (_Full_precision - _Precision) * 4;
212 // Perform rounding by adding an appropriately-shifted bit.
214 // This can propagate carries all the way into the leading hexit. Examples:
215 // "0.ff9" rounded to a precision of 2 is "1.00".
216 // "1.ff9" rounded to a precision of 2 is "2.00".
218 // Note that the leading hexit participates in the rounding decision. Examples:
219 // "0.8" rounded to a precision of 0 is "0".
220 // "1.8" rounded to a precision of 0 is "2".
222 // Reference implementation with suboptimal codegen:
223 // bool _Should_round_up(bool _Lsb_bit, bool _Round_bit, bool _Has_tail_bits) {
224 // // If there are no insignificant set bits, the value is exactly-representable and should not be rounded.
225 // //
226 // // If there are insignificant set bits, we need to round according to round_to_nearest.
227 // // We need to handle two cases: we round up if either [1] the value is slightly greater
228 // // than the midpoint between two exactly-representable values or [2] the value is exactly the midpoint
229 // // between two exactly-representable values and the greater of the two is even (this is "round-to-even").
230 // return _Round_bit && (_Has_tail_bits || _Lsb_bit);
232 // const bool _Lsb_bit = (_Adjusted_mantissa & (_Uint_type{1} << _Dropped_bits)) != 0;
233 // const bool _Round_bit = (_Adjusted_mantissa & (_Uint_type{1} << (_Dropped_bits - 1))) != 0;
234 // const bool _Has_tail_bits = (_Adjusted_mantissa & ((_Uint_type{1} << (_Dropped_bits - 1)) - 1)) != 0;
235 // const bool _Should_round = _Should_round_up(_Lsb_bit, _Round_bit, _Has_tail_bits);
236 // _Adjusted_mantissa += _Uint_type{_Should_round} << _Dropped_bits;
238 // Example for optimized implementation: Let _Dropped_bits be 8.
239 // Bit index: ...[8]76543210
240 // _Adjusted_mantissa: ...[L]RTTTTTTT (not depicting known details, like hexit alignment)
241 // By focusing on the bit at index _Dropped_bits, we can avoid unnecessary branching and shifting.
243 // Bit index: ...[8]76543210
244 // _Lsb_bit: ...[L]RTTTTTTT
245 const _Uint_type _Lsb_bit = _Adjusted_mantissa;
247 // Bit index: ...9[8]76543210
248 // _Round_bit: ...L[R]TTTTTTT0
249 const _Uint_type _Round_bit = _Adjusted_mantissa << 1;
251 // We can detect (without branching) whether any of the trailing bits are set.
252 // Due to _Should_round below, this computation will be used if and only if R is 1, so we can assume that here.
253 // Bit index: ...9[8]76543210
254 // _Round_bit: ...L[1]TTTTTTT0
255 // _Has_tail_bits: ....[H]........
257 // If all of the trailing bits T are 0, then `_Round_bit - 1` will produce 0 for H (due to R being 1).
258 // If any of the trailing bits T are 1, then `_Round_bit - 1` will produce 1 for H (due to R being 1).
259 const _Uint_type _Has_tail_bits = _Round_bit - 1;
261 // Finally, we can use _Should_round_up() logic with bitwise-AND and bitwise-OR,
262 // selecting just the bit at index _Dropped_bits. This is the appropriately-shifted bit that we want.
263 const _Uint_type _Should_round = _Round_bit & (_Has_tail_bits | _Lsb_bit) & (_Uint_type{1} << _Dropped_bits);
265 // This rounding technique is dedicated to the memory of Peppermint. =^..^=
266 _Adjusted_mantissa += _Should_round;
269 // * Print the leading hexit, then mask it away.
271 const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Adjusted_explicit_bits);
272 _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 3, "");
273 const char _Leading_hexit = static_cast<char>('0' + _Nibble);
275 *_First++ = _Leading_hexit;
277 constexpr _Uint_type _Mask = (_Uint_type{1} << _Adjusted_explicit_bits) - 1;
278 _Adjusted_mantissa &= _Mask;
281 // * Print the decimal point and trailing hexits.
283 // C11 7.21.6.1 "The fprintf function"/8:
284 // "if the precision is zero and the # flag is not specified, no decimal-point character appears."
285 if (_Precision > 0) {
286 *_First++ = '.';
288 int32_t _Number_of_bits_remaining = _Adjusted_explicit_bits; // 24 for float, 52 for double
290 for (;;) {
291 _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
292 _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, "");
293 _Number_of_bits_remaining -= 4;
295 const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining);
296 _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, "");
297 const char _Hexit = __itoa::_Charconv_digits[_Nibble];
299 *_First++ = _Hexit;
301 // _Precision is the number of hexits that still need to be printed.
302 --_Precision;
303 if (_Precision == 0) {
304 break; // We're completely done with this phase.
306 // Otherwise, we need to keep printing hexits.
308 if (_Number_of_bits_remaining == 0) {
309 // We've finished printing _Adjusted_mantissa, so all remaining hexits are '0'.
310 _VSTD::memset(_First, '0', static_cast<size_t>(_Precision));
311 _First += _Precision;
312 break;
315 // Mask away the hexit that we just printed, then keep looping.
316 // (We skip this when breaking out of the loop above, because _Adjusted_mantissa isn't used later.)
317 const _Uint_type _Mask = (_Uint_type{1} << _Number_of_bits_remaining) - 1;
318 _Adjusted_mantissa &= _Mask;
322 // * Print the exponent.
324 // C11 7.21.6.1 "The fprintf function"/8: "The exponent always contains at least one digit, and only as many more
325 // digits as necessary to represent the decimal exponent of 2."
327 // Performance note: We should take advantage of the known ranges of possible exponents.
329 *_First++ = 'p';
330 *_First++ = _Sign_character;
332 // We've already printed '-' if necessary, so uint32_t _Absolute_exponent avoids testing that again.
333 return _VSTD::to_chars(_First, _Last, _Absolute_exponent);
336 template <class _Floating>
337 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
338 to_chars_result _Floating_to_chars_hex_shortest(
339 char* _First, char* const _Last, const _Floating _Value) noexcept {
341 // This prints "1.728p+0" instead of "2.e5p-1".
342 // This prints "0.000002p-126" instead of "1p-149" for float.
343 // This prints "0.0000000000001p-1022" instead of "1p-1074" for double.
344 // This prioritizes being consistent with printf's de facto behavior (and hex-precision's behavior)
345 // over minimizing the number of characters printed.
347 using _Traits = _Floating_type_traits<_Floating>;
348 using _Uint_type = typename _Traits::_Uint_type;
350 const _Uint_type _Uint_value = _VSTD::bit_cast<_Uint_type>(_Value);
352 if (_Uint_value == 0) { // zero detected; write "0p+0" and return
353 // C11 7.21.6.1 "The fprintf function"/8: "If the value is zero, the exponent is zero."
354 // Special-casing zero is necessary because of the exponent.
355 const char* const _Str = "0p+0";
356 const size_t _Len = 4;
358 if (_Last - _First < static_cast<ptrdiff_t>(_Len)) {
359 return {_Last, errc::value_too_large};
362 _VSTD::memcpy(_First, _Str, _Len);
364 return {_First + _Len, errc{}};
367 const _Uint_type _Ieee_mantissa = _Uint_value & _Traits::_Denormal_mantissa_mask;
368 const int32_t _Ieee_exponent = static_cast<int32_t>(_Uint_value >> _Traits::_Exponent_shift);
370 char _Leading_hexit; // implicit bit
371 int32_t _Unbiased_exponent;
373 if (_Ieee_exponent == 0) { // subnormal
374 _Leading_hexit = '0';
375 _Unbiased_exponent = 1 - _Traits::_Exponent_bias;
376 } else { // normal
377 _Leading_hexit = '1';
378 _Unbiased_exponent = _Ieee_exponent - _Traits::_Exponent_bias;
381 // Performance note: Consider avoiding per-character bounds checking when there's plenty of space.
383 if (_First == _Last) {
384 return {_Last, errc::value_too_large};
387 *_First++ = _Leading_hexit;
389 if (_Ieee_mantissa == 0) {
390 // The fraction bits are all 0. Trim them away, including the decimal point.
391 } else {
392 if (_First == _Last) {
393 return {_Last, errc::value_too_large};
396 *_First++ = '.';
398 // The hexits after the decimal point correspond to the explicitly stored fraction bits.
399 // float explicitly stores 23 fraction bits. 23 / 4 == 5.75, so we'll print at most 6 hexits.
400 // double explicitly stores 52 fraction bits. 52 / 4 == 13, so we'll print at most 13 hexits.
401 _Uint_type _Adjusted_mantissa;
402 int32_t _Number_of_bits_remaining;
404 if constexpr (_IsSame<_Floating, float>::value) {
405 _Adjusted_mantissa = _Ieee_mantissa << 1; // align to hexit boundary (23 isn't divisible by 4)
406 _Number_of_bits_remaining = 24; // 23 fraction bits + 1 alignment bit
407 } else {
408 _Adjusted_mantissa = _Ieee_mantissa; // already aligned (52 is divisible by 4)
409 _Number_of_bits_remaining = 52; // 52 fraction bits
412 // do-while: The condition _Adjusted_mantissa != 0 is initially true - we have nonzero fraction bits and we've
413 // printed the decimal point. Each iteration, we print a hexit, mask it away, and keep looping if we still have
414 // nonzero fraction bits. If there would be trailing '0' hexits, this trims them. If there wouldn't be trailing
415 // '0' hexits, the same condition works (as we print the final hexit and mask it away); we don't need to test
416 // _Number_of_bits_remaining.
417 do {
418 _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
419 _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, "");
420 _Number_of_bits_remaining -= 4;
422 const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining);
423 _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, "");
424 const char _Hexit = __itoa::_Charconv_digits[_Nibble];
426 if (_First == _Last) {
427 return {_Last, errc::value_too_large};
430 *_First++ = _Hexit;
432 const _Uint_type _Mask = (_Uint_type{1} << _Number_of_bits_remaining) - 1;
433 _Adjusted_mantissa &= _Mask;
435 } while (_Adjusted_mantissa != 0);
438 // C11 7.21.6.1 "The fprintf function"/8: "The exponent always contains at least one digit, and only as many more
439 // digits as necessary to represent the decimal exponent of 2."
441 // Performance note: We should take advantage of the known ranges of possible exponents.
443 // float: _Unbiased_exponent is within [-126, 127].
444 // double: _Unbiased_exponent is within [-1022, 1023].
446 if (_Last - _First < 2) {
447 return {_Last, errc::value_too_large};
450 *_First++ = 'p';
452 if (_Unbiased_exponent < 0) {
453 *_First++ = '-';
454 _Unbiased_exponent = -_Unbiased_exponent;
455 } else {
456 *_First++ = '+';
459 // We've already printed '-' if necessary, so static_cast<uint32_t> avoids testing that again.
460 return _VSTD::to_chars(_First, _Last, static_cast<uint32_t>(_Unbiased_exponent));
463 // For general precision, we can use lookup tables to avoid performing trial formatting.
465 // For a simple example, imagine counting the number of digits D in an integer, and needing to know
466 // whether D is less than 3, equal to 3/4/5/6, or greater than 6. We could use a lookup table:
467 // D | Largest integer with D digits
468 // 2 | 99
469 // 3 | 999
470 // 4 | 9'999
471 // 5 | 99'999
472 // 6 | 999'999
473 // 7 | table end
474 // Looking up an integer in this table with lower_bound() will work:
475 // * Too-small integers, like 7, 70, and 99, will cause lower_bound() to return the D == 2 row. (If all we care
476 // about is whether D is less than 3, then it's okay to smash the D == 1 and D == 2 cases together.)
477 // * Integers in [100, 999] will cause lower_bound() to return the D == 3 row, and so forth.
478 // * Too-large integers, like 1'000'000 and above, will cause lower_bound() to return the end of the table. If we
479 // compute D from that index, this will be considered D == 7, which will activate any "greater than 6" logic.
481 // Floating-point is slightly more complicated.
483 // The ordinary lookup tables are for X within [-5, 38] for float, and [-5, 308] for double.
484 // (-5 absorbs too-negative exponents, outside the P > X >= -4 criterion. 38 and 308 are the maximum exponents.)
485 // Due to the P > X condition, we can use a subset of the table for X within [-5, P - 1], suitably clamped.
487 // When P is small, rounding can affect X. For example:
488 // For P == 1, the largest double with X == 0 is: 9.4999999999999982236431605997495353221893310546875
489 // For P == 2, the largest double with X == 0 is: 9.949999999999999289457264239899814128875732421875
490 // For P == 3, the largest double with X == 0 is: 9.9949999999999992184029906638897955417633056640625
492 // Exponent adjustment is a concern for P within [1, 7] for float, and [1, 15] for double (determined via
493 // brute force). While larger values of P still perform rounding, they can't trigger exponent adjustment.
494 // This is because only values with repeated '9' digits can undergo exponent adjustment during rounding,
495 // and floating-point granularity limits the number of consecutive '9' digits that can appear.
497 // So, we need special lookup tables for small values of P.
498 // These tables have varying lengths due to the P > X >= -4 criterion. For example:
499 // For P == 1, need table entries for X: -5, -4, -3, -2, -1, 0
500 // For P == 2, need table entries for X: -5, -4, -3, -2, -1, 0, 1
501 // For P == 3, need table entries for X: -5, -4, -3, -2, -1, 0, 1, 2
502 // For P == 4, need table entries for X: -5, -4, -3, -2, -1, 0, 1, 2, 3
504 // We can concatenate these tables for compact storage, using triangular numbers to access them.
505 // The table for P begins at index (P - 1) * (P + 10) / 2 with length P + 5.
507 // For both the ordinary and special lookup tables, after an index I is returned by lower_bound(), X is I - 5.
509 // We need to special-case the floating-point value 0.0, which is considered to have X == 0.
510 // Otherwise, the lookup tables would consider it to have a highly negative X.
512 // Finally, because we're working with positive floating-point values,
513 // representation comparisons behave identically to floating-point comparisons.
515 // The following code generated the lookup tables for the scientific exponent X. Don't remove this code.
516 #if 0
517 // cl /EHsc /nologo /W4 /MT /O2 /std:c++17 generate_tables.cpp && generate_tables
519 #include <algorithm>
520 #include <assert.h>
521 #include <charconv>
522 #include <cmath>
523 #include <limits>
524 #include <map>
525 #include <stdint.h>
526 #include <stdio.h>
527 #include <system_error>
528 #include <type_traits>
529 #include <vector>
530 using namespace std;
532 template <typename UInt, typename Pred>
533 [[nodiscard]] UInt uint_partition_point(UInt first, const UInt last, Pred pred) {
534 // Find the beginning of the false partition in [first, last).
535 // [first, last) is partitioned when all of the true values occur before all of the false values.
537 static_assert(is_unsigned_v<UInt>);
538 assert(first <= last);
540 for (UInt n = last - first; n > 0;) {
541 const UInt n2 = n / 2;
542 const UInt mid = first + n2;
544 if (pred(mid)) {
545 first = mid + 1;
546 n = n - n2 - 1;
547 } else {
548 n = n2;
552 return first;
555 template <typename Floating>
556 [[nodiscard]] int scientific_exponent_X(const int P, const Floating flt) {
557 char buf[400]; // more than enough
559 // C11 7.21.6.1 "The fprintf function"/8 performs trial formatting with scientific precision P - 1.
560 const auto to_result = to_chars(buf, end(buf), flt, chars_format::scientific, P - 1);
561 assert(to_result.ec == errc{});
563 const char* exp_ptr = find(buf, to_result.ptr, 'e');
564 assert(exp_ptr != to_result.ptr);
566 ++exp_ptr; // advance past 'e'
568 if (*exp_ptr == '+') {
569 ++exp_ptr; // advance past '+' which from_chars() won't parse
572 int X;
573 const auto from_result = from_chars(exp_ptr, to_result.ptr, X);
574 assert(from_result.ec == errc{});
575 return X;
578 template <typename UInt>
579 void print_table(const vector<UInt>& v, const char* const name) {
580 constexpr const char* UIntName = _IsSame<UInt, uint32_t>::value ? "uint32_t" : "uint64_t";
582 printf("static constexpr %s %s[%zu] = {\n", UIntName, name, v.size());
584 for (const auto& val : v) {
585 if constexpr (_IsSame<UInt, uint32_t>::value) {
586 printf("0x%08Xu,\n", val);
587 } else {
588 printf("0x%016llXu,\n", val);
592 printf("};\n");
595 enum class Mode { Tables, Tests };
597 template <typename Floating>
598 void generate_tables(const Mode mode) {
599 using Limits = numeric_limits<Floating>;
600 using UInt = conditional_t<_IsSame<Floating, float>::value, uint32_t, uint64_t>;
602 map<int, map<int, UInt>> P_X_LargestValWithX;
604 constexpr int MaxP = Limits::max_exponent10 + 1; // MaxP performs no rounding during trial formatting
606 for (int P = 1; P <= MaxP; ++P) {
607 for (int X = -5; X < P; ++X) {
608 constexpr Floating first = static_cast<Floating>(9e-5); // well below 9.5e-5, otherwise arbitrary
609 constexpr Floating last = Limits::infinity(); // one bit above Limits::max()
611 const UInt val_beyond_X = uint_partition_point(reinterpret_cast<const UInt&>(first),
612 reinterpret_cast<const UInt&>(last),
613 [P, X](const UInt u) { return scientific_exponent_X(P, reinterpret_cast<const Floating&>(u)) <= X; });
615 P_X_LargestValWithX[P][X] = val_beyond_X - 1;
619 constexpr const char* FloatingName = _IsSame<Floating, float>::value ? "float" : "double";
621 constexpr int MaxSpecialP = _IsSame<Floating, float>::value ? 7 : 15; // MaxSpecialP is affected by exponent adjustment
623 if (mode == Mode::Tables) {
624 printf("template <>\n");
625 printf("struct _General_precision_tables<%s> {\n", FloatingName);
627 printf("static constexpr int _Max_special_P = %d;\n", MaxSpecialP);
629 vector<UInt> special;
631 for (int P = 1; P <= MaxSpecialP; ++P) {
632 for (int X = -5; X < P; ++X) {
633 const UInt val = P_X_LargestValWithX[P][X];
634 special.push_back(val);
638 print_table(special, "_Special_X_table");
640 for (int P = MaxSpecialP + 1; P < MaxP; ++P) {
641 for (int X = -5; X < P; ++X) {
642 const UInt val = P_X_LargestValWithX[P][X];
643 assert(val == P_X_LargestValWithX[MaxP][X]);
647 printf("static constexpr int _Max_P = %d;\n", MaxP);
649 vector<UInt> ordinary;
651 for (int X = -5; X < MaxP; ++X) {
652 const UInt val = P_X_LargestValWithX[MaxP][X];
653 ordinary.push_back(val);
656 print_table(ordinary, "_Ordinary_X_table");
658 printf("};\n");
659 } else {
660 printf("==========\n");
661 printf("Test cases for %s:\n", FloatingName);
663 constexpr int Hexits = _IsSame<Floating, float>::value ? 6 : 13;
664 constexpr const char* Suffix = _IsSame<Floating, float>::value ? "f" : "";
666 for (int P = 1; P <= MaxP; ++P) {
667 for (int X = -5; X < P; ++X) {
668 if (P <= MaxSpecialP || P == 25 || P == MaxP || X == P - 1) {
669 const UInt val1 = P_X_LargestValWithX[P][X];
670 const Floating f1 = reinterpret_cast<const Floating&>(val1);
671 const UInt val2 = val1 + 1;
672 const Floating f2 = reinterpret_cast<const Floating&>(val2);
674 printf("{%.*a%s, chars_format::general, %d, \"%.*g\"},\n", Hexits, f1, Suffix, P, P, f1);
675 if (isfinite(f2)) {
676 printf("{%.*a%s, chars_format::general, %d, \"%.*g\"},\n", Hexits, f2, Suffix, P, P, f2);
684 int main() {
685 printf("template <class _Floating>\n");
686 printf("struct _General_precision_tables;\n");
687 generate_tables<float>(Mode::Tables);
688 generate_tables<double>(Mode::Tables);
689 generate_tables<float>(Mode::Tests);
690 generate_tables<double>(Mode::Tests);
692 #endif // 0
694 template <class _Floating>
695 struct _General_precision_tables;
697 template <>
698 struct _General_precision_tables<float> {
699 static constexpr int _Max_special_P = 7;
701 static constexpr uint32_t _Special_X_table[63] = {0x38C73ABCu, 0x3A79096Bu, 0x3C1BA5E3u, 0x3DC28F5Cu, 0x3F733333u,
702 0x4117FFFFu, 0x38D0AAA7u, 0x3A826AA8u, 0x3C230553u, 0x3DCBC6A7u, 0x3F7EB851u, 0x411F3333u, 0x42C6FFFFu,
703 0x38D19C3Fu, 0x3A8301A7u, 0x3C23C211u, 0x3DCCB295u, 0x3F7FDF3Bu, 0x411FEB85u, 0x42C7E666u, 0x4479DFFFu,
704 0x38D1B468u, 0x3A8310C1u, 0x3C23D4F1u, 0x3DCCCA2Du, 0x3F7FFCB9u, 0x411FFDF3u, 0x42C7FD70u, 0x4479FCCCu,
705 0x461C3DFFu, 0x38D1B6D2u, 0x3A831243u, 0x3C23D6D4u, 0x3DCCCC89u, 0x3F7FFFACu, 0x411FFFCBu, 0x42C7FFBEu,
706 0x4479FFAEu, 0x461C3FCCu, 0x47C34FBFu, 0x38D1B710u, 0x3A83126Au, 0x3C23D704u, 0x3DCCCCC6u, 0x3F7FFFF7u,
707 0x411FFFFAu, 0x42C7FFF9u, 0x4479FFF7u, 0x461C3FFAu, 0x47C34FF9u, 0x497423F7u, 0x38D1B716u, 0x3A83126Eu,
708 0x3C23D709u, 0x3DCCCCCCu, 0x3F7FFFFFu, 0x411FFFFFu, 0x42C7FFFFu, 0x4479FFFFu, 0x461C3FFFu, 0x47C34FFFu,
709 0x497423FFu, 0x4B18967Fu};
711 static constexpr int _Max_P = 39;
713 static constexpr uint32_t _Ordinary_X_table[44] = {0x38D1B717u, 0x3A83126Eu, 0x3C23D70Au, 0x3DCCCCCCu, 0x3F7FFFFFu,
714 0x411FFFFFu, 0x42C7FFFFu, 0x4479FFFFu, 0x461C3FFFu, 0x47C34FFFu, 0x497423FFu, 0x4B18967Fu, 0x4CBEBC1Fu,
715 0x4E6E6B27u, 0x501502F8u, 0x51BA43B7u, 0x5368D4A5u, 0x551184E7u, 0x56B5E620u, 0x58635FA9u, 0x5A0E1BC9u,
716 0x5BB1A2BCu, 0x5D5E0B6Bu, 0x5F0AC723u, 0x60AD78EBu, 0x6258D726u, 0x64078678u, 0x65A96816u, 0x6753C21Bu,
717 0x69045951u, 0x6AA56FA5u, 0x6C4ECB8Fu, 0x6E013F39u, 0x6FA18F07u, 0x7149F2C9u, 0x72FC6F7Cu, 0x749DC5ADu,
718 0x76453719u, 0x77F684DFu, 0x799A130Bu, 0x7B4097CEu, 0x7CF0BDC2u, 0x7E967699u, 0x7F7FFFFFu};
721 template <>
722 struct _General_precision_tables<double> {
723 static constexpr int _Max_special_P = 15;
725 static constexpr uint64_t _Special_X_table[195] = {0x3F18E757928E0C9Du, 0x3F4F212D77318FC5u, 0x3F8374BC6A7EF9DBu,
726 0x3FB851EB851EB851u, 0x3FEE666666666666u, 0x4022FFFFFFFFFFFFu, 0x3F1A1554FBDAD751u, 0x3F504D551D68C692u,
727 0x3F8460AA64C2F837u, 0x3FB978D4FDF3B645u, 0x3FEFD70A3D70A3D7u, 0x4023E66666666666u, 0x4058DFFFFFFFFFFFu,
728 0x3F1A3387ECC8EB96u, 0x3F506034F3FD933Eu, 0x3F84784230FCF80Du, 0x3FB99652BD3C3611u, 0x3FEFFBE76C8B4395u,
729 0x4023FD70A3D70A3Du, 0x4058FCCCCCCCCCCCu, 0x408F3BFFFFFFFFFFu, 0x3F1A368D04E0BA6Au, 0x3F506218230C7482u,
730 0x3F847A9E2BCF91A3u, 0x3FB99945B6C3760Bu, 0x3FEFFF972474538Eu, 0x4023FFBE76C8B439u, 0x4058FFAE147AE147u,
731 0x408F3F9999999999u, 0x40C387BFFFFFFFFFu, 0x3F1A36DA54164F19u, 0x3F506248748DF16Fu, 0x3F847ADA91B16DCBu,
732 0x3FB99991361DC93Eu, 0x3FEFFFF583A53B8Eu, 0x4023FFF972474538u, 0x4058FFF7CED91687u, 0x408F3FF5C28F5C28u,
733 0x40C387F999999999u, 0x40F869F7FFFFFFFFu, 0x3F1A36E20F35445Du, 0x3F50624D49814ABAu, 0x3F847AE09BE19D69u,
734 0x3FB99998C2DA04C3u, 0x3FEFFFFEF39085F4u, 0x4023FFFF583A53B8u, 0x4058FFFF2E48E8A7u, 0x408F3FFEF9DB22D0u,
735 0x40C387FF5C28F5C2u, 0x40F869FF33333333u, 0x412E847EFFFFFFFFu, 0x3F1A36E2D51EC34Bu, 0x3F50624DC5333A0Eu,
736 0x3F847AE136800892u, 0x3FB9999984200AB7u, 0x3FEFFFFFE5280D65u, 0x4023FFFFEF39085Fu, 0x4058FFFFEB074A77u,
737 0x408F3FFFE5C91D14u, 0x40C387FFEF9DB22Du, 0x40F869FFEB851EB8u, 0x412E847FE6666666u, 0x416312CFEFFFFFFFu,
738 0x3F1A36E2E8E94FFCu, 0x3F50624DD191D1FDu, 0x3F847AE145F6467Du, 0x3FB999999773D81Cu, 0x3FEFFFFFFD50CE23u,
739 0x4023FFFFFE5280D6u, 0x4058FFFFFDE7210Bu, 0x408F3FFFFD60E94Eu, 0x40C387FFFE5C91D1u, 0x40F869FFFDF3B645u,
740 0x412E847FFD70A3D7u, 0x416312CFFE666666u, 0x4197D783FDFFFFFFu, 0x3F1A36E2EAE3F7A7u, 0x3F50624DD2CE7AC8u,
741 0x3F847AE14782197Bu, 0x3FB9999999629FD9u, 0x3FEFFFFFFFBB47D0u, 0x4023FFFFFFD50CE2u, 0x4058FFFFFFCA501Au,
742 0x408F3FFFFFBCE421u, 0x40C387FFFFD60E94u, 0x40F869FFFFCB923Au, 0x412E847FFFBE76C8u, 0x416312CFFFD70A3Du,
743 0x4197D783FFCCCCCCu, 0x41CDCD64FFBFFFFFu, 0x3F1A36E2EB16A205u, 0x3F50624DD2EE2543u, 0x3F847AE147A9AE94u,
744 0x3FB9999999941A39u, 0x3FEFFFFFFFF920C8u, 0x4023FFFFFFFBB47Du, 0x4058FFFFFFFAA19Cu, 0x408F3FFFFFF94A03u,
745 0x40C387FFFFFBCE42u, 0x40F869FFFFFAC1D2u, 0x412E847FFFF97247u, 0x416312CFFFFBE76Cu, 0x4197D783FFFAE147u,
746 0x41CDCD64FFF99999u, 0x4202A05F1FFBFFFFu, 0x3F1A36E2EB1BB30Fu, 0x3F50624DD2F14FE9u, 0x3F847AE147ADA3E3u,
747 0x3FB9999999990CDCu, 0x3FEFFFFFFFFF5014u, 0x4023FFFFFFFF920Cu, 0x4058FFFFFFFF768Fu, 0x408F3FFFFFFF5433u,
748 0x40C387FFFFFF94A0u, 0x40F869FFFFFF79C8u, 0x412E847FFFFF583Au, 0x416312CFFFFF9724u, 0x4197D783FFFF7CEDu,
749 0x41CDCD64FFFF5C28u, 0x4202A05F1FFF9999u, 0x42374876E7FF7FFFu, 0x3F1A36E2EB1C34C3u, 0x3F50624DD2F1A0FAu,
750 0x3F847AE147AE0938u, 0x3FB9999999998B86u, 0x3FEFFFFFFFFFEE68u, 0x4023FFFFFFFFF501u, 0x4058FFFFFFFFF241u,
751 0x408F3FFFFFFFEED1u, 0x40C387FFFFFFF543u, 0x40F869FFFFFFF294u, 0x412E847FFFFFEF39u, 0x416312CFFFFFF583u,
752 0x4197D783FFFFF2E4u, 0x41CDCD64FFFFEF9Du, 0x4202A05F1FFFF5C2u, 0x42374876E7FFF333u, 0x426D1A94A1FFEFFFu,
753 0x3F1A36E2EB1C41BBu, 0x3F50624DD2F1A915u, 0x3F847AE147AE135Au, 0x3FB9999999999831u, 0x3FEFFFFFFFFFFE3Du,
754 0x4023FFFFFFFFFEE6u, 0x4058FFFFFFFFFEA0u, 0x408F3FFFFFFFFE48u, 0x40C387FFFFFFFEEDu, 0x40F869FFFFFFFEA8u,
755 0x412E847FFFFFFE52u, 0x416312CFFFFFFEF3u, 0x4197D783FFFFFEB0u, 0x41CDCD64FFFFFE5Cu, 0x4202A05F1FFFFEF9u,
756 0x42374876E7FFFEB8u, 0x426D1A94A1FFFE66u, 0x42A2309CE53FFEFFu, 0x3F1A36E2EB1C4307u, 0x3F50624DD2F1A9E4u,
757 0x3F847AE147AE145Eu, 0x3FB9999999999975u, 0x3FEFFFFFFFFFFFD2u, 0x4023FFFFFFFFFFE3u, 0x4058FFFFFFFFFFDCu,
758 0x408F3FFFFFFFFFD4u, 0x40C387FFFFFFFFE4u, 0x40F869FFFFFFFFDDu, 0x412E847FFFFFFFD5u, 0x416312CFFFFFFFE5u,
759 0x4197D783FFFFFFDEu, 0x41CDCD64FFFFFFD6u, 0x4202A05F1FFFFFE5u, 0x42374876E7FFFFDFu, 0x426D1A94A1FFFFD7u,
760 0x42A2309CE53FFFE6u, 0x42D6BCC41E8FFFDFu, 0x3F1A36E2EB1C4328u, 0x3F50624DD2F1A9F9u, 0x3F847AE147AE1477u,
761 0x3FB9999999999995u, 0x3FEFFFFFFFFFFFFBu, 0x4023FFFFFFFFFFFDu, 0x4058FFFFFFFFFFFCu, 0x408F3FFFFFFFFFFBu,
762 0x40C387FFFFFFFFFDu, 0x40F869FFFFFFFFFCu, 0x412E847FFFFFFFFBu, 0x416312CFFFFFFFFDu, 0x4197D783FFFFFFFCu,
763 0x41CDCD64FFFFFFFBu, 0x4202A05F1FFFFFFDu, 0x42374876E7FFFFFCu, 0x426D1A94A1FFFFFBu, 0x42A2309CE53FFFFDu,
764 0x42D6BCC41E8FFFFCu, 0x430C6BF52633FFFBu};
766 static constexpr int _Max_P = 309;
768 static constexpr uint64_t _Ordinary_X_table[314] = {0x3F1A36E2EB1C432Cu, 0x3F50624DD2F1A9FBu, 0x3F847AE147AE147Au,
769 0x3FB9999999999999u, 0x3FEFFFFFFFFFFFFFu, 0x4023FFFFFFFFFFFFu, 0x4058FFFFFFFFFFFFu, 0x408F3FFFFFFFFFFFu,
770 0x40C387FFFFFFFFFFu, 0x40F869FFFFFFFFFFu, 0x412E847FFFFFFFFFu, 0x416312CFFFFFFFFFu, 0x4197D783FFFFFFFFu,
771 0x41CDCD64FFFFFFFFu, 0x4202A05F1FFFFFFFu, 0x42374876E7FFFFFFu, 0x426D1A94A1FFFFFFu, 0x42A2309CE53FFFFFu,
772 0x42D6BCC41E8FFFFFu, 0x430C6BF52633FFFFu, 0x4341C37937E07FFFu, 0x4376345785D89FFFu, 0x43ABC16D674EC7FFu,
773 0x43E158E460913CFFu, 0x4415AF1D78B58C3Fu, 0x444B1AE4D6E2EF4Fu, 0x4480F0CF064DD591u, 0x44B52D02C7E14AF6u,
774 0x44EA784379D99DB4u, 0x45208B2A2C280290u, 0x4554ADF4B7320334u, 0x4589D971E4FE8401u, 0x45C027E72F1F1281u,
775 0x45F431E0FAE6D721u, 0x46293E5939A08CE9u, 0x465F8DEF8808B024u, 0x4693B8B5B5056E16u, 0x46C8A6E32246C99Cu,
776 0x46FED09BEAD87C03u, 0x4733426172C74D82u, 0x476812F9CF7920E2u, 0x479E17B84357691Bu, 0x47D2CED32A16A1B1u,
777 0x48078287F49C4A1Du, 0x483D6329F1C35CA4u, 0x48725DFA371A19E6u, 0x48A6F578C4E0A060u, 0x48DCB2D6F618C878u,
778 0x4911EFC659CF7D4Bu, 0x49466BB7F0435C9Eu, 0x497C06A5EC5433C6u, 0x49B18427B3B4A05Bu, 0x49E5E531A0A1C872u,
779 0x4A1B5E7E08CA3A8Fu, 0x4A511B0EC57E6499u, 0x4A8561D276DDFDC0u, 0x4ABABA4714957D30u, 0x4AF0B46C6CDD6E3Eu,
780 0x4B24E1878814C9CDu, 0x4B5A19E96A19FC40u, 0x4B905031E2503DA8u, 0x4BC4643E5AE44D12u, 0x4BF97D4DF19D6057u,
781 0x4C2FDCA16E04B86Du, 0x4C63E9E4E4C2F344u, 0x4C98E45E1DF3B015u, 0x4CCF1D75A5709C1Au, 0x4D03726987666190u,
782 0x4D384F03E93FF9F4u, 0x4D6E62C4E38FF872u, 0x4DA2FDBB0E39FB47u, 0x4DD7BD29D1C87A19u, 0x4E0DAC74463A989Fu,
783 0x4E428BC8ABE49F63u, 0x4E772EBAD6DDC73Cu, 0x4EACFA698C95390Bu, 0x4EE21C81F7DD43A7u, 0x4F16A3A275D49491u,
784 0x4F4C4C8B1349B9B5u, 0x4F81AFD6EC0E1411u, 0x4FB61BCCA7119915u, 0x4FEBA2BFD0D5FF5Bu, 0x502145B7E285BF98u,
785 0x50559725DB272F7Fu, 0x508AFCEF51F0FB5Eu, 0x50C0DE1593369D1Bu, 0x50F5159AF8044462u, 0x512A5B01B605557Au,
786 0x516078E111C3556Cu, 0x5194971956342AC7u, 0x51C9BCDFABC13579u, 0x5200160BCB58C16Cu, 0x52341B8EBE2EF1C7u,
787 0x526922726DBAAE39u, 0x529F6B0F092959C7u, 0x52D3A2E965B9D81Cu, 0x53088BA3BF284E23u, 0x533EAE8CAEF261ACu,
788 0x53732D17ED577D0Bu, 0x53A7F85DE8AD5C4Eu, 0x53DDF67562D8B362u, 0x5412BA095DC7701Du, 0x5447688BB5394C25u,
789 0x547D42AEA2879F2Eu, 0x54B249AD2594C37Cu, 0x54E6DC186EF9F45Cu, 0x551C931E8AB87173u, 0x5551DBF316B346E7u,
790 0x558652EFDC6018A1u, 0x55BBE7ABD3781ECAu, 0x55F170CB642B133Eu, 0x5625CCFE3D35D80Eu, 0x565B403DCC834E11u,
791 0x569108269FD210CBu, 0x56C54A3047C694FDu, 0x56FA9CBC59B83A3Du, 0x5730A1F5B8132466u, 0x5764CA732617ED7Fu,
792 0x5799FD0FEF9DE8DFu, 0x57D03E29F5C2B18Bu, 0x58044DB473335DEEu, 0x583961219000356Au, 0x586FB969F40042C5u,
793 0x58A3D3E2388029BBu, 0x58D8C8DAC6A0342Au, 0x590EFB1178484134u, 0x59435CEAEB2D28C0u, 0x59783425A5F872F1u,
794 0x59AE412F0F768FADu, 0x59E2E8BD69AA19CCu, 0x5A17A2ECC414A03Fu, 0x5A4D8BA7F519C84Fu, 0x5A827748F9301D31u,
795 0x5AB7151B377C247Eu, 0x5AECDA62055B2D9Du, 0x5B22087D4358FC82u, 0x5B568A9C942F3BA3u, 0x5B8C2D43B93B0A8Bu,
796 0x5BC19C4A53C4E697u, 0x5BF6035CE8B6203Du, 0x5C2B843422E3A84Cu, 0x5C6132A095CE492Fu, 0x5C957F48BB41DB7Bu,
797 0x5CCADF1AEA12525Au, 0x5D00CB70D24B7378u, 0x5D34FE4D06DE5056u, 0x5D6A3DE04895E46Cu, 0x5DA066AC2D5DAEC3u,
798 0x5DD4805738B51A74u, 0x5E09A06D06E26112u, 0x5E400444244D7CABu, 0x5E7405552D60DBD6u, 0x5EA906AA78B912CBu,
799 0x5EDF485516E7577Eu, 0x5F138D352E5096AFu, 0x5F48708279E4BC5Au, 0x5F7E8CA3185DEB71u, 0x5FB317E5EF3AB327u,
800 0x5FE7DDDF6B095FF0u, 0x601DD55745CBB7ECu, 0x6052A5568B9F52F4u, 0x60874EAC2E8727B1u, 0x60BD22573A28F19Du,
801 0x60F2357684599702u, 0x6126C2D4256FFCC2u, 0x615C73892ECBFBF3u, 0x6191C835BD3F7D78u, 0x61C63A432C8F5CD6u,
802 0x61FBC8D3F7B3340Bu, 0x62315D847AD00087u, 0x6265B4E5998400A9u, 0x629B221EFFE500D3u, 0x62D0F5535FEF2084u,
803 0x630532A837EAE8A5u, 0x633A7F5245E5A2CEu, 0x63708F936BAF85C1u, 0x63A4B378469B6731u, 0x63D9E056584240FDu,
804 0x64102C35F729689Eu, 0x6444374374F3C2C6u, 0x647945145230B377u, 0x64AF965966BCE055u, 0x64E3BDF7E0360C35u,
805 0x6518AD75D8438F43u, 0x654ED8D34E547313u, 0x6583478410F4C7ECu, 0x65B819651531F9E7u, 0x65EE1FBE5A7E7861u,
806 0x6622D3D6F88F0B3Cu, 0x665788CCB6B2CE0Cu, 0x668D6AFFE45F818Fu, 0x66C262DFEEBBB0F9u, 0x66F6FB97EA6A9D37u,
807 0x672CBA7DE5054485u, 0x6761F48EAF234AD3u, 0x679671B25AEC1D88u, 0x67CC0E1EF1A724EAu, 0x680188D357087712u,
808 0x6835EB082CCA94D7u, 0x686B65CA37FD3A0Du, 0x68A11F9E62FE4448u, 0x68D56785FBBDD55Au, 0x690AC1677AAD4AB0u,
809 0x6940B8E0ACAC4EAEu, 0x6974E718D7D7625Au, 0x69AA20DF0DCD3AF0u, 0x69E0548B68A044D6u, 0x6A1469AE42C8560Cu,
810 0x6A498419D37A6B8Fu, 0x6A7FE52048590672u, 0x6AB3EF342D37A407u, 0x6AE8EB0138858D09u, 0x6B1F25C186A6F04Cu,
811 0x6B537798F428562Fu, 0x6B88557F31326BBBu, 0x6BBE6ADEFD7F06AAu, 0x6BF302CB5E6F642Au, 0x6C27C37E360B3D35u,
812 0x6C5DB45DC38E0C82u, 0x6C9290BA9A38C7D1u, 0x6CC734E940C6F9C5u, 0x6CFD022390F8B837u, 0x6D3221563A9B7322u,
813 0x6D66A9ABC9424FEBu, 0x6D9C5416BB92E3E6u, 0x6DD1B48E353BCE6Fu, 0x6E0621B1C28AC20Bu, 0x6E3BAA1E332D728Eu,
814 0x6E714A52DFFC6799u, 0x6EA59CE797FB817Fu, 0x6EDB04217DFA61DFu, 0x6F10E294EEBC7D2Bu, 0x6F451B3A2A6B9C76u,
815 0x6F7A6208B5068394u, 0x6FB07D457124123Cu, 0x6FE49C96CD6D16CBu, 0x7019C3BC80C85C7Eu, 0x70501A55D07D39CFu,
816 0x708420EB449C8842u, 0x70B9292615C3AA53u, 0x70EF736F9B3494E8u, 0x7123A825C100DD11u, 0x7158922F31411455u,
817 0x718EB6BAFD91596Bu, 0x71C33234DE7AD7E2u, 0x71F7FEC216198DDBu, 0x722DFE729B9FF152u, 0x7262BF07A143F6D3u,
818 0x72976EC98994F488u, 0x72CD4A7BEBFA31AAu, 0x73024E8D737C5F0Au, 0x7336E230D05B76CDu, 0x736C9ABD04725480u,
819 0x73A1E0B622C774D0u, 0x73D658E3AB795204u, 0x740BEF1C9657A685u, 0x74417571DDF6C813u, 0x7475D2CE55747A18u,
820 0x74AB4781EAD1989Eu, 0x74E10CB132C2FF63u, 0x75154FDD7F73BF3Bu, 0x754AA3D4DF50AF0Au, 0x7580A6650B926D66u,
821 0x75B4CFFE4E7708C0u, 0x75EA03FDE214CAF0u, 0x7620427EAD4CFED6u, 0x7654531E58A03E8Bu, 0x768967E5EEC84E2Eu,
822 0x76BFC1DF6A7A61BAu, 0x76F3D92BA28C7D14u, 0x7728CF768B2F9C59u, 0x775F03542DFB8370u, 0x779362149CBD3226u,
823 0x77C83A99C3EC7EAFu, 0x77FE494034E79E5Bu, 0x7832EDC82110C2F9u, 0x7867A93A2954F3B7u, 0x789D9388B3AA30A5u,
824 0x78D27C35704A5E67u, 0x79071B42CC5CF601u, 0x793CE2137F743381u, 0x79720D4C2FA8A030u, 0x79A6909F3B92C83Du,
825 0x79DC34C70A777A4Cu, 0x7A11A0FC668AAC6Fu, 0x7A46093B802D578Bu, 0x7A7B8B8A6038AD6Eu, 0x7AB137367C236C65u,
826 0x7AE585041B2C477Eu, 0x7B1AE64521F7595Eu, 0x7B50CFEB353A97DAu, 0x7B8503E602893DD1u, 0x7BBA44DF832B8D45u,
827 0x7BF06B0BB1FB384Bu, 0x7C2485CE9E7A065Eu, 0x7C59A742461887F6u, 0x7C9008896BCF54F9u, 0x7CC40AABC6C32A38u,
828 0x7CF90D56B873F4C6u, 0x7D2F50AC6690F1F8u, 0x7D63926BC01A973Bu, 0x7D987706B0213D09u, 0x7DCE94C85C298C4Cu,
829 0x7E031CFD3999F7AFu, 0x7E37E43C8800759Bu, 0x7E6DDD4BAA009302u, 0x7EA2AA4F4A405BE1u, 0x7ED754E31CD072D9u,
830 0x7F0D2A1BE4048F90u, 0x7F423A516E82D9BAu, 0x7F76C8E5CA239028u, 0x7FAC7B1F3CAC7433u, 0x7FE1CCF385EBC89Fu,
831 0x7FEFFFFFFFFFFFFFu};
834 template <class _Floating>
835 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
836 to_chars_result _Floating_to_chars_general_precision(
837 char* _First, char* const _Last, const _Floating _Value, int _Precision) noexcept {
839 using _Traits = _Floating_type_traits<_Floating>;
840 using _Uint_type = typename _Traits::_Uint_type;
842 const _Uint_type _Uint_value = _VSTD::bit_cast<_Uint_type>(_Value);
844 if (_Uint_value == 0) { // zero detected; write "0" and return; _Precision is irrelevant due to zero-trimming
845 if (_First == _Last) {
846 return {_Last, errc::value_too_large};
849 *_First++ = '0';
851 return {_First, errc{}};
854 // C11 7.21.6.1 "The fprintf function"/5:
855 // "A negative precision argument is taken as if the precision were omitted."
856 // /8: "g,G [...] Let P equal the precision if nonzero, 6 if the precision is omitted,
857 // or 1 if the precision is zero."
859 // Performance note: It's possible to rewrite this for branchless codegen,
860 // but profiling will be necessary to determine whether that's faster.
861 if (_Precision < 0) {
862 _Precision = 6;
863 } else if (_Precision == 0) {
864 _Precision = 1;
865 } else if (_Precision < 1'000'000) {
866 // _Precision is ok.
867 } else {
868 // Avoid integer overflow.
869 // Due to general notation's zero-trimming behavior, we can simply clamp _Precision.
870 // This is further clamped below.
871 _Precision = 1'000'000;
874 // _Precision is now the Standard's P.
876 // /8: "Then, if a conversion with style E would have an exponent of X:
877 // - if P > X >= -4, the conversion is with style f (or F) and precision P - (X + 1).
878 // - otherwise, the conversion is with style e (or E) and precision P - 1."
880 // /8: "Finally, [...] any trailing zeros are removed from the fractional portion of the result
881 // and the decimal-point character is removed if there is no fractional portion remaining."
883 using _Tables = _General_precision_tables<_Floating>;
885 const _Uint_type* _Table_begin;
886 const _Uint_type* _Table_end;
888 if (_Precision <= _Tables::_Max_special_P) {
889 _Table_begin = _Tables::_Special_X_table + (_Precision - 1) * (_Precision + 10) / 2;
890 _Table_end = _Table_begin + _Precision + 5;
891 } else {
892 _Table_begin = _Tables::_Ordinary_X_table;
893 _Table_end = _Table_begin + _VSTD::min(_Precision, _Tables::_Max_P) + 5;
896 // Profiling indicates that linear search is faster than binary search for small tables.
897 // Performance note: lambda captures may have a small performance cost.
898 const _Uint_type* const _Table_lower_bound = [=] {
899 if constexpr (!_IsSame<_Floating, float>::value) {
900 if (_Precision > 155) { // threshold determined via profiling
901 return _VSTD::lower_bound(_Table_begin, _Table_end, _Uint_value, less{});
905 return _VSTD::find_if(_Table_begin, _Table_end, [=](const _Uint_type _Elem) { return _Uint_value <= _Elem; });
906 }();
908 const ptrdiff_t _Table_index = _Table_lower_bound - _Table_begin;
909 const int _Scientific_exponent_X = static_cast<int>(_Table_index - 5);
910 const bool _Use_fixed_notation = _Precision > _Scientific_exponent_X && _Scientific_exponent_X >= -4;
912 // Performance note: it might (or might not) be faster to modify Ryu Printf to perform zero-trimming.
913 // Such modifications would involve a fairly complicated state machine (notably, both '0' and '9' digits would
914 // need to be buffered, due to rounding), and that would have performance costs due to increased branching.
915 // Here, we're using a simpler approach: writing into a local buffer, manually zero-trimming, and then copying into
916 // the output range. The necessary buffer size is reasonably small, the zero-trimming logic is simple and fast,
917 // and the final copying is also fast.
919 constexpr int _Max_output_length =
920 _IsSame<_Floating, float>::value ? 117 : 773; // cases: 0x1.fffffep-126f and 0x1.fffffffffffffp-1022
921 constexpr int _Max_fixed_precision =
922 _IsSame<_Floating, float>::value ? 37 : 66; // cases: 0x1.fffffep-14f and 0x1.fffffffffffffp-14
923 constexpr int _Max_scientific_precision =
924 _IsSame<_Floating, float>::value ? 111 : 766; // cases: 0x1.fffffep-126f and 0x1.fffffffffffffp-1022
926 // Note that _Max_output_length is determined by scientific notation and is more than enough for fixed notation.
927 // 0x1.fffffep+127f is 39 digits, plus 1 for '.', plus _Max_fixed_precision for '0' digits, equals 77.
928 // 0x1.fffffffffffffp+1023 is 309 digits, plus 1 for '.', plus _Max_fixed_precision for '0' digits, equals 376.
930 char _Buffer[_Max_output_length];
931 const char* const _Significand_first = _Buffer; // e.g. "1.234"
932 const char* _Significand_last = nullptr;
933 const char* _Exponent_first = nullptr; // e.g. "e-05"
934 const char* _Exponent_last = nullptr;
935 int _Effective_precision; // number of digits printed after the decimal point, before trimming
937 // Write into the local buffer.
938 // Clamping _Effective_precision allows _Buffer to be as small as possible, and increases efficiency.
939 if (_Use_fixed_notation) {
940 _Effective_precision = _VSTD::min(_Precision - (_Scientific_exponent_X + 1), _Max_fixed_precision);
941 const to_chars_result _Buf_result =
942 _Floating_to_chars_fixed_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision);
943 _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
944 _Significand_last = _Buf_result.ptr;
945 } else {
946 _Effective_precision = _VSTD::min(_Precision - 1, _Max_scientific_precision);
947 const to_chars_result _Buf_result =
948 _Floating_to_chars_scientific_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision);
949 _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
950 _Significand_last = _VSTD::find(_Buffer, _Buf_result.ptr, 'e');
951 _Exponent_first = _Significand_last;
952 _Exponent_last = _Buf_result.ptr;
955 // If we printed a decimal point followed by digits, perform zero-trimming.
956 if (_Effective_precision > 0) {
957 while (_Significand_last[-1] == '0') { // will stop at '.' or a nonzero digit
958 --_Significand_last;
961 if (_Significand_last[-1] == '.') {
962 --_Significand_last;
966 // Copy the significand to the output range.
967 const ptrdiff_t _Significand_distance = _Significand_last - _Significand_first;
968 if (_Last - _First < _Significand_distance) {
969 return {_Last, errc::value_too_large};
971 _VSTD::memcpy(_First, _Significand_first, static_cast<size_t>(_Significand_distance));
972 _First += _Significand_distance;
974 // Copy the exponent to the output range.
975 if (!_Use_fixed_notation) {
976 const ptrdiff_t _Exponent_distance = _Exponent_last - _Exponent_first;
977 if (_Last - _First < _Exponent_distance) {
978 return {_Last, errc::value_too_large};
980 _VSTD::memcpy(_First, _Exponent_first, static_cast<size_t>(_Exponent_distance));
981 _First += _Exponent_distance;
984 return {_First, errc{}};
987 enum class _Floating_to_chars_overload { _Plain, _Format_only, _Format_precision };
989 template <_Floating_to_chars_overload _Overload, class _Floating>
990 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
991 to_chars_result _Floating_to_chars(
992 char* _First, char* const _Last, _Floating _Value, const chars_format _Fmt, const int _Precision) noexcept {
994 if constexpr (_Overload == _Floating_to_chars_overload::_Plain) {
995 _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
996 } else {
997 _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format::general || _Fmt == chars_format::scientific
998 || _Fmt == chars_format::fixed || _Fmt == chars_format::hex,
999 "invalid format in to_chars()");
1002 using _Traits = _Floating_type_traits<_Floating>;
1003 using _Uint_type = typename _Traits::_Uint_type;
1005 _Uint_type _Uint_value = _VSTD::bit_cast<_Uint_type>(_Value);
1007 const bool _Was_negative = (_Uint_value & _Traits::_Shifted_sign_mask) != 0;
1009 if (_Was_negative) { // sign bit detected; write minus sign and clear sign bit
1010 if (_First == _Last) {
1011 return {_Last, errc::value_too_large};
1014 *_First++ = '-';
1016 _Uint_value &= ~_Traits::_Shifted_sign_mask;
1017 _Value = _VSTD::bit_cast<_Floating>(_Uint_value);
1020 if ((_Uint_value & _Traits::_Shifted_exponent_mask) == _Traits::_Shifted_exponent_mask) {
1021 // inf/nan detected; write appropriate string and return
1022 const char* _Str;
1023 size_t _Len;
1025 const _Uint_type _Mantissa = _Uint_value & _Traits::_Denormal_mantissa_mask;
1027 if (_Mantissa == 0) {
1028 _Str = "inf";
1029 _Len = 3;
1030 } else if (_Was_negative && _Mantissa == _Traits::_Special_nan_mantissa_mask) {
1031 // When a NaN value has the sign bit set, the quiet bit set, and all other mantissa bits cleared,
1032 // the UCRT interprets it to mean "indeterminate", and indicates this by printing "-nan(ind)".
1033 _Str = "nan(ind)";
1034 _Len = 8;
1035 } else if ((_Mantissa & _Traits::_Special_nan_mantissa_mask) != 0) {
1036 _Str = "nan";
1037 _Len = 3;
1038 } else {
1039 _Str = "nan(snan)";
1040 _Len = 9;
1043 if (_Last - _First < static_cast<ptrdiff_t>(_Len)) {
1044 return {_Last, errc::value_too_large};
1047 _VSTD::memcpy(_First, _Str, _Len);
1049 return {_First + _Len, errc{}};
1052 if constexpr (_Overload == _Floating_to_chars_overload::_Plain) {
1053 return _Floating_to_chars_ryu(_First, _Last, _Value, chars_format{});
1054 } else if constexpr (_Overload == _Floating_to_chars_overload::_Format_only) {
1055 if (_Fmt == chars_format::hex) {
1056 return _Floating_to_chars_hex_shortest(_First, _Last, _Value);
1059 return _Floating_to_chars_ryu(_First, _Last, _Value, _Fmt);
1060 } else if constexpr (_Overload == _Floating_to_chars_overload::_Format_precision) {
1061 switch (_Fmt) {
1062 case chars_format::scientific:
1063 return _Floating_to_chars_scientific_precision(_First, _Last, _Value, _Precision);
1064 case chars_format::fixed:
1065 return _Floating_to_chars_fixed_precision(_First, _Last, _Value, _Precision);
1066 case chars_format::general:
1067 return _Floating_to_chars_general_precision(_First, _Last, _Value, _Precision);
1068 case chars_format::hex:
1069 default: // avoid MSVC warning C4715: not all control paths return a value
1070 return _Floating_to_chars_hex_precision(_First, _Last, _Value, _Precision);
1075 // clang-format on
1077 _LIBCPP_END_NAMESPACE_STD
1079 #endif // _LIBCPP_SRC_INCLUDE_TO_CHARS_FLOATING_POINT_H