xref: /freebsd/contrib/llvm-project/libcxx/src/ryu/d2fixed.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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 
4281ad6265SDimitry Andric #include <__assert>
4381ad6265SDimitry Andric #include <__config>
4481ad6265SDimitry Andric #include <charconv>
4581ad6265SDimitry Andric #include <cstring>
460eae32dcSDimitry Andric 
470eae32dcSDimitry Andric #include "include/ryu/common.h"
480eae32dcSDimitry Andric #include "include/ryu/d2fixed.h"
490eae32dcSDimitry Andric #include "include/ryu/d2fixed_full_table.h"
500eae32dcSDimitry Andric #include "include/ryu/d2s.h"
510eae32dcSDimitry Andric #include "include/ryu/d2s_intrinsics.h"
520eae32dcSDimitry Andric #include "include/ryu/digit_table.h"
530eae32dcSDimitry Andric 
540eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
550eae32dcSDimitry Andric 
560eae32dcSDimitry Andric inline constexpr int __POW10_ADDITIONAL_BITS = 120;
570eae32dcSDimitry Andric 
580eae32dcSDimitry Andric #ifdef _LIBCPP_INTRINSIC128
590eae32dcSDimitry Andric // Returns the low 64 bits of the high 128 bits of the 256-bit product of a and b.
600eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __umul256_hi128_lo64(
610eae32dcSDimitry Andric   const uint64_t __aHi, const uint64_t __aLo, const uint64_t __bHi, const uint64_t __bLo) {
620eae32dcSDimitry Andric   uint64_t __b00Hi;
630eae32dcSDimitry Andric   const uint64_t __b00Lo = __ryu_umul128(__aLo, __bLo, &__b00Hi);
640eae32dcSDimitry Andric   uint64_t __b01Hi;
650eae32dcSDimitry Andric   const uint64_t __b01Lo = __ryu_umul128(__aLo, __bHi, &__b01Hi);
660eae32dcSDimitry Andric   uint64_t __b10Hi;
670eae32dcSDimitry Andric   const uint64_t __b10Lo = __ryu_umul128(__aHi, __bLo, &__b10Hi);
680eae32dcSDimitry Andric   uint64_t __b11Hi;
690eae32dcSDimitry Andric   const uint64_t __b11Lo = __ryu_umul128(__aHi, __bHi, &__b11Hi);
700eae32dcSDimitry Andric   (void) __b00Lo; // unused
710eae32dcSDimitry Andric   (void) __b11Hi; // unused
720eae32dcSDimitry Andric   const uint64_t __temp1Lo = __b10Lo + __b00Hi;
730eae32dcSDimitry Andric   const uint64_t __temp1Hi = __b10Hi + (__temp1Lo < __b10Lo);
740eae32dcSDimitry Andric   const uint64_t __temp2Lo = __b01Lo + __temp1Lo;
750eae32dcSDimitry Andric   const uint64_t __temp2Hi = __b01Hi + (__temp2Lo < __b01Lo);
760eae32dcSDimitry Andric   return __b11Lo + __temp1Hi + __temp2Hi;
770eae32dcSDimitry Andric }
780eae32dcSDimitry Andric 
790eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __uint128_mod1e9(const uint64_t __vHi, const uint64_t __vLo) {
800eae32dcSDimitry Andric   // After multiplying, we're going to shift right by 29, then truncate to uint32_t.
810eae32dcSDimitry Andric   // This means that we need only 29 + 32 = 61 bits, so we can truncate to uint64_t before shifting.
820eae32dcSDimitry Andric   const uint64_t __multiplied = __umul256_hi128_lo64(__vHi, __vLo, 0x89705F4136B4A597u, 0x31680A88F8953031u);
830eae32dcSDimitry Andric 
840eae32dcSDimitry Andric   // For uint32_t truncation, see the __mod1e9() comment in d2s_intrinsics.h.
850eae32dcSDimitry Andric   const uint32_t __shifted = static_cast<uint32_t>(__multiplied >> 29);
860eae32dcSDimitry Andric 
870eae32dcSDimitry Andric   return static_cast<uint32_t>(__vLo) - 1000000000 * __shifted;
880eae32dcSDimitry Andric }
890eae32dcSDimitry Andric #endif // ^^^ intrinsics available ^^^
900eae32dcSDimitry Andric 
910eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift_mod1e9(const uint64_t __m, const uint64_t* const __mul, const int32_t __j) {
920eae32dcSDimitry Andric   uint64_t __high0;                                               // 64
930eae32dcSDimitry Andric   const uint64_t __low0 = __ryu_umul128(__m, __mul[0], &__high0); // 0
940eae32dcSDimitry Andric   uint64_t __high1;                                               // 128
950eae32dcSDimitry Andric   const uint64_t __low1 = __ryu_umul128(__m, __mul[1], &__high1); // 64
960eae32dcSDimitry Andric   uint64_t __high2;                                               // 192
970eae32dcSDimitry Andric   const uint64_t __low2 = __ryu_umul128(__m, __mul[2], &__high2); // 128
980eae32dcSDimitry Andric   const uint64_t __s0low = __low0;                  // 0
990eae32dcSDimitry Andric   (void) __s0low; // unused
1000eae32dcSDimitry Andric   const uint64_t __s0high = __low1 + __high0;       // 64
1010eae32dcSDimitry Andric   const uint32_t __c1 = __s0high < __low1;
1020eae32dcSDimitry Andric   const uint64_t __s1low = __low2 + __high1 + __c1; // 128
1030eae32dcSDimitry Andric   const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2
1040eae32dcSDimitry Andric   const uint64_t __s1high = __high2 + __c2;         // 192
105*5f757f3fSDimitry Andric   _LIBCPP_ASSERT_INTERNAL(__j >= 128, "");
106*5f757f3fSDimitry Andric   _LIBCPP_ASSERT_INTERNAL(__j <= 180, "");
1070eae32dcSDimitry Andric #ifdef _LIBCPP_INTRINSIC128
1080eae32dcSDimitry Andric   const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52]
1090eae32dcSDimitry Andric   const uint64_t __shiftedhigh = __s1high >> __dist;
1100eae32dcSDimitry Andric   const uint64_t __shiftedlow = __ryu_shiftright128(__s1low, __s1high, __dist);
1110eae32dcSDimitry Andric   return __uint128_mod1e9(__shiftedhigh, __shiftedlow);
1120eae32dcSDimitry Andric #else // ^^^ intrinsics available ^^^ / vvv intrinsics unavailable vvv
1130eae32dcSDimitry Andric   if (__j < 160) { // __j: [128, 160)
1140eae32dcSDimitry Andric     const uint64_t __r0 = __mod1e9(__s1high);
1150eae32dcSDimitry Andric     const uint64_t __r1 = __mod1e9((__r0 << 32) | (__s1low >> 32));
1160eae32dcSDimitry Andric     const uint64_t __r2 = ((__r1 << 32) | (__s1low & 0xffffffff));
1170eae32dcSDimitry Andric     return __mod1e9(__r2 >> (__j - 128));
1180eae32dcSDimitry Andric   } else { // __j: [160, 192)
1190eae32dcSDimitry Andric     const uint64_t __r0 = __mod1e9(__s1high);
1200eae32dcSDimitry Andric     const uint64_t __r1 = ((__r0 << 32) | (__s1low >> 32));
1210eae32dcSDimitry Andric     return __mod1e9(__r1 >> (__j - 160));
1220eae32dcSDimitry Andric   }
1230eae32dcSDimitry Andric #endif // ^^^ intrinsics unavailable ^^^
1240eae32dcSDimitry Andric }
1250eae32dcSDimitry Andric 
1260eae32dcSDimitry Andric void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const __result) {
1270eae32dcSDimitry Andric   uint32_t __i = 0;
1280eae32dcSDimitry Andric   while (__digits >= 10000) {
1290eae32dcSDimitry Andric #ifdef __clang__ // TRANSITION, LLVM-38217
1300eae32dcSDimitry Andric     const uint32_t __c = __digits - 10000 * (__digits / 10000);
1310eae32dcSDimitry Andric #else
1320eae32dcSDimitry Andric     const uint32_t __c = __digits % 10000;
1330eae32dcSDimitry Andric #endif
1340eae32dcSDimitry Andric     __digits /= 10000;
1350eae32dcSDimitry Andric     const uint32_t __c0 = (__c % 100) << 1;
1360eae32dcSDimitry Andric     const uint32_t __c1 = (__c / 100) << 1;
13706c3fb27SDimitry Andric     std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
13806c3fb27SDimitry Andric     std::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
1390eae32dcSDimitry Andric     __i += 4;
1400eae32dcSDimitry Andric   }
1410eae32dcSDimitry Andric   if (__digits >= 100) {
1420eae32dcSDimitry Andric     const uint32_t __c = (__digits % 100) << 1;
1430eae32dcSDimitry Andric     __digits /= 100;
14406c3fb27SDimitry Andric     std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
1450eae32dcSDimitry Andric     __i += 2;
1460eae32dcSDimitry Andric   }
1470eae32dcSDimitry Andric   if (__digits >= 10) {
1480eae32dcSDimitry Andric     const uint32_t __c = __digits << 1;
14906c3fb27SDimitry Andric     std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
1500eae32dcSDimitry Andric   } else {
1510eae32dcSDimitry Andric     __result[0] = static_cast<char>('0' + __digits);
1520eae32dcSDimitry Andric   }
1530eae32dcSDimitry Andric }
1540eae32dcSDimitry Andric 
1550eae32dcSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline void __append_d_digits(const uint32_t __olength, uint32_t __digits, char* const __result) {
1560eae32dcSDimitry Andric   uint32_t __i = 0;
1570eae32dcSDimitry Andric   while (__digits >= 10000) {
1580eae32dcSDimitry Andric #ifdef __clang__ // TRANSITION, LLVM-38217
1590eae32dcSDimitry Andric     const uint32_t __c = __digits - 10000 * (__digits / 10000);
1600eae32dcSDimitry Andric #else
1610eae32dcSDimitry Andric     const uint32_t __c = __digits % 10000;
1620eae32dcSDimitry Andric #endif
1630eae32dcSDimitry Andric     __digits /= 10000;
1640eae32dcSDimitry Andric     const uint32_t __c0 = (__c % 100) << 1;
1650eae32dcSDimitry Andric     const uint32_t __c1 = (__c / 100) << 1;
16606c3fb27SDimitry Andric     std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
16706c3fb27SDimitry Andric     std::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
1680eae32dcSDimitry Andric     __i += 4;
1690eae32dcSDimitry Andric   }
1700eae32dcSDimitry Andric   if (__digits >= 100) {
1710eae32dcSDimitry Andric     const uint32_t __c = (__digits % 100) << 1;
1720eae32dcSDimitry Andric     __digits /= 100;
17306c3fb27SDimitry Andric     std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
1740eae32dcSDimitry Andric     __i += 2;
1750eae32dcSDimitry Andric   }
1760eae32dcSDimitry Andric   if (__digits >= 10) {
1770eae32dcSDimitry Andric     const uint32_t __c = __digits << 1;
1780eae32dcSDimitry Andric     __result[2] = __DIGIT_TABLE[__c + 1];
1790eae32dcSDimitry Andric     __result[1] = '.';
1800eae32dcSDimitry Andric     __result[0] = __DIGIT_TABLE[__c];
1810eae32dcSDimitry Andric   } else {
1820eae32dcSDimitry Andric     __result[1] = '.';
1830eae32dcSDimitry Andric     __result[0] = static_cast<char>('0' + __digits);
1840eae32dcSDimitry Andric   }
1850eae32dcSDimitry Andric }
1860eae32dcSDimitry Andric 
1870eae32dcSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint32_t __digits, char* const __result) {
1880eae32dcSDimitry Andric   uint32_t __i = 0;
1890eae32dcSDimitry Andric   for (; __i < __count - 1; __i += 2) {
1900eae32dcSDimitry Andric     const uint32_t __c = (__digits % 100) << 1;
1910eae32dcSDimitry Andric     __digits /= 100;
19206c3fb27SDimitry Andric     std::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
1930eae32dcSDimitry Andric   }
1940eae32dcSDimitry Andric   if (__i < __count) {
1950eae32dcSDimitry Andric     const char __c = static_cast<char>('0' + (__digits % 10));
1960eae32dcSDimitry Andric     __result[__count - __i - 1] = __c;
1970eae32dcSDimitry Andric   }
1980eae32dcSDimitry Andric }
1990eae32dcSDimitry Andric 
2000eae32dcSDimitry Andric void __append_nine_digits(uint32_t __digits, char* const __result) {
2010eae32dcSDimitry Andric   if (__digits == 0) {
20206c3fb27SDimitry Andric     std::memset(__result, '0', 9);
2030eae32dcSDimitry Andric     return;
2040eae32dcSDimitry Andric   }
2050eae32dcSDimitry Andric 
2060eae32dcSDimitry Andric   for (uint32_t __i = 0; __i < 5; __i += 4) {
2070eae32dcSDimitry Andric #ifdef __clang__ // TRANSITION, LLVM-38217
2080eae32dcSDimitry Andric     const uint32_t __c = __digits - 10000 * (__digits / 10000);
2090eae32dcSDimitry Andric #else
2100eae32dcSDimitry Andric     const uint32_t __c = __digits % 10000;
2110eae32dcSDimitry Andric #endif
2120eae32dcSDimitry Andric     __digits /= 10000;
2130eae32dcSDimitry Andric     const uint32_t __c0 = (__c % 100) << 1;
2140eae32dcSDimitry Andric     const uint32_t __c1 = (__c / 100) << 1;
21506c3fb27SDimitry Andric     std::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
21606c3fb27SDimitry Andric     std::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
2170eae32dcSDimitry Andric   }
2180eae32dcSDimitry Andric   __result[0] = static_cast<char>('0' + __digits);
2190eae32dcSDimitry Andric }
2200eae32dcSDimitry Andric 
2210eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __indexForExponent(const uint32_t __e) {
2220eae32dcSDimitry Andric   return (__e + 15) / 16;
2230eae32dcSDimitry Andric }
2240eae32dcSDimitry Andric 
2250eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow10BitsForIndex(const uint32_t __idx) {
2260eae32dcSDimitry Andric   return 16 * __idx + __POW10_ADDITIONAL_BITS;
2270eae32dcSDimitry Andric }
2280eae32dcSDimitry Andric 
2290eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __lengthForIndex(const uint32_t __idx) {
2300eae32dcSDimitry Andric   // +1 for ceil, +16 for mantissa, +8 to round up when dividing by 9
2310eae32dcSDimitry Andric   return (__log10Pow2(16 * static_cast<int32_t>(__idx)) + 1 + 16 + 8) / 9;
2320eae32dcSDimitry Andric }
2330eae32dcSDimitry Andric 
2340eae32dcSDimitry Andric [[nodiscard]] to_chars_result __d2fixed_buffered_n(char* _First, char* const _Last, const double __d,
2350eae32dcSDimitry Andric   const uint32_t __precision) {
2360eae32dcSDimitry Andric   char* const _Original_first = _First;
2370eae32dcSDimitry Andric 
2380eae32dcSDimitry Andric   const uint64_t __bits = __double_to_bits(__d);
2390eae32dcSDimitry Andric 
2400eae32dcSDimitry Andric   // Case distinction; exit early for the easy cases.
2410eae32dcSDimitry Andric   if (__bits == 0) {
2420eae32dcSDimitry Andric     const int32_t _Total_zero_length = 1 // leading zero
2430eae32dcSDimitry Andric       + static_cast<int32_t>(__precision != 0) // possible decimal point
2440eae32dcSDimitry Andric       + static_cast<int32_t>(__precision); // zeroes after decimal point
2450eae32dcSDimitry Andric 
2460eae32dcSDimitry Andric     if (_Last - _First < _Total_zero_length) {
2470eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
2480eae32dcSDimitry Andric     }
2490eae32dcSDimitry Andric 
2500eae32dcSDimitry Andric     *_First++ = '0';
2510eae32dcSDimitry Andric     if (__precision > 0) {
2520eae32dcSDimitry Andric       *_First++ = '.';
25306c3fb27SDimitry Andric       std::memset(_First, '0', __precision);
2540eae32dcSDimitry Andric       _First += __precision;
2550eae32dcSDimitry Andric     }
2560eae32dcSDimitry Andric     return { _First, errc{} };
2570eae32dcSDimitry Andric   }
2580eae32dcSDimitry Andric 
2590eae32dcSDimitry Andric   // Decode __bits into mantissa and exponent.
2600eae32dcSDimitry Andric   const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
2610eae32dcSDimitry Andric   const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
2620eae32dcSDimitry Andric 
2630eae32dcSDimitry Andric   int32_t __e2;
2640eae32dcSDimitry Andric   uint64_t __m2;
2650eae32dcSDimitry Andric   if (__ieeeExponent == 0) {
2660eae32dcSDimitry Andric     __e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
2670eae32dcSDimitry Andric     __m2 = __ieeeMantissa;
2680eae32dcSDimitry Andric   } else {
2690eae32dcSDimitry Andric     __e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
2700eae32dcSDimitry Andric     __m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
2710eae32dcSDimitry Andric   }
2720eae32dcSDimitry Andric 
2730eae32dcSDimitry Andric   bool __nonzero = false;
2740eae32dcSDimitry Andric   if (__e2 >= -52) {
2750eae32dcSDimitry Andric     const uint32_t __idx = __e2 < 0 ? 0 : __indexForExponent(static_cast<uint32_t>(__e2));
2760eae32dcSDimitry Andric     const uint32_t __p10bits = __pow10BitsForIndex(__idx);
2770eae32dcSDimitry Andric     const int32_t __len = static_cast<int32_t>(__lengthForIndex(__idx));
2780eae32dcSDimitry Andric     for (int32_t __i = __len - 1; __i >= 0; --__i) {
2790eae32dcSDimitry Andric       const uint32_t __j = __p10bits - __e2;
2800eae32dcSDimitry Andric       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
2810eae32dcSDimitry Andric       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
2820eae32dcSDimitry Andric       const uint32_t __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT[__POW10_OFFSET[__idx] + __i],
2830eae32dcSDimitry Andric         static_cast<int32_t>(__j + 8));
2840eae32dcSDimitry Andric       if (__nonzero) {
2850eae32dcSDimitry Andric         if (_Last - _First < 9) {
2860eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
2870eae32dcSDimitry Andric         }
2880eae32dcSDimitry Andric         __append_nine_digits(__digits, _First);
2890eae32dcSDimitry Andric         _First += 9;
2900eae32dcSDimitry Andric       } else if (__digits != 0) {
2910eae32dcSDimitry Andric         const uint32_t __olength = __decimalLength9(__digits);
2920eae32dcSDimitry Andric         if (_Last - _First < static_cast<ptrdiff_t>(__olength)) {
2930eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
2940eae32dcSDimitry Andric         }
2950eae32dcSDimitry Andric         __append_n_digits(__olength, __digits, _First);
2960eae32dcSDimitry Andric         _First += __olength;
2970eae32dcSDimitry Andric         __nonzero = true;
2980eae32dcSDimitry Andric       }
2990eae32dcSDimitry Andric     }
3000eae32dcSDimitry Andric   }
3010eae32dcSDimitry Andric   if (!__nonzero) {
3020eae32dcSDimitry Andric     if (_First == _Last) {
3030eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
3040eae32dcSDimitry Andric     }
3050eae32dcSDimitry Andric     *_First++ = '0';
3060eae32dcSDimitry Andric   }
3070eae32dcSDimitry Andric   if (__precision > 0) {
3080eae32dcSDimitry Andric     if (_First == _Last) {
3090eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
3100eae32dcSDimitry Andric     }
3110eae32dcSDimitry Andric     *_First++ = '.';
3120eae32dcSDimitry Andric   }
3130eae32dcSDimitry Andric   if (__e2 < 0) {
3140eae32dcSDimitry Andric     const int32_t __idx = -__e2 / 16;
3150eae32dcSDimitry Andric     const uint32_t __blocks = __precision / 9 + 1;
3160eae32dcSDimitry Andric     // 0 = don't round up; 1 = round up unconditionally; 2 = round up if odd.
3170eae32dcSDimitry Andric     int __roundUp = 0;
3180eae32dcSDimitry Andric     uint32_t __i = 0;
3190eae32dcSDimitry Andric     if (__blocks <= __MIN_BLOCK_2[__idx]) {
3200eae32dcSDimitry Andric       __i = __blocks;
3210eae32dcSDimitry Andric       if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
3220eae32dcSDimitry Andric         return { _Last, errc::value_too_large };
3230eae32dcSDimitry Andric       }
32406c3fb27SDimitry Andric       std::memset(_First, '0', __precision);
3250eae32dcSDimitry Andric       _First += __precision;
3260eae32dcSDimitry Andric     } else if (__i < __MIN_BLOCK_2[__idx]) {
3270eae32dcSDimitry Andric       __i = __MIN_BLOCK_2[__idx];
3280eae32dcSDimitry Andric       if (_Last - _First < static_cast<ptrdiff_t>(9 * __i)) {
3290eae32dcSDimitry Andric         return { _Last, errc::value_too_large };
3300eae32dcSDimitry Andric       }
33106c3fb27SDimitry Andric       std::memset(_First, '0', 9 * __i);
3320eae32dcSDimitry Andric       _First += 9 * __i;
3330eae32dcSDimitry Andric     }
3340eae32dcSDimitry Andric     for (; __i < __blocks; ++__i) {
3350eae32dcSDimitry Andric       const int32_t __j = __ADDITIONAL_BITS_2 + (-__e2 - 16 * __idx);
3360eae32dcSDimitry Andric       const uint32_t __p = __POW10_OFFSET_2[__idx] + __i - __MIN_BLOCK_2[__idx];
3370eae32dcSDimitry Andric       if (__p >= __POW10_OFFSET_2[__idx + 1]) {
3380eae32dcSDimitry Andric         // If the remaining digits are all 0, then we might as well use memset.
3390eae32dcSDimitry Andric         // No rounding required in this case.
3400eae32dcSDimitry Andric         const uint32_t __fill = __precision - 9 * __i;
3410eae32dcSDimitry Andric         if (_Last - _First < static_cast<ptrdiff_t>(__fill)) {
3420eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
3430eae32dcSDimitry Andric         }
34406c3fb27SDimitry Andric         std::memset(_First, '0', __fill);
3450eae32dcSDimitry Andric         _First += __fill;
3460eae32dcSDimitry Andric         break;
3470eae32dcSDimitry Andric       }
3480eae32dcSDimitry Andric       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
3490eae32dcSDimitry Andric       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
3500eae32dcSDimitry Andric       uint32_t __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT_2[__p], __j + 8);
3510eae32dcSDimitry Andric       if (__i < __blocks - 1) {
3520eae32dcSDimitry Andric         if (_Last - _First < 9) {
3530eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
3540eae32dcSDimitry Andric         }
3550eae32dcSDimitry Andric         __append_nine_digits(__digits, _First);
3560eae32dcSDimitry Andric         _First += 9;
3570eae32dcSDimitry Andric       } else {
3580eae32dcSDimitry Andric         const uint32_t __maximum = __precision - 9 * __i;
3590eae32dcSDimitry Andric         uint32_t __lastDigit = 0;
3600eae32dcSDimitry Andric         for (uint32_t __k = 0; __k < 9 - __maximum; ++__k) {
3610eae32dcSDimitry Andric           __lastDigit = __digits % 10;
3620eae32dcSDimitry Andric           __digits /= 10;
3630eae32dcSDimitry Andric         }
3640eae32dcSDimitry Andric         if (__lastDigit != 5) {
3650eae32dcSDimitry Andric           __roundUp = __lastDigit > 5;
3660eae32dcSDimitry Andric         } else {
3670eae32dcSDimitry Andric           // Is m * 10^(additionalDigits + 1) / 2^(-__e2) integer?
3680eae32dcSDimitry Andric           const int32_t __requiredTwos = -__e2 - static_cast<int32_t>(__precision) - 1;
3690eae32dcSDimitry Andric           const bool __trailingZeros = __requiredTwos <= 0
3700eae32dcSDimitry Andric             || (__requiredTwos < 60 && __multipleOfPowerOf2(__m2, static_cast<uint32_t>(__requiredTwos)));
3710eae32dcSDimitry Andric           __roundUp = __trailingZeros ? 2 : 1;
3720eae32dcSDimitry Andric         }
3730eae32dcSDimitry Andric         if (__maximum > 0) {
3740eae32dcSDimitry Andric           if (_Last - _First < static_cast<ptrdiff_t>(__maximum)) {
3750eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
3760eae32dcSDimitry Andric           }
3770eae32dcSDimitry Andric           __append_c_digits(__maximum, __digits, _First);
3780eae32dcSDimitry Andric           _First += __maximum;
3790eae32dcSDimitry Andric         }
3800eae32dcSDimitry Andric         break;
3810eae32dcSDimitry Andric       }
3820eae32dcSDimitry Andric     }
3830eae32dcSDimitry Andric     if (__roundUp != 0) {
3840eae32dcSDimitry Andric       char* _Round = _First;
3850eae32dcSDimitry Andric       char* _Dot = _Last;
3860eae32dcSDimitry Andric       while (true) {
3870eae32dcSDimitry Andric         if (_Round == _Original_first) {
3880eae32dcSDimitry Andric           _Round[0] = '1';
3890eae32dcSDimitry Andric           if (_Dot != _Last) {
3900eae32dcSDimitry Andric             _Dot[0] = '0';
3910eae32dcSDimitry Andric             _Dot[1] = '.';
3920eae32dcSDimitry Andric           }
3930eae32dcSDimitry Andric           if (_First == _Last) {
3940eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
3950eae32dcSDimitry Andric           }
3960eae32dcSDimitry Andric           *_First++ = '0';
3970eae32dcSDimitry Andric           break;
3980eae32dcSDimitry Andric         }
3990eae32dcSDimitry Andric         --_Round;
4000eae32dcSDimitry Andric         const char __c = _Round[0];
4010eae32dcSDimitry Andric         if (__c == '.') {
4020eae32dcSDimitry Andric           _Dot = _Round;
4030eae32dcSDimitry Andric         } else if (__c == '9') {
4040eae32dcSDimitry Andric           _Round[0] = '0';
4050eae32dcSDimitry Andric           __roundUp = 1;
4060eae32dcSDimitry Andric         } else {
4070eae32dcSDimitry Andric           if (__roundUp == 1 || __c % 2 != 0) {
4080eae32dcSDimitry Andric             _Round[0] = __c + 1;
4090eae32dcSDimitry Andric           }
4100eae32dcSDimitry Andric           break;
4110eae32dcSDimitry Andric         }
4120eae32dcSDimitry Andric       }
4130eae32dcSDimitry Andric     }
4140eae32dcSDimitry Andric   } else {
4150eae32dcSDimitry Andric     if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
4160eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
4170eae32dcSDimitry Andric     }
41806c3fb27SDimitry Andric     std::memset(_First, '0', __precision);
4190eae32dcSDimitry Andric     _First += __precision;
4200eae32dcSDimitry Andric   }
4210eae32dcSDimitry Andric   return { _First, errc{} };
4220eae32dcSDimitry Andric }
4230eae32dcSDimitry Andric 
4240eae32dcSDimitry Andric [[nodiscard]] to_chars_result __d2exp_buffered_n(char* _First, char* const _Last, const double __d,
4250eae32dcSDimitry Andric   uint32_t __precision) {
4260eae32dcSDimitry Andric   char* const _Original_first = _First;
4270eae32dcSDimitry Andric 
4280eae32dcSDimitry Andric   const uint64_t __bits = __double_to_bits(__d);
4290eae32dcSDimitry Andric 
4300eae32dcSDimitry Andric   // Case distinction; exit early for the easy cases.
4310eae32dcSDimitry Andric   if (__bits == 0) {
4320eae32dcSDimitry Andric     const int32_t _Total_zero_length = 1 // leading zero
4330eae32dcSDimitry Andric       + static_cast<int32_t>(__precision != 0) // possible decimal point
4340eae32dcSDimitry Andric       + static_cast<int32_t>(__precision) // zeroes after decimal point
4350eae32dcSDimitry Andric       + 4; // "e+00"
4360eae32dcSDimitry Andric     if (_Last - _First < _Total_zero_length) {
4370eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
4380eae32dcSDimitry Andric     }
4390eae32dcSDimitry Andric     *_First++ = '0';
4400eae32dcSDimitry Andric     if (__precision > 0) {
4410eae32dcSDimitry Andric       *_First++ = '.';
44206c3fb27SDimitry Andric       std::memset(_First, '0', __precision);
4430eae32dcSDimitry Andric       _First += __precision;
4440eae32dcSDimitry Andric     }
44506c3fb27SDimitry Andric     std::memcpy(_First, "e+00", 4);
4460eae32dcSDimitry Andric     _First += 4;
4470eae32dcSDimitry Andric     return { _First, errc{} };
4480eae32dcSDimitry Andric   }
4490eae32dcSDimitry Andric 
4500eae32dcSDimitry Andric   // Decode __bits into mantissa and exponent.
4510eae32dcSDimitry Andric   const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
4520eae32dcSDimitry Andric   const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
4530eae32dcSDimitry Andric 
4540eae32dcSDimitry Andric   int32_t __e2;
4550eae32dcSDimitry Andric   uint64_t __m2;
4560eae32dcSDimitry Andric   if (__ieeeExponent == 0) {
4570eae32dcSDimitry Andric     __e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
4580eae32dcSDimitry Andric     __m2 = __ieeeMantissa;
4590eae32dcSDimitry Andric   } else {
4600eae32dcSDimitry Andric     __e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
4610eae32dcSDimitry Andric     __m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
4620eae32dcSDimitry Andric   }
4630eae32dcSDimitry Andric 
4640eae32dcSDimitry Andric   const bool __printDecimalPoint = __precision > 0;
4650eae32dcSDimitry Andric   ++__precision;
4660eae32dcSDimitry Andric   uint32_t __digits = 0;
4670eae32dcSDimitry Andric   uint32_t __printedDigits = 0;
4680eae32dcSDimitry Andric   uint32_t __availableDigits = 0;
4690eae32dcSDimitry Andric   int32_t __exp = 0;
4700eae32dcSDimitry Andric   if (__e2 >= -52) {
4710eae32dcSDimitry Andric     const uint32_t __idx = __e2 < 0 ? 0 : __indexForExponent(static_cast<uint32_t>(__e2));
4720eae32dcSDimitry Andric     const uint32_t __p10bits = __pow10BitsForIndex(__idx);
4730eae32dcSDimitry Andric     const int32_t __len = static_cast<int32_t>(__lengthForIndex(__idx));
4740eae32dcSDimitry Andric     for (int32_t __i = __len - 1; __i >= 0; --__i) {
4750eae32dcSDimitry Andric       const uint32_t __j = __p10bits - __e2;
4760eae32dcSDimitry Andric       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
4770eae32dcSDimitry Andric       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
4780eae32dcSDimitry Andric       __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT[__POW10_OFFSET[__idx] + __i],
4790eae32dcSDimitry Andric         static_cast<int32_t>(__j + 8));
4800eae32dcSDimitry Andric       if (__printedDigits != 0) {
4810eae32dcSDimitry Andric         if (__printedDigits + 9 > __precision) {
4820eae32dcSDimitry Andric           __availableDigits = 9;
4830eae32dcSDimitry Andric           break;
4840eae32dcSDimitry Andric         }
4850eae32dcSDimitry Andric         if (_Last - _First < 9) {
4860eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
4870eae32dcSDimitry Andric         }
4880eae32dcSDimitry Andric         __append_nine_digits(__digits, _First);
4890eae32dcSDimitry Andric         _First += 9;
4900eae32dcSDimitry Andric         __printedDigits += 9;
4910eae32dcSDimitry Andric       } else if (__digits != 0) {
4920eae32dcSDimitry Andric         __availableDigits = __decimalLength9(__digits);
4930eae32dcSDimitry Andric         __exp = __i * 9 + static_cast<int32_t>(__availableDigits) - 1;
4940eae32dcSDimitry Andric         if (__availableDigits > __precision) {
4950eae32dcSDimitry Andric           break;
4960eae32dcSDimitry Andric         }
4970eae32dcSDimitry Andric         if (__printDecimalPoint) {
4980eae32dcSDimitry Andric           if (_Last - _First < static_cast<ptrdiff_t>(__availableDigits + 1)) {
4990eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
5000eae32dcSDimitry Andric           }
5010eae32dcSDimitry Andric           __append_d_digits(__availableDigits, __digits, _First);
5020eae32dcSDimitry Andric           _First += __availableDigits + 1; // +1 for decimal point
5030eae32dcSDimitry Andric         } else {
5040eae32dcSDimitry Andric           if (_First == _Last) {
5050eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
5060eae32dcSDimitry Andric           }
5070eae32dcSDimitry Andric           *_First++ = static_cast<char>('0' + __digits);
5080eae32dcSDimitry Andric         }
5090eae32dcSDimitry Andric         __printedDigits = __availableDigits;
5100eae32dcSDimitry Andric         __availableDigits = 0;
5110eae32dcSDimitry Andric       }
5120eae32dcSDimitry Andric     }
5130eae32dcSDimitry Andric   }
5140eae32dcSDimitry Andric 
5150eae32dcSDimitry Andric   if (__e2 < 0 && __availableDigits == 0) {
5160eae32dcSDimitry Andric     const int32_t __idx = -__e2 / 16;
5170eae32dcSDimitry Andric     for (int32_t __i = __MIN_BLOCK_2[__idx]; __i < 200; ++__i) {
5180eae32dcSDimitry Andric       const int32_t __j = __ADDITIONAL_BITS_2 + (-__e2 - 16 * __idx);
5190eae32dcSDimitry Andric       const uint32_t __p = __POW10_OFFSET_2[__idx] + static_cast<uint32_t>(__i) - __MIN_BLOCK_2[__idx];
5200eae32dcSDimitry Andric       // Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
5210eae32dcSDimitry Andric       // a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
5220eae32dcSDimitry Andric       __digits = (__p >= __POW10_OFFSET_2[__idx + 1]) ? 0 : __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT_2[__p], __j + 8);
5230eae32dcSDimitry Andric       if (__printedDigits != 0) {
5240eae32dcSDimitry Andric         if (__printedDigits + 9 > __precision) {
5250eae32dcSDimitry Andric           __availableDigits = 9;
5260eae32dcSDimitry Andric           break;
5270eae32dcSDimitry Andric         }
5280eae32dcSDimitry Andric         if (_Last - _First < 9) {
5290eae32dcSDimitry Andric           return { _Last, errc::value_too_large };
5300eae32dcSDimitry Andric         }
5310eae32dcSDimitry Andric         __append_nine_digits(__digits, _First);
5320eae32dcSDimitry Andric         _First += 9;
5330eae32dcSDimitry Andric         __printedDigits += 9;
5340eae32dcSDimitry Andric       } else if (__digits != 0) {
5350eae32dcSDimitry Andric         __availableDigits = __decimalLength9(__digits);
5360eae32dcSDimitry Andric         __exp = -(__i + 1) * 9 + static_cast<int32_t>(__availableDigits) - 1;
5370eae32dcSDimitry Andric         if (__availableDigits > __precision) {
5380eae32dcSDimitry Andric           break;
5390eae32dcSDimitry Andric         }
5400eae32dcSDimitry Andric         if (__printDecimalPoint) {
5410eae32dcSDimitry Andric           if (_Last - _First < static_cast<ptrdiff_t>(__availableDigits + 1)) {
5420eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
5430eae32dcSDimitry Andric           }
5440eae32dcSDimitry Andric           __append_d_digits(__availableDigits, __digits, _First);
5450eae32dcSDimitry Andric           _First += __availableDigits + 1; // +1 for decimal point
5460eae32dcSDimitry Andric         } else {
5470eae32dcSDimitry Andric           if (_First == _Last) {
5480eae32dcSDimitry Andric             return { _Last, errc::value_too_large };
5490eae32dcSDimitry Andric           }
5500eae32dcSDimitry Andric           *_First++ = static_cast<char>('0' + __digits);
5510eae32dcSDimitry Andric         }
5520eae32dcSDimitry Andric         __printedDigits = __availableDigits;
5530eae32dcSDimitry Andric         __availableDigits = 0;
5540eae32dcSDimitry Andric       }
5550eae32dcSDimitry Andric     }
5560eae32dcSDimitry Andric   }
5570eae32dcSDimitry Andric 
5580eae32dcSDimitry Andric   const uint32_t __maximum = __precision - __printedDigits;
5590eae32dcSDimitry Andric   if (__availableDigits == 0) {
5600eae32dcSDimitry Andric     __digits = 0;
5610eae32dcSDimitry Andric   }
5620eae32dcSDimitry Andric   uint32_t __lastDigit = 0;
5630eae32dcSDimitry Andric   if (__availableDigits > __maximum) {
5640eae32dcSDimitry Andric     for (uint32_t __k = 0; __k < __availableDigits - __maximum; ++__k) {
5650eae32dcSDimitry Andric       __lastDigit = __digits % 10;
5660eae32dcSDimitry Andric       __digits /= 10;
5670eae32dcSDimitry Andric     }
5680eae32dcSDimitry Andric   }
5690eae32dcSDimitry Andric   // 0 = don't round up; 1 = round up unconditionally; 2 = round up if odd.
5700eae32dcSDimitry Andric   int __roundUp = 0;
5710eae32dcSDimitry Andric   if (__lastDigit != 5) {
5720eae32dcSDimitry Andric     __roundUp = __lastDigit > 5;
5730eae32dcSDimitry Andric   } else {
5740eae32dcSDimitry Andric     // Is m * 2^__e2 * 10^(__precision + 1 - __exp) integer?
5750eae32dcSDimitry Andric     // __precision was already increased by 1, so we don't need to write + 1 here.
5760eae32dcSDimitry Andric     const int32_t __rexp = static_cast<int32_t>(__precision) - __exp;
5770eae32dcSDimitry Andric     const int32_t __requiredTwos = -__e2 - __rexp;
5780eae32dcSDimitry Andric     bool __trailingZeros = __requiredTwos <= 0
5790eae32dcSDimitry Andric       || (__requiredTwos < 60 && __multipleOfPowerOf2(__m2, static_cast<uint32_t>(__requiredTwos)));
5800eae32dcSDimitry Andric     if (__rexp < 0) {
5810eae32dcSDimitry Andric       const int32_t __requiredFives = -__rexp;
5820eae32dcSDimitry Andric       __trailingZeros = __trailingZeros && __multipleOfPowerOf5(__m2, static_cast<uint32_t>(__requiredFives));
5830eae32dcSDimitry Andric     }
5840eae32dcSDimitry Andric     __roundUp = __trailingZeros ? 2 : 1;
5850eae32dcSDimitry Andric   }
5860eae32dcSDimitry Andric   if (__printedDigits != 0) {
5870eae32dcSDimitry Andric     if (_Last - _First < static_cast<ptrdiff_t>(__maximum)) {
5880eae32dcSDimitry Andric       return { _Last, errc::value_too_large };
5890eae32dcSDimitry Andric     }
5900eae32dcSDimitry Andric     if (__digits == 0) {
59106c3fb27SDimitry Andric       std::memset(_First, '0', __maximum);
5920eae32dcSDimitry Andric     } else {
5930eae32dcSDimitry Andric       __append_c_digits(__maximum, __digits, _First);
5940eae32dcSDimitry Andric     }
5950eae32dcSDimitry Andric     _First += __maximum;
5960eae32dcSDimitry Andric   } else {
5970eae32dcSDimitry Andric     if (__printDecimalPoint) {
5980eae32dcSDimitry Andric       if (_Last - _First < static_cast<ptrdiff_t>(__maximum + 1)) {
5990eae32dcSDimitry Andric         return { _Last, errc::value_too_large };
6000eae32dcSDimitry Andric       }
6010eae32dcSDimitry Andric       __append_d_digits(__maximum, __digits, _First);
6020eae32dcSDimitry Andric       _First += __maximum + 1; // +1 for decimal point
6030eae32dcSDimitry Andric     } else {
6040eae32dcSDimitry Andric       if (_First == _Last) {
6050eae32dcSDimitry Andric         return { _Last, errc::value_too_large };
6060eae32dcSDimitry Andric       }
6070eae32dcSDimitry Andric       *_First++ = static_cast<char>('0' + __digits);
6080eae32dcSDimitry Andric     }
6090eae32dcSDimitry Andric   }
6100eae32dcSDimitry Andric   if (__roundUp != 0) {
6110eae32dcSDimitry Andric     char* _Round = _First;
6120eae32dcSDimitry Andric     while (true) {
6130eae32dcSDimitry Andric       if (_Round == _Original_first) {
6140eae32dcSDimitry Andric         _Round[0] = '1';
6150eae32dcSDimitry Andric         ++__exp;
6160eae32dcSDimitry Andric         break;
6170eae32dcSDimitry Andric       }
6180eae32dcSDimitry Andric       --_Round;
6190eae32dcSDimitry Andric       const char __c = _Round[0];
6200eae32dcSDimitry Andric       if (__c == '.') {
6210eae32dcSDimitry Andric         // Keep going.
6220eae32dcSDimitry Andric       } else if (__c == '9') {
6230eae32dcSDimitry Andric         _Round[0] = '0';
6240eae32dcSDimitry Andric         __roundUp = 1;
6250eae32dcSDimitry Andric       } else {
6260eae32dcSDimitry Andric         if (__roundUp == 1 || __c % 2 != 0) {
6270eae32dcSDimitry Andric           _Round[0] = __c + 1;
6280eae32dcSDimitry Andric         }
6290eae32dcSDimitry Andric         break;
6300eae32dcSDimitry Andric       }
6310eae32dcSDimitry Andric     }
6320eae32dcSDimitry Andric   }
6330eae32dcSDimitry Andric 
6340eae32dcSDimitry Andric   char _Sign_character;
6350eae32dcSDimitry Andric 
6360eae32dcSDimitry Andric   if (__exp < 0) {
6370eae32dcSDimitry Andric     _Sign_character = '-';
6380eae32dcSDimitry Andric     __exp = -__exp;
6390eae32dcSDimitry Andric   } else {
6400eae32dcSDimitry Andric     _Sign_character = '+';
6410eae32dcSDimitry Andric   }
6420eae32dcSDimitry Andric 
6430eae32dcSDimitry Andric   const int _Exponent_part_length = __exp >= 100
6440eae32dcSDimitry Andric     ? 5 // "e+NNN"
6450eae32dcSDimitry Andric     : 4; // "e+NN"
6460eae32dcSDimitry Andric 
6470eae32dcSDimitry Andric   if (_Last - _First < _Exponent_part_length) {
6480eae32dcSDimitry Andric     return { _Last, errc::value_too_large };
6490eae32dcSDimitry Andric   }
6500eae32dcSDimitry Andric 
6510eae32dcSDimitry Andric   *_First++ = 'e';
6520eae32dcSDimitry Andric   *_First++ = _Sign_character;
6530eae32dcSDimitry Andric 
6540eae32dcSDimitry Andric   if (__exp >= 100) {
6550eae32dcSDimitry Andric     const int32_t __c = __exp % 10;
65606c3fb27SDimitry Andric     std::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
6570eae32dcSDimitry Andric     _First[2] = static_cast<char>('0' + __c);
6580eae32dcSDimitry Andric     _First += 3;
6590eae32dcSDimitry Andric   } else {
66006c3fb27SDimitry Andric     std::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
6610eae32dcSDimitry Andric     _First += 2;
6620eae32dcSDimitry Andric   }
6630eae32dcSDimitry Andric 
6640eae32dcSDimitry Andric   return { _First, errc{} };
6650eae32dcSDimitry Andric }
6660eae32dcSDimitry Andric 
6670eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_STD
6680eae32dcSDimitry Andric 
6690eae32dcSDimitry Andric // clang-format on
670