1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // 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.
20 #include <__algorithm/find.h>
21 #include <__algorithm/find_if.h>
22 #include <__algorithm/lower_bound.h>
23 #include <__algorithm/min.h>
26 #include <__functional/operations.h>
27 #include <__iterator/access.h>
28 #include <__iterator/size.h>
33 #include "include/ryu/ryu.h"
35 _LIBCPP_BEGIN_NAMESPACE_STD
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);
43 // vvvvvvvvvv DERIVED FROM corecrt_internal_fltintrn.h vvvvvvvvvv
45 template <class _FloatingType
>
46 struct _Floating_type_traits
;
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
;
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)
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
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
;
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
);
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;
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
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.
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) {
288 int32_t _Number_of_bits_remaining
= _Adjusted_explicit_bits
; // 24 for float, 52 for double
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
];
301 // _Precision is the number of hexits that still need to be printed.
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
;
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.
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
;
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.
392 if (_First
== _Last
) {
393 return {_Last
, errc::value_too_large
};
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
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.
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
};
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
};
452 if (_Unbiased_exponent
< 0) {
454 _Unbiased_exponent
= -_Unbiased_exponent
;
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
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.
517 // cl /EHsc /nologo /W4 /MT /O2 /std:c++17 generate_tables.cpp && generate_tables
527 #include <system_error>
528 #include <type_traits>
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
;
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
573 const auto from_result
= from_chars(exp_ptr
, to_result
.ptr
, X
);
574 assert(from_result
.ec
== errc
{});
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
);
588 printf("0x%016llXu,\n", val
);
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");
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
);
676 printf("{%.*a%s, chars_format::general, %d, \"%.*g\"},\n", Hexits
, f2
, Suffix
, P
, P
, f2
);
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
);
694 template <class _Floating
>
695 struct _General_precision_tables
;
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
};
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
};
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) {
863 } else if (_Precision
== 0) {
865 } else if (_Precision
< 1'000'000) {
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;
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
; });
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
;
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
961 if (_Significand_last
[-1] == '.') {
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
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
};
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
1025 const _Uint_type _Mantissa
= _Uint_value
& _Traits::_Denormal_mantissa_mask
;
1027 if (_Mantissa
== 0) {
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)".
1035 } else if ((_Mantissa
& _Traits::_Special_nan_mantissa_mask
) != 0) {
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
) {
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
);
1077 _LIBCPP_END_NAMESPACE_STD
1079 #endif // _LIBCPP_SRC_INCLUDE_TO_CHARS_FLOATING_POINT_H