xref: /freebsd-src/contrib/llvm-project/libcxx/src/ryu/d2fixed.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
20eae32dcSDimitry Andric //
30eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60eae32dcSDimitry Andric //
70eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
80eae32dcSDimitry Andric 
90eae32dcSDimitry Andric // Copyright (c) Microsoft Corporation.
100eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
110eae32dcSDimitry Andric 
120eae32dcSDimitry Andric // Copyright 2018 Ulf Adams
130eae32dcSDimitry Andric // Copyright (c) Microsoft Corporation. All rights reserved.
140eae32dcSDimitry Andric 
150eae32dcSDimitry Andric // Boost Software License - Version 1.0 - August 17th, 2003
160eae32dcSDimitry Andric 
170eae32dcSDimitry Andric // Permission is hereby granted, free of charge, to any person or organization
180eae32dcSDimitry Andric // obtaining a copy of the software and accompanying documentation covered by
190eae32dcSDimitry Andric // this license (the "Software") to use, reproduce, display, distribute,
200eae32dcSDimitry Andric // execute, and transmit the Software, and to prepare derivative works of the
210eae32dcSDimitry Andric // Software, and to permit third-parties to whom the Software is furnished to
220eae32dcSDimitry Andric // do so, all subject to the following:
230eae32dcSDimitry Andric 
240eae32dcSDimitry Andric // The copyright notices in the Software and this entire statement, including
250eae32dcSDimitry Andric // the above license grant, this restriction and the following disclaimer,
260eae32dcSDimitry Andric // must be included in all copies of the Software, in whole or in part, and
270eae32dcSDimitry Andric // all derivative works of the Software, unless such copies or derivative
280eae32dcSDimitry Andric // works are solely in the form of machine-executable object code generated by
290eae32dcSDimitry Andric // a source language processor.
300eae32dcSDimitry Andric 
310eae32dcSDimitry Andric // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
320eae32dcSDimitry Andric // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
330eae32dcSDimitry Andric // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
340eae32dcSDimitry Andric // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
350eae32dcSDimitry Andric // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
360eae32dcSDimitry Andric // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
370eae32dcSDimitry Andric // DEALINGS IN THE SOFTWARE.
380eae32dcSDimitry Andric 
390eae32dcSDimitry Andric // Avoid formatting to keep the changes with the original code minimal.
400eae32dcSDimitry Andric // clang-format off
410eae32dcSDimitry Andric 
42*81ad6265SDimitry Andric #include <__assert>
43*81ad6265SDimitry Andric #include <__config>
44*81ad6265SDimitry Andric #include <charconv>
45*81ad6265SDimitry Andric #include <cstring>
46*81ad6265SDimitry Andric #include <system_error>
470eae32dcSDimitry Andric 
480eae32dcSDimitry Andric #include "include/ryu/common.h"
490eae32dcSDimitry Andric #include "include/ryu/d2fixed.h"
500eae32dcSDimitry Andric #include "include/ryu/d2fixed_full_table.h"
510eae32dcSDimitry Andric #include "include/ryu/d2s.h"
520eae32dcSDimitry Andric #include "include/ryu/d2s_intrinsics.h"
530eae32dcSDimitry Andric #include "include/ryu/digit_table.h"
540eae32dcSDimitry Andric 
550eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
560eae32dcSDimitry Andric 
570eae32dcSDimitry Andric inline constexpr int __POW10_ADDITIONAL_BITS = 120;
580eae32dcSDimitry Andric 
590eae32dcSDimitry Andric #ifdef _LIBCPP_INTRINSIC128
600eae32dcSDimitry Andric // Returns the low 64 bits of the high 128 bits of the 256-bit product of a and b.
610eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __umul256_hi128_lo64(
620eae32dcSDimitry Andric   const uint64_t __aHi, const uint64_t __aLo, const uint64_t __bHi, const uint64_t __bLo) {
630eae32dcSDimitry Andric   uint64_t __b00Hi;
640eae32dcSDimitry Andric   const uint64_t __b00Lo = __ryu_umul128(__aLo, __bLo, &__b00Hi);
650eae32dcSDimitry Andric   uint64_t __b01Hi;
660eae32dcSDimitry Andric   const uint64_t __b01Lo = __ryu_umul128(__aLo, __bHi, &__b01Hi);
670eae32dcSDimitry Andric   uint64_t __b10Hi;
680eae32dcSDimitry Andric   const uint64_t __b10Lo = __ryu_umul128(__aHi, __bLo, &__b10Hi);
690eae32dcSDimitry Andric   uint64_t __b11Hi;
700eae32dcSDimitry Andric   const uint64_t __b11Lo = __ryu_umul128(__aHi, __bHi, &__b11Hi);
710eae32dcSDimitry Andric   (void) __b00Lo; // unused
720eae32dcSDimitry Andric   (void) __b11Hi; // unused
730eae32dcSDimitry Andric   const uint64_t __temp1Lo = __b10Lo + __b00Hi;
740eae32dcSDimitry Andric   const uint64_t __temp1Hi = __b10Hi + (__temp1Lo < __b10Lo);
750eae32dcSDimitry Andric   const uint64_t __temp2Lo = __b01Lo + __temp1Lo;
760eae32dcSDimitry Andric   const uint64_t __temp2Hi = __b01Hi + (__temp2Lo < __b01Lo);
770eae32dcSDimitry Andric   return __b11Lo + __temp1Hi + __temp2Hi;
780eae32dcSDimitry Andric }
790eae32dcSDimitry Andric 
800eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __uint128_mod1e9(const uint64_t __vHi, const uint64_t __vLo) {
810eae32dcSDimitry Andric   // After multiplying, we're going to shift right by 29, then truncate to uint32_t.
820eae32dcSDimitry Andric   // This means that we need only 29 + 32 = 61 bits, so we can truncate to uint64_t before shifting.
830eae32dcSDimitry Andric   const uint64_t __multiplied = __umul256_hi128_lo64(__vHi, __vLo, 0x89705F4136B4A597u, 0x31680A88F8953031u);
840eae32dcSDimitry Andric 
850eae32dcSDimitry Andric   // For uint32_t truncation, see the __mod1e9() comment in d2s_intrinsics.h.
860eae32dcSDimitry Andric   const uint32_t __shifted = static_cast<uint32_t>(__multiplied >> 29);
870eae32dcSDimitry Andric 
880eae32dcSDimitry Andric   return static_cast<uint32_t>(__vLo) - 1000000000 * __shifted;
890eae32dcSDimitry Andric }
900eae32dcSDimitry Andric #endif // ^^^ intrinsics available ^^^
910eae32dcSDimitry Andric 
920eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift_mod1e9(const uint64_t __m, const uint64_t* const __mul, const int32_t __j) {
930eae32dcSDimitry Andric   uint64_t __high0;                                               // 64
940eae32dcSDimitry Andric   const uint64_t __low0 = __ryu_umul128(__m, __mul[0], &__high0); // 0
950eae32dcSDimitry Andric   uint64_t __high1;                                               // 128
960eae32dcSDimitry Andric   const uint64_t __low1 = __ryu_umul128(__m, __mul[1], &__high1); // 64
970eae32dcSDimitry Andric   uint64_t __high2;                                               // 192
980eae32dcSDimitry Andric   const uint64_t __low2 = __ryu_umul128(__m, __mul[2], &__high2); // 128
990eae32dcSDimitry Andric   const uint64_t __s0low = __low0;                  // 0
1000eae32dcSDimitry Andric   (void) __s0low; // unused
1010eae32dcSDimitry Andric   const uint64_t __s0high = __low1 + __high0;       // 64
1020eae32dcSDimitry Andric   const uint32_t __c1 = __s0high < __low1;
1030eae32dcSDimitry Andric   const uint64_t __s1low = __low2 + __high1 + __c1; // 128
1040eae32dcSDimitry Andric   const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2
1050eae32dcSDimitry Andric   const uint64_t __s1high = __high2 + __c2;         // 192
1060eae32dcSDimitry Andric   _LIBCPP_ASSERT(__j >= 128, "");
1070eae32dcSDimitry Andric   _LIBCPP_ASSERT(__j <= 180, "");
1080eae32dcSDimitry Andric #ifdef _LIBCPP_INTRINSIC128
1090eae32dcSDimitry Andric   const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52]
1100eae32dcSDimitry Andric   const uint64_t __shiftedhigh = __s1high >> __dist;
1110eae32dcSDimitry Andric   const uint64_t __shiftedlow = __ryu_shiftright128(__s1low, __s1high, __dist);
1120eae32dcSDimitry Andric   return __uint128_mod1e9(__shiftedhigh, __shiftedlow);
1130eae32dcSDimitry Andric #else // ^^^ intrinsics available ^^^ / vvv intrinsics unavailable vvv
1140eae32dcSDimitry Andric   if (__j < 160) { // __j: [128, 160)
1150eae32dcSDimitry Andric     const uint64_t __r0 = __mod1e9(__s1high);
1160eae32dcSDimitry Andric     const uint64_t __r1 = __mod1e9((__r0 << 32) | (__s1low >> 32));
1170eae32dcSDimitry Andric     const uint64_t __r2 = ((__r1 << 32) | (__s1low & 0xffffffff));
1180eae32dcSDimitry Andric     return __mod1e9(__r2 >> (__j - 128));
1190eae32dcSDimitry Andric   } else { // __j: [160, 192)
1200eae32dcSDimitry Andric     const uint64_t __r0 = __mod1e9(__s1high);
1210eae32dcSDimitry Andric     const uint64_t __r1 = ((__r0 << 32) | (__s1low >> 32));
1220eae32dcSDimitry Andric     return __mod1e9(__r1 >> (__j - 160));
1230eae32dcSDimitry Andric   }
1240eae32dcSDimitry Andric #endif // ^^^ intrinsics unavailable ^^^
1250eae32dcSDimitry Andric }
1260eae32dcSDimitry Andric 
1270eae32dcSDimitry Andric void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const __result) {
1280eae32dcSDimitry Andric   uint32_t __i = 0;
1290eae32dcSDimitry Andric   while (__digits >= 10000) {
1300eae32dcSDimitry Andric #ifdef __clang__ // TRANSITION, LLVM-38217
1310eae32dcSDimitry Andric     const uint32_t __c = __digits - 10000 * (__digits / 10000);
1320eae32dcSDimitry Andric #else
1330eae32dcSDimitry Andric     const uint32_t __c = __digits % 10000;
1340eae32dcSDimitry Andric #endif
1350eae32dcSDimitry Andric     __digits /= 10000;
1360eae32dcSDimitry Andric     const uint32_t __c0 = (__c % 100) << 1;
1370eae32dcSDimitry Andric     const uint32_t __c1 = (__c / 100) << 1;
1380eae32dcSDimitry Andric     _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
1390eae32dcSDimitry Andric     _VSTD::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
1400eae32dcSDimitry Andric     __i += 4;
1410eae32dcSDimitry Andric   }
1420eae32dcSDimitry Andric   if (__digits >= 100) {
1430eae32dcSDimitry Andric     const uint32_t __c = (__digits % 100) << 1;
1440eae32dcSDimitry Andric     __digits /= 100;
1450eae32dcSDimitry Andric     _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
1460eae32dcSDimitry Andric     __i += 2;
1470eae32dcSDimitry Andric   }
1480eae32dcSDimitry Andric   if (__digits >= 10) {
1490eae32dcSDimitry Andric     const uint32_t __c = __digits << 1;
1500eae32dcSDimitry Andric     _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
1510eae32dcSDimitry Andric   } else {
1520eae32dcSDimitry Andric     __result[0] = static_cast<char>('0' + __digits);
1530eae32dcSDimitry Andric   }
1540eae32dcSDimitry Andric }
1550eae32dcSDimitry Andric 
1560eae32dcSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline void __append_d_digits(const uint32_t __olength, uint32_t __digits, char* const __result) {
1570eae32dcSDimitry Andric   uint32_t __i = 0;
1580eae32dcSDimitry Andric   while (__digits >= 10000) {
1590eae32dcSDimitry Andric #ifdef __clang__ // TRANSITION, LLVM-38217
1600eae32dcSDimitry Andric     const uint32_t __c = __digits - 10000 * (__digits / 10000);
1610eae32dcSDimitry Andric #else
1620eae32dcSDimitry Andric     const uint32_t __c = __digits % 10000;
1630eae32dcSDimitry Andric #endif
1640eae32dcSDimitry Andric     __digits /= 10000;
1650eae32dcSDimitry Andric     const uint32_t __c0 = (__c % 100) << 1;
1660eae32dcSDimitry Andric     const uint32_t __c1 = (__c / 100) << 1;
1670eae32dcSDimitry Andric     _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
1680eae32dcSDimitry Andric     _VSTD::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
1690eae32dcSDimitry Andric     __i += 4;
1700eae32dcSDimitry Andric   }
1710eae32dcSDimitry Andric   if (__digits >= 100) {
1720eae32dcSDimitry Andric     const uint32_t __c = (__digits % 100) << 1;
1730eae32dcSDimitry Andric     __digits /= 100;
1740eae32dcSDimitry Andric     _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
1750eae32dcSDimitry Andric     __i += 2;
1760eae32dcSDimitry Andric   }
1770eae32dcSDimitry Andric   if (__digits >= 10) {
1780eae32dcSDimitry Andric     const uint32_t __c = __digits << 1;
1790eae32dcSDimitry Andric     __result[2] = __DIGIT_TABLE[__c + 1];
1800eae32dcSDimitry Andric     __result[1] = '.';
1810eae32dcSDimitry Andric     __result[0] = __DIGIT_TABLE[__c];
1820eae32dcSDimitry Andric   } else {
1830eae32dcSDimitry Andric     __result[1] = '.';
1840eae32dcSDimitry Andric     __result[0] = static_cast<char>('0' + __digits);
1850eae32dcSDimitry Andric   }
1860eae32dcSDimitry Andric }
1870eae32dcSDimitry Andric 
1880eae32dcSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint32_t __digits, char* const __result) {
1890eae32dcSDimitry Andric   uint32_t __i = 0;
1900eae32dcSDimitry Andric   for (; __i < __count - 1; __i += 2) {
1910eae32dcSDimitry Andric     const uint32_t __c = (__digits % 100) << 1;
1920eae32dcSDimitry Andric     __digits /= 100;
1930eae32dcSDimitry Andric     _VSTD::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
1940eae32dcSDimitry Andric   }
1950eae32dcSDimitry Andric   if (__i < __count) {
1960eae32dcSDimitry Andric     const char __c = static_cast<char>('0' + (__digits % 10));
1970eae32dcSDimitry Andric     __result[__count - __i - 1] = __c;
1980eae32dcSDimitry Andric   }
1990eae32dcSDimitry Andric }
2000eae32dcSDimitry Andric 
2010eae32dcSDimitry Andric void __append_nine_digits(uint32_t __digits, char* const __result) {
2020eae32dcSDimitry Andric   if (__digits == 0) {
2030eae32dcSDimitry Andric     _VSTD::memset(__result, '0', 9);
2040eae32dcSDimitry Andric     return;
2050eae32dcSDimitry Andric   }
2060eae32dcSDimitry Andric 
2070eae32dcSDimitry Andric   for (uint32_t __i = 0; __i < 5; __i += 4) {
2080eae32dcSDimitry Andric #ifdef __clang__ // TRANSITION, LLVM-38217
2090eae32dcSDimitry Andric     const uint32_t __c = __digits - 10000 * (__digits / 10000);
2100eae32dcSDimitry Andric #else
2110eae32dcSDimitry Andric     const uint32_t __c = __digits % 10000;
2120eae32dcSDimitry Andric #endif
2130eae32dcSDimitry Andric     __digits /= 10000;
2140eae32dcSDimitry Andric     const uint32_t __c0 = (__c % 100) << 1;
2150eae32dcSDimitry Andric     const uint32_t __c1 = (__c / 100) << 1;
2160eae32dcSDimitry Andric     _VSTD::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
2170eae32dcSDimitry Andric     _VSTD::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
2180eae32dcSDimitry Andric   }
2190eae32dcSDimitry Andric   __result[0] = static_cast<char>('0' + __digits);
2200eae32dcSDimitry Andric }
2210eae32dcSDimitry Andric 
2220eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __indexForExponent(const uint32_t __e) {
2230eae32dcSDimitry Andric   return (__e + 15) / 16;
2240eae32dcSDimitry Andric }
2250eae32dcSDimitry Andric 
2260eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow10BitsForIndex(const uint32_t __idx) {
2270eae32dcSDimitry Andric   return 16 * __idx + __POW10_ADDITIONAL_BITS;
2280eae32dcSDimitry Andric }
2290eae32dcSDimitry Andric 
2300eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __lengthForIndex(const uint32_t __idx) {
2310eae32dcSDimitry Andric   // +1 for ceil, +16 for mantissa, +8 to round up when dividing by 9
2320eae32dcSDimitry Andric   return (__log10Pow2(16 * static_cast<int32_t>(__idx)) + 1 + 16 + 8) / 9;
2330eae32dcSDimitry Andric }
2340eae32dcSDimitry Andric 
2350eae32dcSDimitry Andric [[nodiscard]] to_chars_result __d2fixed_buffered_n(char* _First, char* const _Last, const double __d,
2360eae32dcSDimitry Andric   const uint32_t __precision) {
2370eae32dcSDimitry Andric   char* const _Original_first = _First;
2380eae32dcSDimitry Andric 
2390eae32dcSDimitry Andric   const uint64_t __bits = __double_to_bits(__d);
2400eae32dcSDimitry Andric 
2410eae32dcSDimitry Andric   // Case distinction; exit early for the easy cases.
2420eae32dcSDimitry Andric   if (__bits == 0) {
2430eae32dcSDimitry Andric     const int32_t _Total_zero_length = 1 // leading zero
2440eae32dcSDimitry Andric       + static_cast<int32_t>(__precision != 0) // possible decimal point
2450eae32dcSDimitry Andric       + static_cast<int32_t>(__precision); // zeroes after decimal point
2460eae32dcSDimitry Andric 
2470eae32dcSDimitry Andric     if (_Last - _First < _Total_zero_length) {
2480eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
2490eae32dcSDimitry Andric     }
2500eae32dcSDimitry Andric 
2510eae32dcSDimitry Andric     *_First++ = '0';
2520eae32dcSDimitry Andric     if (__precision > 0) {
2530eae32dcSDimitry Andric       *_First++ = '.';
2540eae32dcSDimitry Andric       _VSTD::memset(_First, '0', __precision);
2550eae32dcSDimitry Andric       _First += __precision;
2560eae32dcSDimitry Andric     }
2570eae32dcSDimitry Andric     return { _First, errc{} };
2580eae32dcSDimitry Andric   }
2590eae32dcSDimitry Andric 
2600eae32dcSDimitry Andric   // Decode __bits into mantissa and exponent.
2610eae32dcSDimitry Andric   const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
2620eae32dcSDimitry Andric   const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
2630eae32dcSDimitry Andric 
2640eae32dcSDimitry Andric   int32_t __e2;
2650eae32dcSDimitry Andric   uint64_t __m2;
2660eae32dcSDimitry Andric   if (__ieeeExponent == 0) {
2670eae32dcSDimitry Andric     __e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
2680eae32dcSDimitry Andric     __m2 = __ieeeMantissa;
2690eae32dcSDimitry Andric   } else {
2700eae32dcSDimitry Andric     __e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
2710eae32dcSDimitry Andric     __m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
2720eae32dcSDimitry Andric   }
2730eae32dcSDimitry Andric 
2740eae32dcSDimitry Andric   bool __nonzero = false;
2750eae32dcSDimitry Andric   if (__e2 >= -52) {
2760eae32dcSDimitry Andric     const uint32_t __idx = __e2 < 0 ? 0 : __indexForExponent(static_cast<uint32_t>(__e2));
2770eae32dcSDimitry Andric     const uint32_t __p10bits = __pow10BitsForIndex(__idx);
2780eae32dcSDimitry Andric     const int32_t __len = static_cast<int32_t>(__lengthForIndex(__idx));
2790eae32dcSDimitry Andric     for (int32_t __i = __len - 1; __i >= 0; --__i) {
2800eae32dcSDimitry Andric       const uint32_t __j = __p10bits - __e2;
2810eae32dcSDimitry Andric       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
2820eae32dcSDimitry Andric       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
2830eae32dcSDimitry Andric       const uint32_t __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT[__POW10_OFFSET[__idx] + __i],
2840eae32dcSDimitry Andric         static_cast<int32_t>(__j + 8));
2850eae32dcSDimitry Andric       if (__nonzero) {
2860eae32dcSDimitry Andric         if (_Last - _First < 9) {
2870eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
2880eae32dcSDimitry Andric         }
2890eae32dcSDimitry Andric         __append_nine_digits(__digits, _First);
2900eae32dcSDimitry Andric         _First += 9;
2910eae32dcSDimitry Andric       } else if (__digits != 0) {
2920eae32dcSDimitry Andric         const uint32_t __olength = __decimalLength9(__digits);
2930eae32dcSDimitry Andric         if (_Last - _First < static_cast<ptrdiff_t>(__olength)) {
2940eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
2950eae32dcSDimitry Andric         }
2960eae32dcSDimitry Andric         __append_n_digits(__olength, __digits, _First);
2970eae32dcSDimitry Andric         _First += __olength;
2980eae32dcSDimitry Andric         __nonzero = true;
2990eae32dcSDimitry Andric       }
3000eae32dcSDimitry Andric     }
3010eae32dcSDimitry Andric   }
3020eae32dcSDimitry Andric   if (!__nonzero) {
3030eae32dcSDimitry Andric     if (_First == _Last) {
3040eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
3050eae32dcSDimitry Andric     }
3060eae32dcSDimitry Andric     *_First++ = '0';
3070eae32dcSDimitry Andric   }
3080eae32dcSDimitry Andric   if (__precision > 0) {
3090eae32dcSDimitry Andric     if (_First == _Last) {
3100eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
3110eae32dcSDimitry Andric     }
3120eae32dcSDimitry Andric     *_First++ = '.';
3130eae32dcSDimitry Andric   }
3140eae32dcSDimitry Andric   if (__e2 < 0) {
3150eae32dcSDimitry Andric     const int32_t __idx = -__e2 / 16;
3160eae32dcSDimitry Andric     const uint32_t __blocks = __precision / 9 + 1;
3170eae32dcSDimitry Andric     // 0 = don't round up; 1 = round up unconditionally; 2 = round up if odd.
3180eae32dcSDimitry Andric     int __roundUp = 0;
3190eae32dcSDimitry Andric     uint32_t __i = 0;
3200eae32dcSDimitry Andric     if (__blocks <= __MIN_BLOCK_2[__idx]) {
3210eae32dcSDimitry Andric       __i = __blocks;
3220eae32dcSDimitry Andric       if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
3230eae32dcSDimitry Andric         return { _Last, errc::value_too_large };
3240eae32dcSDimitry Andric       }
3250eae32dcSDimitry Andric       _VSTD::memset(_First, '0', __precision);
3260eae32dcSDimitry Andric       _First += __precision;
3270eae32dcSDimitry Andric     } else if (__i < __MIN_BLOCK_2[__idx]) {
3280eae32dcSDimitry Andric       __i = __MIN_BLOCK_2[__idx];
3290eae32dcSDimitry Andric       if (_Last - _First < static_cast<ptrdiff_t>(9 * __i)) {
3300eae32dcSDimitry Andric         return { _Last, errc::value_too_large };
3310eae32dcSDimitry Andric       }
3320eae32dcSDimitry Andric       _VSTD::memset(_First, '0', 9 * __i);
3330eae32dcSDimitry Andric       _First += 9 * __i;
3340eae32dcSDimitry Andric     }
3350eae32dcSDimitry Andric     for (; __i < __blocks; ++__i) {
3360eae32dcSDimitry Andric       const int32_t __j = __ADDITIONAL_BITS_2 + (-__e2 - 16 * __idx);
3370eae32dcSDimitry Andric       const uint32_t __p = __POW10_OFFSET_2[__idx] + __i - __MIN_BLOCK_2[__idx];
3380eae32dcSDimitry Andric       if (__p >= __POW10_OFFSET_2[__idx + 1]) {
3390eae32dcSDimitry Andric         // If the remaining digits are all 0, then we might as well use memset.
3400eae32dcSDimitry Andric         // No rounding required in this case.
3410eae32dcSDimitry Andric         const uint32_t __fill = __precision - 9 * __i;
3420eae32dcSDimitry Andric         if (_Last - _First < static_cast<ptrdiff_t>(__fill)) {
3430eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
3440eae32dcSDimitry Andric         }
3450eae32dcSDimitry Andric         _VSTD::memset(_First, '0', __fill);
3460eae32dcSDimitry Andric         _First += __fill;
3470eae32dcSDimitry Andric         break;
3480eae32dcSDimitry Andric       }
3490eae32dcSDimitry Andric       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
3500eae32dcSDimitry Andric       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
3510eae32dcSDimitry Andric       uint32_t __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT_2[__p], __j + 8);
3520eae32dcSDimitry Andric       if (__i < __blocks - 1) {
3530eae32dcSDimitry Andric         if (_Last - _First < 9) {
3540eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
3550eae32dcSDimitry Andric         }
3560eae32dcSDimitry Andric         __append_nine_digits(__digits, _First);
3570eae32dcSDimitry Andric         _First += 9;
3580eae32dcSDimitry Andric       } else {
3590eae32dcSDimitry Andric         const uint32_t __maximum = __precision - 9 * __i;
3600eae32dcSDimitry Andric         uint32_t __lastDigit = 0;
3610eae32dcSDimitry Andric         for (uint32_t __k = 0; __k < 9 - __maximum; ++__k) {
3620eae32dcSDimitry Andric           __lastDigit = __digits % 10;
3630eae32dcSDimitry Andric           __digits /= 10;
3640eae32dcSDimitry Andric         }
3650eae32dcSDimitry Andric         if (__lastDigit != 5) {
3660eae32dcSDimitry Andric           __roundUp = __lastDigit > 5;
3670eae32dcSDimitry Andric         } else {
3680eae32dcSDimitry Andric           // Is m * 10^(additionalDigits + 1) / 2^(-__e2) integer?
3690eae32dcSDimitry Andric           const int32_t __requiredTwos = -__e2 - static_cast<int32_t>(__precision) - 1;
3700eae32dcSDimitry Andric           const bool __trailingZeros = __requiredTwos <= 0
3710eae32dcSDimitry Andric             || (__requiredTwos < 60 && __multipleOfPowerOf2(__m2, static_cast<uint32_t>(__requiredTwos)));
3720eae32dcSDimitry Andric           __roundUp = __trailingZeros ? 2 : 1;
3730eae32dcSDimitry Andric         }
3740eae32dcSDimitry Andric         if (__maximum > 0) {
3750eae32dcSDimitry Andric           if (_Last - _First < static_cast<ptrdiff_t>(__maximum)) {
3760eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
3770eae32dcSDimitry Andric           }
3780eae32dcSDimitry Andric           __append_c_digits(__maximum, __digits, _First);
3790eae32dcSDimitry Andric           _First += __maximum;
3800eae32dcSDimitry Andric         }
3810eae32dcSDimitry Andric         break;
3820eae32dcSDimitry Andric       }
3830eae32dcSDimitry Andric     }
3840eae32dcSDimitry Andric     if (__roundUp != 0) {
3850eae32dcSDimitry Andric       char* _Round = _First;
3860eae32dcSDimitry Andric       char* _Dot = _Last;
3870eae32dcSDimitry Andric       while (true) {
3880eae32dcSDimitry Andric         if (_Round == _Original_first) {
3890eae32dcSDimitry Andric           _Round[0] = '1';
3900eae32dcSDimitry Andric           if (_Dot != _Last) {
3910eae32dcSDimitry Andric             _Dot[0] = '0';
3920eae32dcSDimitry Andric             _Dot[1] = '.';
3930eae32dcSDimitry Andric           }
3940eae32dcSDimitry Andric           if (_First == _Last) {
3950eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
3960eae32dcSDimitry Andric           }
3970eae32dcSDimitry Andric           *_First++ = '0';
3980eae32dcSDimitry Andric           break;
3990eae32dcSDimitry Andric         }
4000eae32dcSDimitry Andric         --_Round;
4010eae32dcSDimitry Andric         const char __c = _Round[0];
4020eae32dcSDimitry Andric         if (__c == '.') {
4030eae32dcSDimitry Andric           _Dot = _Round;
4040eae32dcSDimitry Andric         } else if (__c == '9') {
4050eae32dcSDimitry Andric           _Round[0] = '0';
4060eae32dcSDimitry Andric           __roundUp = 1;
4070eae32dcSDimitry Andric         } else {
4080eae32dcSDimitry Andric           if (__roundUp == 1 || __c % 2 != 0) {
4090eae32dcSDimitry Andric             _Round[0] = __c + 1;
4100eae32dcSDimitry Andric           }
4110eae32dcSDimitry Andric           break;
4120eae32dcSDimitry Andric         }
4130eae32dcSDimitry Andric       }
4140eae32dcSDimitry Andric     }
4150eae32dcSDimitry Andric   } else {
4160eae32dcSDimitry Andric     if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
4170eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
4180eae32dcSDimitry Andric     }
4190eae32dcSDimitry Andric     _VSTD::memset(_First, '0', __precision);
4200eae32dcSDimitry Andric     _First += __precision;
4210eae32dcSDimitry Andric   }
4220eae32dcSDimitry Andric   return { _First, errc{} };
4230eae32dcSDimitry Andric }
4240eae32dcSDimitry Andric 
4250eae32dcSDimitry Andric [[nodiscard]] to_chars_result __d2exp_buffered_n(char* _First, char* const _Last, const double __d,
4260eae32dcSDimitry Andric   uint32_t __precision) {
4270eae32dcSDimitry Andric   char* const _Original_first = _First;
4280eae32dcSDimitry Andric 
4290eae32dcSDimitry Andric   const uint64_t __bits = __double_to_bits(__d);
4300eae32dcSDimitry Andric 
4310eae32dcSDimitry Andric   // Case distinction; exit early for the easy cases.
4320eae32dcSDimitry Andric   if (__bits == 0) {
4330eae32dcSDimitry Andric     const int32_t _Total_zero_length = 1 // leading zero
4340eae32dcSDimitry Andric       + static_cast<int32_t>(__precision != 0) // possible decimal point
4350eae32dcSDimitry Andric       + static_cast<int32_t>(__precision) // zeroes after decimal point
4360eae32dcSDimitry Andric       + 4; // "e+00"
4370eae32dcSDimitry Andric     if (_Last - _First < _Total_zero_length) {
4380eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
4390eae32dcSDimitry Andric     }
4400eae32dcSDimitry Andric     *_First++ = '0';
4410eae32dcSDimitry Andric     if (__precision > 0) {
4420eae32dcSDimitry Andric       *_First++ = '.';
4430eae32dcSDimitry Andric       _VSTD::memset(_First, '0', __precision);
4440eae32dcSDimitry Andric       _First += __precision;
4450eae32dcSDimitry Andric     }
4460eae32dcSDimitry Andric     _VSTD::memcpy(_First, "e+00", 4);
4470eae32dcSDimitry Andric     _First += 4;
4480eae32dcSDimitry Andric     return { _First, errc{} };
4490eae32dcSDimitry Andric   }
4500eae32dcSDimitry Andric 
4510eae32dcSDimitry Andric   // Decode __bits into mantissa and exponent.
4520eae32dcSDimitry Andric   const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
4530eae32dcSDimitry Andric   const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
4540eae32dcSDimitry Andric 
4550eae32dcSDimitry Andric   int32_t __e2;
4560eae32dcSDimitry Andric   uint64_t __m2;
4570eae32dcSDimitry Andric   if (__ieeeExponent == 0) {
4580eae32dcSDimitry Andric     __e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
4590eae32dcSDimitry Andric     __m2 = __ieeeMantissa;
4600eae32dcSDimitry Andric   } else {
4610eae32dcSDimitry Andric     __e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
4620eae32dcSDimitry Andric     __m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
4630eae32dcSDimitry Andric   }
4640eae32dcSDimitry Andric 
4650eae32dcSDimitry Andric   const bool __printDecimalPoint = __precision > 0;
4660eae32dcSDimitry Andric   ++__precision;
4670eae32dcSDimitry Andric   uint32_t __digits = 0;
4680eae32dcSDimitry Andric   uint32_t __printedDigits = 0;
4690eae32dcSDimitry Andric   uint32_t __availableDigits = 0;
4700eae32dcSDimitry Andric   int32_t __exp = 0;
4710eae32dcSDimitry Andric   if (__e2 >= -52) {
4720eae32dcSDimitry Andric     const uint32_t __idx = __e2 < 0 ? 0 : __indexForExponent(static_cast<uint32_t>(__e2));
4730eae32dcSDimitry Andric     const uint32_t __p10bits = __pow10BitsForIndex(__idx);
4740eae32dcSDimitry Andric     const int32_t __len = static_cast<int32_t>(__lengthForIndex(__idx));
4750eae32dcSDimitry Andric     for (int32_t __i = __len - 1; __i >= 0; --__i) {
4760eae32dcSDimitry Andric       const uint32_t __j = __p10bits - __e2;
4770eae32dcSDimitry Andric       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
4780eae32dcSDimitry Andric       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
4790eae32dcSDimitry Andric       __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT[__POW10_OFFSET[__idx] + __i],
4800eae32dcSDimitry Andric         static_cast<int32_t>(__j + 8));
4810eae32dcSDimitry Andric       if (__printedDigits != 0) {
4820eae32dcSDimitry Andric         if (__printedDigits + 9 > __precision) {
4830eae32dcSDimitry Andric           __availableDigits = 9;
4840eae32dcSDimitry Andric           break;
4850eae32dcSDimitry Andric         }
4860eae32dcSDimitry Andric         if (_Last - _First < 9) {
4870eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
4880eae32dcSDimitry Andric         }
4890eae32dcSDimitry Andric         __append_nine_digits(__digits, _First);
4900eae32dcSDimitry Andric         _First += 9;
4910eae32dcSDimitry Andric         __printedDigits += 9;
4920eae32dcSDimitry Andric       } else if (__digits != 0) {
4930eae32dcSDimitry Andric         __availableDigits = __decimalLength9(__digits);
4940eae32dcSDimitry Andric         __exp = __i * 9 + static_cast<int32_t>(__availableDigits) - 1;
4950eae32dcSDimitry Andric         if (__availableDigits > __precision) {
4960eae32dcSDimitry Andric           break;
4970eae32dcSDimitry Andric         }
4980eae32dcSDimitry Andric         if (__printDecimalPoint) {
4990eae32dcSDimitry Andric           if (_Last - _First < static_cast<ptrdiff_t>(__availableDigits + 1)) {
5000eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
5010eae32dcSDimitry Andric           }
5020eae32dcSDimitry Andric           __append_d_digits(__availableDigits, __digits, _First);
5030eae32dcSDimitry Andric           _First += __availableDigits + 1; // +1 for decimal point
5040eae32dcSDimitry Andric         } else {
5050eae32dcSDimitry Andric           if (_First == _Last) {
5060eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
5070eae32dcSDimitry Andric           }
5080eae32dcSDimitry Andric           *_First++ = static_cast<char>('0' + __digits);
5090eae32dcSDimitry Andric         }
5100eae32dcSDimitry Andric         __printedDigits = __availableDigits;
5110eae32dcSDimitry Andric         __availableDigits = 0;
5120eae32dcSDimitry Andric       }
5130eae32dcSDimitry Andric     }
5140eae32dcSDimitry Andric   }
5150eae32dcSDimitry Andric 
5160eae32dcSDimitry Andric   if (__e2 < 0 && __availableDigits == 0) {
5170eae32dcSDimitry Andric     const int32_t __idx = -__e2 / 16;
5180eae32dcSDimitry Andric     for (int32_t __i = __MIN_BLOCK_2[__idx]; __i < 200; ++__i) {
5190eae32dcSDimitry Andric       const int32_t __j = __ADDITIONAL_BITS_2 + (-__e2 - 16 * __idx);
5200eae32dcSDimitry Andric       const uint32_t __p = __POW10_OFFSET_2[__idx] + static_cast<uint32_t>(__i) - __MIN_BLOCK_2[__idx];
5210eae32dcSDimitry Andric       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
5220eae32dcSDimitry Andric       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
5230eae32dcSDimitry Andric       __digits = (__p >= __POW10_OFFSET_2[__idx + 1]) ? 0 : __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT_2[__p], __j + 8);
5240eae32dcSDimitry Andric       if (__printedDigits != 0) {
5250eae32dcSDimitry Andric         if (__printedDigits + 9 > __precision) {
5260eae32dcSDimitry Andric           __availableDigits = 9;
5270eae32dcSDimitry Andric           break;
5280eae32dcSDimitry Andric         }
5290eae32dcSDimitry Andric         if (_Last - _First < 9) {
5300eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
5310eae32dcSDimitry Andric         }
5320eae32dcSDimitry Andric         __append_nine_digits(__digits, _First);
5330eae32dcSDimitry Andric         _First += 9;
5340eae32dcSDimitry Andric         __printedDigits += 9;
5350eae32dcSDimitry Andric       } else if (__digits != 0) {
5360eae32dcSDimitry Andric         __availableDigits = __decimalLength9(__digits);
5370eae32dcSDimitry Andric         __exp = -(__i + 1) * 9 + static_cast<int32_t>(__availableDigits) - 1;
5380eae32dcSDimitry Andric         if (__availableDigits > __precision) {
5390eae32dcSDimitry Andric           break;
5400eae32dcSDimitry Andric         }
5410eae32dcSDimitry Andric         if (__printDecimalPoint) {
5420eae32dcSDimitry Andric           if (_Last - _First < static_cast<ptrdiff_t>(__availableDigits + 1)) {
5430eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
5440eae32dcSDimitry Andric           }
5450eae32dcSDimitry Andric           __append_d_digits(__availableDigits, __digits, _First);
5460eae32dcSDimitry Andric           _First += __availableDigits + 1; // +1 for decimal point
5470eae32dcSDimitry Andric         } else {
5480eae32dcSDimitry Andric           if (_First == _Last) {
5490eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
5500eae32dcSDimitry Andric           }
5510eae32dcSDimitry Andric           *_First++ = static_cast<char>('0' + __digits);
5520eae32dcSDimitry Andric         }
5530eae32dcSDimitry Andric         __printedDigits = __availableDigits;
5540eae32dcSDimitry Andric         __availableDigits = 0;
5550eae32dcSDimitry Andric       }
5560eae32dcSDimitry Andric     }
5570eae32dcSDimitry Andric   }
5580eae32dcSDimitry Andric 
5590eae32dcSDimitry Andric   const uint32_t __maximum = __precision - __printedDigits;
5600eae32dcSDimitry Andric   if (__availableDigits == 0) {
5610eae32dcSDimitry Andric     __digits = 0;
5620eae32dcSDimitry Andric   }
5630eae32dcSDimitry Andric   uint32_t __lastDigit = 0;
5640eae32dcSDimitry Andric   if (__availableDigits > __maximum) {
5650eae32dcSDimitry Andric     for (uint32_t __k = 0; __k < __availableDigits - __maximum; ++__k) {
5660eae32dcSDimitry Andric       __lastDigit = __digits % 10;
5670eae32dcSDimitry Andric       __digits /= 10;
5680eae32dcSDimitry Andric     }
5690eae32dcSDimitry Andric   }
5700eae32dcSDimitry Andric   // 0 = don't round up; 1 = round up unconditionally; 2 = round up if odd.
5710eae32dcSDimitry Andric   int __roundUp = 0;
5720eae32dcSDimitry Andric   if (__lastDigit != 5) {
5730eae32dcSDimitry Andric     __roundUp = __lastDigit > 5;
5740eae32dcSDimitry Andric   } else {
5750eae32dcSDimitry Andric     // Is m * 2^__e2 * 10^(__precision + 1 - __exp) integer?
5760eae32dcSDimitry Andric     // __precision was already increased by 1, so we don't need to write + 1 here.
5770eae32dcSDimitry Andric     const int32_t __rexp = static_cast<int32_t>(__precision) - __exp;
5780eae32dcSDimitry Andric     const int32_t __requiredTwos = -__e2 - __rexp;
5790eae32dcSDimitry Andric     bool __trailingZeros = __requiredTwos <= 0
5800eae32dcSDimitry Andric       || (__requiredTwos < 60 && __multipleOfPowerOf2(__m2, static_cast<uint32_t>(__requiredTwos)));
5810eae32dcSDimitry Andric     if (__rexp < 0) {
5820eae32dcSDimitry Andric       const int32_t __requiredFives = -__rexp;
5830eae32dcSDimitry Andric       __trailingZeros = __trailingZeros && __multipleOfPowerOf5(__m2, static_cast<uint32_t>(__requiredFives));
5840eae32dcSDimitry Andric     }
5850eae32dcSDimitry Andric     __roundUp = __trailingZeros ? 2 : 1;
5860eae32dcSDimitry Andric   }
5870eae32dcSDimitry Andric   if (__printedDigits != 0) {
5880eae32dcSDimitry Andric     if (_Last - _First < static_cast<ptrdiff_t>(__maximum)) {
5890eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
5900eae32dcSDimitry Andric     }
5910eae32dcSDimitry Andric     if (__digits == 0) {
5920eae32dcSDimitry Andric       _VSTD::memset(_First, '0', __maximum);
5930eae32dcSDimitry Andric     } else {
5940eae32dcSDimitry Andric       __append_c_digits(__maximum, __digits, _First);
5950eae32dcSDimitry Andric     }
5960eae32dcSDimitry Andric     _First += __maximum;
5970eae32dcSDimitry Andric   } else {
5980eae32dcSDimitry Andric     if (__printDecimalPoint) {
5990eae32dcSDimitry Andric       if (_Last - _First < static_cast<ptrdiff_t>(__maximum + 1)) {
6000eae32dcSDimitry Andric         return { _Last, errc::value_too_large };
6010eae32dcSDimitry Andric       }
6020eae32dcSDimitry Andric       __append_d_digits(__maximum, __digits, _First);
6030eae32dcSDimitry Andric       _First += __maximum + 1; // +1 for decimal point
6040eae32dcSDimitry Andric     } else {
6050eae32dcSDimitry Andric       if (_First == _Last) {
6060eae32dcSDimitry Andric         return { _Last, errc::value_too_large };
6070eae32dcSDimitry Andric       }
6080eae32dcSDimitry Andric       *_First++ = static_cast<char>('0' + __digits);
6090eae32dcSDimitry Andric     }
6100eae32dcSDimitry Andric   }
6110eae32dcSDimitry Andric   if (__roundUp != 0) {
6120eae32dcSDimitry Andric     char* _Round = _First;
6130eae32dcSDimitry Andric     while (true) {
6140eae32dcSDimitry Andric       if (_Round == _Original_first) {
6150eae32dcSDimitry Andric         _Round[0] = '1';
6160eae32dcSDimitry Andric         ++__exp;
6170eae32dcSDimitry Andric         break;
6180eae32dcSDimitry Andric       }
6190eae32dcSDimitry Andric       --_Round;
6200eae32dcSDimitry Andric       const char __c = _Round[0];
6210eae32dcSDimitry Andric       if (__c == '.') {
6220eae32dcSDimitry Andric         // Keep going.
6230eae32dcSDimitry Andric       } else if (__c == '9') {
6240eae32dcSDimitry Andric         _Round[0] = '0';
6250eae32dcSDimitry Andric         __roundUp = 1;
6260eae32dcSDimitry Andric       } else {
6270eae32dcSDimitry Andric         if (__roundUp == 1 || __c % 2 != 0) {
6280eae32dcSDimitry Andric           _Round[0] = __c + 1;
6290eae32dcSDimitry Andric         }
6300eae32dcSDimitry Andric         break;
6310eae32dcSDimitry Andric       }
6320eae32dcSDimitry Andric     }
6330eae32dcSDimitry Andric   }
6340eae32dcSDimitry Andric 
6350eae32dcSDimitry Andric   char _Sign_character;
6360eae32dcSDimitry Andric 
6370eae32dcSDimitry Andric   if (__exp < 0) {
6380eae32dcSDimitry Andric     _Sign_character = '-';
6390eae32dcSDimitry Andric     __exp = -__exp;
6400eae32dcSDimitry Andric   } else {
6410eae32dcSDimitry Andric     _Sign_character = '+';
6420eae32dcSDimitry Andric   }
6430eae32dcSDimitry Andric 
6440eae32dcSDimitry Andric   const int _Exponent_part_length = __exp >= 100
6450eae32dcSDimitry Andric     ? 5 // "e+NNN"
6460eae32dcSDimitry Andric     : 4; // "e+NN"
6470eae32dcSDimitry Andric 
6480eae32dcSDimitry Andric   if (_Last - _First < _Exponent_part_length) {
6490eae32dcSDimitry Andric     return { _Last, errc::value_too_large };
6500eae32dcSDimitry Andric   }
6510eae32dcSDimitry Andric 
6520eae32dcSDimitry Andric   *_First++ = 'e';
6530eae32dcSDimitry Andric   *_First++ = _Sign_character;
6540eae32dcSDimitry Andric 
6550eae32dcSDimitry Andric   if (__exp >= 100) {
6560eae32dcSDimitry Andric     const int32_t __c = __exp % 10;
6570eae32dcSDimitry Andric     _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
6580eae32dcSDimitry Andric     _First[2] = static_cast<char>('0' + __c);
6590eae32dcSDimitry Andric     _First += 3;
6600eae32dcSDimitry Andric   } else {
6610eae32dcSDimitry Andric     _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
6620eae32dcSDimitry Andric     _First += 2;
6630eae32dcSDimitry Andric   }
6640eae32dcSDimitry Andric 
6650eae32dcSDimitry Andric   return { _First, errc{} };
6660eae32dcSDimitry Andric }
6670eae32dcSDimitry Andric 
6680eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_STD
6690eae32dcSDimitry Andric 
6700eae32dcSDimitry Andric // clang-format on
671