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

source code of libcxx/src/ryu/d2fixed.cpp