brintos

brintos / llvm-project-archived public Read only

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