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