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