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