xref: /freebsd/contrib/llvm-project/libcxx/src/ryu/d2fixed.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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 //===----------------------------------------------------------------------===//
8 
9 // Copyright (c) Microsoft Corporation.
10 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11 
12 // Copyright 2018 Ulf Adams
13 // Copyright (c) Microsoft Corporation. All rights reserved.
14 
15 // Boost Software License - Version 1.0 - August 17th, 2003
16 
17 // Permission is hereby granted, free of charge, to any person or organization
18 // obtaining a copy of the software and accompanying documentation covered by
19 // this license (the "Software") to use, reproduce, display, distribute,
20 // execute, and transmit the Software, and to prepare derivative works of the
21 // Software, and to permit third-parties to whom the Software is furnished to
22 // do so, all subject to the following:
23 
24 // The copyright notices in the Software and this entire statement, including
25 // the above license grant, this restriction and the following disclaimer,
26 // must be included in all copies of the Software, in whole or in part, and
27 // all derivative works of the Software, unless such copies or derivative
28 // works are solely in the form of machine-executable object code generated by
29 // a source language processor.
30 
31 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
34 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
35 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
36 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
37 // DEALINGS IN THE SOFTWARE.
38 
39 // Avoid formatting to keep the changes with the original code minimal.
40 // clang-format off
41 
42 #include <__assert>
43 #include <__config>
44 #include <charconv>
45 #include <cstring>
46 
47 #include "include/ryu/common.h"
48 #include "include/ryu/d2fixed.h"
49 #include "include/ryu/d2fixed_full_table.h"
50 #include "include/ryu/d2s.h"
51 #include "include/ryu/d2s_intrinsics.h"
52 #include "include/ryu/digit_table.h"
53 
54 _LIBCPP_BEGIN_NAMESPACE_STD
55 
56 inline constexpr int __POW10_ADDITIONAL_BITS = 120;
57 
58 #ifdef _LIBCPP_INTRINSIC128
59 // Returns the low 64 bits of the high 128 bits of the 256-bit product of a and b.
60 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __umul256_hi128_lo64(
61   const uint64_t __aHi, const uint64_t __aLo, const uint64_t __bHi, const uint64_t __bLo) {
62   uint64_t __b00Hi;
63   const uint64_t __b00Lo = __ryu_umul128(__aLo, __bLo, &__b00Hi);
64   uint64_t __b01Hi;
65   const uint64_t __b01Lo = __ryu_umul128(__aLo, __bHi, &__b01Hi);
66   uint64_t __b10Hi;
67   const uint64_t __b10Lo = __ryu_umul128(__aHi, __bLo, &__b10Hi);
68   uint64_t __b11Hi;
69   const uint64_t __b11Lo = __ryu_umul128(__aHi, __bHi, &__b11Hi);
70   (void) __b00Lo; // unused
71   (void) __b11Hi; // unused
72   const uint64_t __temp1Lo = __b10Lo + __b00Hi;
73   const uint64_t __temp1Hi = __b10Hi + (__temp1Lo < __b10Lo);
74   const uint64_t __temp2Lo = __b01Lo + __temp1Lo;
75   const uint64_t __temp2Hi = __b01Hi + (__temp2Lo < __b01Lo);
76   return __b11Lo + __temp1Hi + __temp2Hi;
77 }
78 
79 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __uint128_mod1e9(const uint64_t __vHi, const uint64_t __vLo) {
80   // After multiplying, we're going to shift right by 29, then truncate to uint32_t.
81   // This means that we need only 29 + 32 = 61 bits, so we can truncate to uint64_t before shifting.
82   const uint64_t __multiplied = __umul256_hi128_lo64(__vHi, __vLo, 0x89705F4136B4A597u, 0x31680A88F8953031u);
83 
84   // For uint32_t truncation, see the __mod1e9() comment in d2s_intrinsics.h.
85   const uint32_t __shifted = static_cast<uint32_t>(__multiplied >> 29);
86 
87   return static_cast<uint32_t>(__vLo) - 1000000000 * __shifted;
88 }
89 #endif // ^^^ intrinsics available ^^^
90 
91 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift_mod1e9(const uint64_t __m, const uint64_t* const __mul, const int32_t __j) {
92   uint64_t __high0;                                               // 64
93   const uint64_t __low0 = __ryu_umul128(__m, __mul[0], &__high0); // 0
94   uint64_t __high1;                                               // 128
95   const uint64_t __low1 = __ryu_umul128(__m, __mul[1], &__high1); // 64
96   uint64_t __high2;                                               // 192
97   const uint64_t __low2 = __ryu_umul128(__m, __mul[2], &__high2); // 128
98   const uint64_t __s0low = __low0;                  // 0
99   (void) __s0low; // unused
100   const uint64_t __s0high = __low1 + __high0;       // 64
101   const uint32_t __c1 = __s0high < __low1;
102   const uint64_t __s1low = __low2 + __high1 + __c1; // 128
103   const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2
104   const uint64_t __s1high = __high2 + __c2;         // 192
105   _LIBCPP_ASSERT_UNCATEGORIZED(__j >= 128, "");
106   _LIBCPP_ASSERT_UNCATEGORIZED(__j <= 180, "");
107 #ifdef _LIBCPP_INTRINSIC128
108   const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52]
109   const uint64_t __shiftedhigh = __s1high >> __dist;
110   const uint64_t __shiftedlow = __ryu_shiftright128(__s1low, __s1high, __dist);
111   return __uint128_mod1e9(__shiftedhigh, __shiftedlow);
112 #else // ^^^ intrinsics available ^^^ / vvv intrinsics unavailable vvv
113   if (__j < 160) { // __j: [128, 160)
114     const uint64_t __r0 = __mod1e9(__s1high);
115     const uint64_t __r1 = __mod1e9((__r0 << 32) | (__s1low >> 32));
116     const uint64_t __r2 = ((__r1 << 32) | (__s1low & 0xffffffff));
117     return __mod1e9(__r2 >> (__j - 128));
118   } else { // __j: [160, 192)
119     const uint64_t __r0 = __mod1e9(__s1high);
120     const uint64_t __r1 = ((__r0 << 32) | (__s1low >> 32));
121     return __mod1e9(__r1 >> (__j - 160));
122   }
123 #endif // ^^^ intrinsics unavailable ^^^
124 }
125 
126 void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const __result) {
127   uint32_t __i = 0;
128   while (__digits >= 10000) {
129 #ifdef __clang__ // TRANSITION, LLVM-38217
130     const uint32_t __c = __digits - 10000 * (__digits / 10000);
131 #else
132     const uint32_t __c = __digits % 10000;
133 #endif
134     __digits /= 10000;
135     const uint32_t __c0 = (__c % 100) << 1;
136     const uint32_t __c1 = (__c / 100) << 1;
137     std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
138     std::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
139     __i += 4;
140   }
141   if (__digits >= 100) {
142     const uint32_t __c = (__digits % 100) << 1;
143     __digits /= 100;
144     std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
145     __i += 2;
146   }
147   if (__digits >= 10) {
148     const uint32_t __c = __digits << 1;
149     std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
150   } else {
151     __result[0] = static_cast<char>('0' + __digits);
152   }
153 }
154 
155 _LIBCPP_HIDE_FROM_ABI inline void __append_d_digits(const uint32_t __olength, uint32_t __digits, char* const __result) {
156   uint32_t __i = 0;
157   while (__digits >= 10000) {
158 #ifdef __clang__ // TRANSITION, LLVM-38217
159     const uint32_t __c = __digits - 10000 * (__digits / 10000);
160 #else
161     const uint32_t __c = __digits % 10000;
162 #endif
163     __digits /= 10000;
164     const uint32_t __c0 = (__c % 100) << 1;
165     const uint32_t __c1 = (__c / 100) << 1;
166     std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
167     std::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
168     __i += 4;
169   }
170   if (__digits >= 100) {
171     const uint32_t __c = (__digits % 100) << 1;
172     __digits /= 100;
173     std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
174     __i += 2;
175   }
176   if (__digits >= 10) {
177     const uint32_t __c = __digits << 1;
178     __result[2] = __DIGIT_TABLE[__c + 1];
179     __result[1] = '.';
180     __result[0] = __DIGIT_TABLE[__c];
181   } else {
182     __result[1] = '.';
183     __result[0] = static_cast<char>('0' + __digits);
184   }
185 }
186 
187 _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint32_t __digits, char* const __result) {
188   uint32_t __i = 0;
189   for (; __i < __count - 1; __i += 2) {
190     const uint32_t __c = (__digits % 100) << 1;
191     __digits /= 100;
192     std::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
193   }
194   if (__i < __count) {
195     const char __c = static_cast<char>('0' + (__digits % 10));
196     __result[__count - __i - 1] = __c;
197   }
198 }
199 
200 void __append_nine_digits(uint32_t __digits, char* const __result) {
201   if (__digits == 0) {
202     std::memset(__result, '0', 9);
203     return;
204   }
205 
206   for (uint32_t __i = 0; __i < 5; __i += 4) {
207 #ifdef __clang__ // TRANSITION, LLVM-38217
208     const uint32_t __c = __digits - 10000 * (__digits / 10000);
209 #else
210     const uint32_t __c = __digits % 10000;
211 #endif
212     __digits /= 10000;
213     const uint32_t __c0 = (__c % 100) << 1;
214     const uint32_t __c1 = (__c / 100) << 1;
215     std::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
216     std::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
217   }
218   __result[0] = static_cast<char>('0' + __digits);
219 }
220 
221 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __indexForExponent(const uint32_t __e) {
222   return (__e + 15) / 16;
223 }
224 
225 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow10BitsForIndex(const uint32_t __idx) {
226   return 16 * __idx + __POW10_ADDITIONAL_BITS;
227 }
228 
229 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __lengthForIndex(const uint32_t __idx) {
230   // +1 for ceil, +16 for mantissa, +8 to round up when dividing by 9
231   return (__log10Pow2(16 * static_cast<int32_t>(__idx)) + 1 + 16 + 8) / 9;
232 }
233 
234 [[nodiscard]] to_chars_result __d2fixed_buffered_n(char* _First, char* const _Last, const double __d,
235   const uint32_t __precision) {
236   char* const _Original_first = _First;
237 
238   const uint64_t __bits = __double_to_bits(__d);
239 
240   // Case distinction; exit early for the easy cases.
241   if (__bits == 0) {
242     const int32_t _Total_zero_length = 1 // leading zero
243       + static_cast<int32_t>(__precision != 0) // possible decimal point
244       + static_cast<int32_t>(__precision); // zeroes after decimal point
245 
246     if (_Last - _First < _Total_zero_length) {
247       return { _Last, errc::value_too_large };
248     }
249 
250     *_First++ = '0';
251     if (__precision > 0) {
252       *_First++ = '.';
253       std::memset(_First, '0', __precision);
254       _First += __precision;
255     }
256     return { _First, errc{} };
257   }
258 
259   // Decode __bits into mantissa and exponent.
260   const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
261   const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
262 
263   int32_t __e2;
264   uint64_t __m2;
265   if (__ieeeExponent == 0) {
266     __e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
267     __m2 = __ieeeMantissa;
268   } else {
269     __e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
270     __m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
271   }
272 
273   bool __nonzero = false;
274   if (__e2 >= -52) {
275     const uint32_t __idx = __e2 < 0 ? 0 : __indexForExponent(static_cast<uint32_t>(__e2));
276     const uint32_t __p10bits = __pow10BitsForIndex(__idx);
277     const int32_t __len = static_cast<int32_t>(__lengthForIndex(__idx));
278     for (int32_t __i = __len - 1; __i >= 0; --__i) {
279       const uint32_t __j = __p10bits - __e2;
280       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
281       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
282       const uint32_t __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT[__POW10_OFFSET[__idx] + __i],
283         static_cast<int32_t>(__j + 8));
284       if (__nonzero) {
285         if (_Last - _First < 9) {
286           return { _Last, errc::value_too_large };
287         }
288         __append_nine_digits(__digits, _First);
289         _First += 9;
290       } else if (__digits != 0) {
291         const uint32_t __olength = __decimalLength9(__digits);
292         if (_Last - _First < static_cast<ptrdiff_t>(__olength)) {
293           return { _Last, errc::value_too_large };
294         }
295         __append_n_digits(__olength, __digits, _First);
296         _First += __olength;
297         __nonzero = true;
298       }
299     }
300   }
301   if (!__nonzero) {
302     if (_First == _Last) {
303       return { _Last, errc::value_too_large };
304     }
305     *_First++ = '0';
306   }
307   if (__precision > 0) {
308     if (_First == _Last) {
309       return { _Last, errc::value_too_large };
310     }
311     *_First++ = '.';
312   }
313   if (__e2 < 0) {
314     const int32_t __idx = -__e2 / 16;
315     const uint32_t __blocks = __precision / 9 + 1;
316     // 0 = don't round up; 1 = round up unconditionally; 2 = round up if odd.
317     int __roundUp = 0;
318     uint32_t __i = 0;
319     if (__blocks <= __MIN_BLOCK_2[__idx]) {
320       __i = __blocks;
321       if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
322         return { _Last, errc::value_too_large };
323       }
324       std::memset(_First, '0', __precision);
325       _First += __precision;
326     } else if (__i < __MIN_BLOCK_2[__idx]) {
327       __i = __MIN_BLOCK_2[__idx];
328       if (_Last - _First < static_cast<ptrdiff_t>(9 * __i)) {
329         return { _Last, errc::value_too_large };
330       }
331       std::memset(_First, '0', 9 * __i);
332       _First += 9 * __i;
333     }
334     for (; __i < __blocks; ++__i) {
335       const int32_t __j = __ADDITIONAL_BITS_2 + (-__e2 - 16 * __idx);
336       const uint32_t __p = __POW10_OFFSET_2[__idx] + __i - __MIN_BLOCK_2[__idx];
337       if (__p >= __POW10_OFFSET_2[__idx + 1]) {
338         // If the remaining digits are all 0, then we might as well use memset.
339         // No rounding required in this case.
340         const uint32_t __fill = __precision - 9 * __i;
341         if (_Last - _First < static_cast<ptrdiff_t>(__fill)) {
342           return { _Last, errc::value_too_large };
343         }
344         std::memset(_First, '0', __fill);
345         _First += __fill;
346         break;
347       }
348       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
349       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
350       uint32_t __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT_2[__p], __j + 8);
351       if (__i < __blocks - 1) {
352         if (_Last - _First < 9) {
353           return { _Last, errc::value_too_large };
354         }
355         __append_nine_digits(__digits, _First);
356         _First += 9;
357       } else {
358         const uint32_t __maximum = __precision - 9 * __i;
359         uint32_t __lastDigit = 0;
360         for (uint32_t __k = 0; __k < 9 - __maximum; ++__k) {
361           __lastDigit = __digits % 10;
362           __digits /= 10;
363         }
364         if (__lastDigit != 5) {
365           __roundUp = __lastDigit > 5;
366         } else {
367           // Is m * 10^(additionalDigits + 1) / 2^(-__e2) integer?
368           const int32_t __requiredTwos = -__e2 - static_cast<int32_t>(__precision) - 1;
369           const bool __trailingZeros = __requiredTwos <= 0
370             || (__requiredTwos < 60 && __multipleOfPowerOf2(__m2, static_cast<uint32_t>(__requiredTwos)));
371           __roundUp = __trailingZeros ? 2 : 1;
372         }
373         if (__maximum > 0) {
374           if (_Last - _First < static_cast<ptrdiff_t>(__maximum)) {
375             return { _Last, errc::value_too_large };
376           }
377           __append_c_digits(__maximum, __digits, _First);
378           _First += __maximum;
379         }
380         break;
381       }
382     }
383     if (__roundUp != 0) {
384       char* _Round = _First;
385       char* _Dot = _Last;
386       while (true) {
387         if (_Round == _Original_first) {
388           _Round[0] = '1';
389           if (_Dot != _Last) {
390             _Dot[0] = '0';
391             _Dot[1] = '.';
392           }
393           if (_First == _Last) {
394             return { _Last, errc::value_too_large };
395           }
396           *_First++ = '0';
397           break;
398         }
399         --_Round;
400         const char __c = _Round[0];
401         if (__c == '.') {
402           _Dot = _Round;
403         } else if (__c == '9') {
404           _Round[0] = '0';
405           __roundUp = 1;
406         } else {
407           if (__roundUp == 1 || __c % 2 != 0) {
408             _Round[0] = __c + 1;
409           }
410           break;
411         }
412       }
413     }
414   } else {
415     if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
416       return { _Last, errc::value_too_large };
417     }
418     std::memset(_First, '0', __precision);
419     _First += __precision;
420   }
421   return { _First, errc{} };
422 }
423 
424 [[nodiscard]] to_chars_result __d2exp_buffered_n(char* _First, char* const _Last, const double __d,
425   uint32_t __precision) {
426   char* const _Original_first = _First;
427 
428   const uint64_t __bits = __double_to_bits(__d);
429 
430   // Case distinction; exit early for the easy cases.
431   if (__bits == 0) {
432     const int32_t _Total_zero_length = 1 // leading zero
433       + static_cast<int32_t>(__precision != 0) // possible decimal point
434       + static_cast<int32_t>(__precision) // zeroes after decimal point
435       + 4; // "e+00"
436     if (_Last - _First < _Total_zero_length) {
437       return { _Last, errc::value_too_large };
438     }
439     *_First++ = '0';
440     if (__precision > 0) {
441       *_First++ = '.';
442       std::memset(_First, '0', __precision);
443       _First += __precision;
444     }
445     std::memcpy(_First, "e+00", 4);
446     _First += 4;
447     return { _First, errc{} };
448   }
449 
450   // Decode __bits into mantissa and exponent.
451   const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
452   const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
453 
454   int32_t __e2;
455   uint64_t __m2;
456   if (__ieeeExponent == 0) {
457     __e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
458     __m2 = __ieeeMantissa;
459   } else {
460     __e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
461     __m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
462   }
463 
464   const bool __printDecimalPoint = __precision > 0;
465   ++__precision;
466   uint32_t __digits = 0;
467   uint32_t __printedDigits = 0;
468   uint32_t __availableDigits = 0;
469   int32_t __exp = 0;
470   if (__e2 >= -52) {
471     const uint32_t __idx = __e2 < 0 ? 0 : __indexForExponent(static_cast<uint32_t>(__e2));
472     const uint32_t __p10bits = __pow10BitsForIndex(__idx);
473     const int32_t __len = static_cast<int32_t>(__lengthForIndex(__idx));
474     for (int32_t __i = __len - 1; __i >= 0; --__i) {
475       const uint32_t __j = __p10bits - __e2;
476       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
477       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
478       __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT[__POW10_OFFSET[__idx] + __i],
479         static_cast<int32_t>(__j + 8));
480       if (__printedDigits != 0) {
481         if (__printedDigits + 9 > __precision) {
482           __availableDigits = 9;
483           break;
484         }
485         if (_Last - _First < 9) {
486           return { _Last, errc::value_too_large };
487         }
488         __append_nine_digits(__digits, _First);
489         _First += 9;
490         __printedDigits += 9;
491       } else if (__digits != 0) {
492         __availableDigits = __decimalLength9(__digits);
493         __exp = __i * 9 + static_cast<int32_t>(__availableDigits) - 1;
494         if (__availableDigits > __precision) {
495           break;
496         }
497         if (__printDecimalPoint) {
498           if (_Last - _First < static_cast<ptrdiff_t>(__availableDigits + 1)) {
499             return { _Last, errc::value_too_large };
500           }
501           __append_d_digits(__availableDigits, __digits, _First);
502           _First += __availableDigits + 1; // +1 for decimal point
503         } else {
504           if (_First == _Last) {
505             return { _Last, errc::value_too_large };
506           }
507           *_First++ = static_cast<char>('0' + __digits);
508         }
509         __printedDigits = __availableDigits;
510         __availableDigits = 0;
511       }
512     }
513   }
514 
515   if (__e2 < 0 && __availableDigits == 0) {
516     const int32_t __idx = -__e2 / 16;
517     for (int32_t __i = __MIN_BLOCK_2[__idx]; __i < 200; ++__i) {
518       const int32_t __j = __ADDITIONAL_BITS_2 + (-__e2 - 16 * __idx);
519       const uint32_t __p = __POW10_OFFSET_2[__idx] + static_cast<uint32_t>(__i) - __MIN_BLOCK_2[__idx];
520       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
521       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
522       __digits = (__p >= __POW10_OFFSET_2[__idx + 1]) ? 0 : __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT_2[__p], __j + 8);
523       if (__printedDigits != 0) {
524         if (__printedDigits + 9 > __precision) {
525           __availableDigits = 9;
526           break;
527         }
528         if (_Last - _First < 9) {
529           return { _Last, errc::value_too_large };
530         }
531         __append_nine_digits(__digits, _First);
532         _First += 9;
533         __printedDigits += 9;
534       } else if (__digits != 0) {
535         __availableDigits = __decimalLength9(__digits);
536         __exp = -(__i + 1) * 9 + static_cast<int32_t>(__availableDigits) - 1;
537         if (__availableDigits > __precision) {
538           break;
539         }
540         if (__printDecimalPoint) {
541           if (_Last - _First < static_cast<ptrdiff_t>(__availableDigits + 1)) {
542             return { _Last, errc::value_too_large };
543           }
544           __append_d_digits(__availableDigits, __digits, _First);
545           _First += __availableDigits + 1; // +1 for decimal point
546         } else {
547           if (_First == _Last) {
548             return { _Last, errc::value_too_large };
549           }
550           *_First++ = static_cast<char>('0' + __digits);
551         }
552         __printedDigits = __availableDigits;
553         __availableDigits = 0;
554       }
555     }
556   }
557 
558   const uint32_t __maximum = __precision - __printedDigits;
559   if (__availableDigits == 0) {
560     __digits = 0;
561   }
562   uint32_t __lastDigit = 0;
563   if (__availableDigits > __maximum) {
564     for (uint32_t __k = 0; __k < __availableDigits - __maximum; ++__k) {
565       __lastDigit = __digits % 10;
566       __digits /= 10;
567     }
568   }
569   // 0 = don't round up; 1 = round up unconditionally; 2 = round up if odd.
570   int __roundUp = 0;
571   if (__lastDigit != 5) {
572     __roundUp = __lastDigit > 5;
573   } else {
574     // Is m * 2^__e2 * 10^(__precision + 1 - __exp) integer?
575     // __precision was already increased by 1, so we don't need to write + 1 here.
576     const int32_t __rexp = static_cast<int32_t>(__precision) - __exp;
577     const int32_t __requiredTwos = -__e2 - __rexp;
578     bool __trailingZeros = __requiredTwos <= 0
579       || (__requiredTwos < 60 && __multipleOfPowerOf2(__m2, static_cast<uint32_t>(__requiredTwos)));
580     if (__rexp < 0) {
581       const int32_t __requiredFives = -__rexp;
582       __trailingZeros = __trailingZeros && __multipleOfPowerOf5(__m2, static_cast<uint32_t>(__requiredFives));
583     }
584     __roundUp = __trailingZeros ? 2 : 1;
585   }
586   if (__printedDigits != 0) {
587     if (_Last - _First < static_cast<ptrdiff_t>(__maximum)) {
588       return { _Last, errc::value_too_large };
589     }
590     if (__digits == 0) {
591       std::memset(_First, '0', __maximum);
592     } else {
593       __append_c_digits(__maximum, __digits, _First);
594     }
595     _First += __maximum;
596   } else {
597     if (__printDecimalPoint) {
598       if (_Last - _First < static_cast<ptrdiff_t>(__maximum + 1)) {
599         return { _Last, errc::value_too_large };
600       }
601       __append_d_digits(__maximum, __digits, _First);
602       _First += __maximum + 1; // +1 for decimal point
603     } else {
604       if (_First == _Last) {
605         return { _Last, errc::value_too_large };
606       }
607       *_First++ = static_cast<char>('0' + __digits);
608     }
609   }
610   if (__roundUp != 0) {
611     char* _Round = _First;
612     while (true) {
613       if (_Round == _Original_first) {
614         _Round[0] = '1';
615         ++__exp;
616         break;
617       }
618       --_Round;
619       const char __c = _Round[0];
620       if (__c == '.') {
621         // Keep going.
622       } else if (__c == '9') {
623         _Round[0] = '0';
624         __roundUp = 1;
625       } else {
626         if (__roundUp == 1 || __c % 2 != 0) {
627           _Round[0] = __c + 1;
628         }
629         break;
630       }
631     }
632   }
633 
634   char _Sign_character;
635 
636   if (__exp < 0) {
637     _Sign_character = '-';
638     __exp = -__exp;
639   } else {
640     _Sign_character = '+';
641   }
642 
643   const int _Exponent_part_length = __exp >= 100
644     ? 5 // "e+NNN"
645     : 4; // "e+NN"
646 
647   if (_Last - _First < _Exponent_part_length) {
648     return { _Last, errc::value_too_large };
649   }
650 
651   *_First++ = 'e';
652   *_First++ = _Sign_character;
653 
654   if (__exp >= 100) {
655     const int32_t __c = __exp % 10;
656     std::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
657     _First[2] = static_cast<char>('0' + __c);
658     _First += 3;
659   } else {
660     std::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
661     _First += 2;
662   }
663 
664   return { _First, errc{} };
665 }
666 
667 _LIBCPP_END_NAMESPACE_STD
668 
669 // clang-format on
670