1 // Copyright 2020 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/strings/internal/str_format/float_conversion.h"
16
17 #include <string.h>
18
19 #include <algorithm>
20 #include <cassert>
21 #include <cmath>
22 #include <limits>
23 #include <string>
24
25 #include "absl/base/attributes.h"
26 #include "absl/base/config.h"
27 #include "absl/base/optimization.h"
28 #include "absl/functional/function_ref.h"
29 #include "absl/meta/type_traits.h"
30 #include "absl/numeric/bits.h"
31 #include "absl/numeric/int128.h"
32 #include "absl/numeric/internal/representation.h"
33 #include "absl/strings/numbers.h"
34 #include "absl/types/optional.h"
35 #include "absl/types/span.h"
36
37 namespace absl {
38 ABSL_NAMESPACE_BEGIN
39 namespace str_format_internal {
40
41 namespace {
42
43 using ::absl::numeric_internal::IsDoubleDouble;
44
45 // The code below wants to avoid heap allocations.
46 // To do so it needs to allocate memory on the stack.
47 // `StackArray` will allocate memory on the stack in the form of a uint32_t
48 // array and call the provided callback with said memory.
49 // It will allocate memory in increments of 512 bytes. We could allocate the
50 // largest needed unconditionally, but that is more than we need in most of
51 // cases. This way we use less stack in the common cases.
52 class StackArray {
53 using Func = absl::FunctionRef<void(absl::Span<uint32_t>)>;
54 static constexpr size_t kStep = 512 / sizeof(uint32_t);
55 // 5 steps is 2560 bytes, which is enough to hold a long double with the
56 // largest/smallest exponents.
57 // The operations below will static_assert their particular maximum.
58 static constexpr size_t kNumSteps = 5;
59
60 // We do not want this function to be inlined.
61 // Otherwise the caller will allocate the stack space unnecessarily for all
62 // the variants even though it only calls one.
63 template <size_t steps>
RunWithCapacityImpl(Func f)64 ABSL_ATTRIBUTE_NOINLINE static void RunWithCapacityImpl(Func f) {
65 uint32_t values[steps * kStep]{};
66 f(absl::MakeSpan(values));
67 }
68
69 public:
70 static constexpr size_t kMaxCapacity = kStep * kNumSteps;
71
RunWithCapacity(size_t capacity,Func f)72 static void RunWithCapacity(size_t capacity, Func f) {
73 assert(capacity <= kMaxCapacity);
74 const size_t step = (capacity + kStep - 1) / kStep;
75 assert(step <= kNumSteps);
76 switch (step) {
77 case 1:
78 return RunWithCapacityImpl<1>(f);
79 case 2:
80 return RunWithCapacityImpl<2>(f);
81 case 3:
82 return RunWithCapacityImpl<3>(f);
83 case 4:
84 return RunWithCapacityImpl<4>(f);
85 case 5:
86 return RunWithCapacityImpl<5>(f);
87 }
88
89 assert(false && "Invalid capacity");
90 }
91 };
92
93 // Calculates `10 * (*v) + carry` and stores the result in `*v` and returns
94 // the carry.
95 // Requires: `0 <= carry <= 9`
96 template <typename Int>
MultiplyBy10WithCarry(Int * v,char carry)97 inline char MultiplyBy10WithCarry(Int* v, char carry) {
98 using BiggerInt = absl::conditional_t<sizeof(Int) == 4, uint64_t, uint128>;
99 BiggerInt tmp =
100 10 * static_cast<BiggerInt>(*v) + static_cast<BiggerInt>(carry);
101 *v = static_cast<Int>(tmp);
102 return static_cast<char>(tmp >> (sizeof(Int) * 8));
103 }
104
105 // Calculates `(2^64 * carry + *v) / 10`.
106 // Stores the quotient in `*v` and returns the remainder.
107 // Requires: `0 <= carry <= 9`
DivideBy10WithCarry(uint64_t * v,char carry)108 inline char DivideBy10WithCarry(uint64_t* v, char carry) {
109 constexpr uint64_t divisor = 10;
110 // 2^64 / divisor = chunk_quotient + chunk_remainder / divisor
111 constexpr uint64_t chunk_quotient = (uint64_t{1} << 63) / (divisor / 2);
112 constexpr uint64_t chunk_remainder = uint64_t{} - chunk_quotient * divisor;
113
114 const uint64_t carry_u64 = static_cast<uint64_t>(carry);
115 const uint64_t mod = *v % divisor;
116 const uint64_t next_carry = chunk_remainder * carry_u64 + mod;
117 *v = *v / divisor + carry_u64 * chunk_quotient + next_carry / divisor;
118 return static_cast<char>(next_carry % divisor);
119 }
120
121 using MaxFloatType =
122 typename std::conditional<IsDoubleDouble(), double, long double>::type;
123
124 // Generates the decimal representation for an integer of the form `v * 2^exp`,
125 // where `v` and `exp` are both positive integers.
126 // It generates the digits from the left (ie the most significant digit first)
127 // to allow for direct printing into the sink.
128 //
129 // Requires `0 <= exp` and `exp <= numeric_limits<MaxFloatType>::max_exponent`.
130 class BinaryToDecimal {
ChunksNeeded(int exp)131 static constexpr size_t ChunksNeeded(int exp) {
132 // We will left shift a uint128 by `exp` bits, so we need `128+exp` total
133 // bits. Round up to 32.
134 // See constructor for details about adding `10%` to the value.
135 return static_cast<size_t>((128 + exp + 31) / 32 * 11 / 10);
136 }
137
138 public:
139 // Run the conversion for `v * 2^exp` and call `f(binary_to_decimal)`.
140 // This function will allocate enough stack space to perform the conversion.
RunConversion(uint128 v,int exp,absl::FunctionRef<void (BinaryToDecimal)> f)141 static void RunConversion(uint128 v, int exp,
142 absl::FunctionRef<void(BinaryToDecimal)> f) {
143 assert(exp > 0);
144 assert(exp <= std::numeric_limits<MaxFloatType>::max_exponent);
145 static_assert(
146 StackArray::kMaxCapacity >=
147 ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent),
148 "");
149
150 StackArray::RunWithCapacity(
151 ChunksNeeded(exp),
152 [=](absl::Span<uint32_t> input) { f(BinaryToDecimal(input, v, exp)); });
153 }
154
TotalDigits() const155 size_t TotalDigits() const {
156 return (decimal_end_ - decimal_start_) * kDigitsPerChunk +
157 CurrentDigits().size();
158 }
159
160 // See the current block of digits.
CurrentDigits() const161 absl::string_view CurrentDigits() const {
162 return absl::string_view(digits_ + kDigitsPerChunk - size_, size_);
163 }
164
165 // Advance the current view of digits.
166 // Returns `false` when no more digits are available.
AdvanceDigits()167 bool AdvanceDigits() {
168 if (decimal_start_ >= decimal_end_) return false;
169
170 uint32_t w = data_[decimal_start_++];
171 for (size_ = 0; size_ < kDigitsPerChunk; w /= 10) {
172 digits_[kDigitsPerChunk - ++size_] = w % 10 + '0';
173 }
174 return true;
175 }
176
177 private:
BinaryToDecimal(absl::Span<uint32_t> data,uint128 v,int exp)178 BinaryToDecimal(absl::Span<uint32_t> data, uint128 v, int exp) : data_(data) {
179 // We need to print the digits directly into the sink object without
180 // buffering them all first. To do this we need two things:
181 // - to know the total number of digits to do padding when necessary
182 // - to generate the decimal digits from the left.
183 //
184 // In order to do this, we do a two pass conversion.
185 // On the first pass we convert the binary representation of the value into
186 // a decimal representation in which each uint32_t chunk holds up to 9
187 // decimal digits. In the second pass we take each decimal-holding-uint32_t
188 // value and generate the ascii decimal digits into `digits_`.
189 //
190 // The binary and decimal representations actually share the same memory
191 // region. As we go converting the chunks from binary to decimal we free
192 // them up and reuse them for the decimal representation. One caveat is that
193 // the decimal representation is around 7% less efficient in space than the
194 // binary one. We allocate an extra 10% memory to account for this. See
195 // ChunksNeeded for this calculation.
196 size_t after_chunk_index = static_cast<size_t>(exp / 32 + 1);
197 decimal_start_ = decimal_end_ = ChunksNeeded(exp);
198 const int offset = exp % 32;
199 // Left shift v by exp bits.
200 data_[after_chunk_index - 1] = static_cast<uint32_t>(v << offset);
201 for (v >>= (32 - offset); v; v >>= 32)
202 data_[++after_chunk_index - 1] = static_cast<uint32_t>(v);
203
204 while (after_chunk_index > 0) {
205 // While we have more than one chunk available, go in steps of 1e9.
206 // `data_[after_chunk_index - 1]` holds the highest non-zero binary chunk,
207 // so keep the variable updated.
208 uint32_t carry = 0;
209 for (size_t i = after_chunk_index; i > 0; --i) {
210 uint64_t tmp = uint64_t{data_[i - 1]} + (uint64_t{carry} << 32);
211 data_[i - 1] = static_cast<uint32_t>(tmp / uint64_t{1000000000});
212 carry = static_cast<uint32_t>(tmp % uint64_t{1000000000});
213 }
214
215 // If the highest chunk is now empty, remove it from view.
216 if (data_[after_chunk_index - 1] == 0)
217 --after_chunk_index;
218
219 --decimal_start_;
220 assert(decimal_start_ != after_chunk_index - 1);
221 data_[decimal_start_] = carry;
222 }
223
224 // Fill the first set of digits. The first chunk might not be complete, so
225 // handle differently.
226 for (uint32_t first = data_[decimal_start_++]; first != 0; first /= 10) {
227 digits_[kDigitsPerChunk - ++size_] = first % 10 + '0';
228 }
229 }
230
231 private:
232 static constexpr size_t kDigitsPerChunk = 9;
233
234 size_t decimal_start_;
235 size_t decimal_end_;
236
237 char digits_[kDigitsPerChunk];
238 size_t size_ = 0;
239
240 absl::Span<uint32_t> data_;
241 };
242
243 // Converts a value of the form `x * 2^-exp` into a sequence of decimal digits.
244 // Requires `-exp < 0` and
245 // `-exp >= limits<MaxFloatType>::min_exponent - limits<MaxFloatType>::digits`.
246 class FractionalDigitGenerator {
247 public:
248 // Run the conversion for `v * 2^exp` and call `f(generator)`.
249 // This function will allocate enough stack space to perform the conversion.
RunConversion(uint128 v,int exp,absl::FunctionRef<void (FractionalDigitGenerator)> f)250 static void RunConversion(
251 uint128 v, int exp, absl::FunctionRef<void(FractionalDigitGenerator)> f) {
252 using Limits = std::numeric_limits<MaxFloatType>;
253 assert(-exp < 0);
254 assert(-exp >= Limits::min_exponent - 128);
255 static_assert(StackArray::kMaxCapacity >=
256 (Limits::digits + 128 - Limits::min_exponent + 31) / 32,
257 "");
258 StackArray::RunWithCapacity(
259 static_cast<size_t>((Limits::digits + exp + 31) / 32),
260 [=](absl::Span<uint32_t> input) {
261 f(FractionalDigitGenerator(input, v, exp));
262 });
263 }
264
265 // Returns true if there are any more non-zero digits left.
HasMoreDigits() const266 bool HasMoreDigits() const { return next_digit_ != 0 || after_chunk_index_; }
267
268 // Returns true if the remainder digits are greater than 5000...
IsGreaterThanHalf() const269 bool IsGreaterThanHalf() const {
270 return next_digit_ > 5 || (next_digit_ == 5 && after_chunk_index_);
271 }
272 // Returns true if the remainder digits are exactly 5000...
IsExactlyHalf() const273 bool IsExactlyHalf() const { return next_digit_ == 5 && !after_chunk_index_; }
274
275 struct Digits {
276 char digit_before_nine;
277 size_t num_nines;
278 };
279
280 // Get the next set of digits.
281 // They are composed by a non-9 digit followed by a runs of zero or more 9s.
GetDigits()282 Digits GetDigits() {
283 Digits digits{next_digit_, 0};
284
285 next_digit_ = GetOneDigit();
286 while (next_digit_ == 9) {
287 ++digits.num_nines;
288 next_digit_ = GetOneDigit();
289 }
290
291 return digits;
292 }
293
294 private:
295 // Return the next digit.
GetOneDigit()296 char GetOneDigit() {
297 if (!after_chunk_index_)
298 return 0;
299
300 char carry = 0;
301 for (size_t i = after_chunk_index_; i > 0; --i) {
302 carry = MultiplyBy10WithCarry(&data_[i - 1], carry);
303 }
304 // If the lowest chunk is now empty, remove it from view.
305 if (data_[after_chunk_index_ - 1] == 0)
306 --after_chunk_index_;
307 return carry;
308 }
309
FractionalDigitGenerator(absl::Span<uint32_t> data,uint128 v,int exp)310 FractionalDigitGenerator(absl::Span<uint32_t> data, uint128 v, int exp)
311 : after_chunk_index_(static_cast<size_t>(exp / 32 + 1)), data_(data) {
312 const int offset = exp % 32;
313 // Right shift `v` by `exp` bits.
314 data_[after_chunk_index_ - 1] = static_cast<uint32_t>(v << (32 - offset));
315 v >>= offset;
316 // Make sure we don't overflow the data. We already calculated that
317 // non-zero bits fit, so we might not have space for leading zero bits.
318 for (size_t pos = after_chunk_index_ - 1; v; v >>= 32)
319 data_[--pos] = static_cast<uint32_t>(v);
320
321 // Fill next_digit_, as GetDigits expects it to be populated always.
322 next_digit_ = GetOneDigit();
323 }
324
325 char next_digit_;
326 size_t after_chunk_index_;
327 absl::Span<uint32_t> data_;
328 };
329
330 // Count the number of leading zero bits.
LeadingZeros(uint64_t v)331 int LeadingZeros(uint64_t v) { return countl_zero(v); }
LeadingZeros(uint128 v)332 int LeadingZeros(uint128 v) {
333 auto high = static_cast<uint64_t>(v >> 64);
334 auto low = static_cast<uint64_t>(v);
335 return high != 0 ? countl_zero(high) : 64 + countl_zero(low);
336 }
337
338 // Round up the text digits starting at `p`.
339 // The buffer must have an extra digit that is known to not need rounding.
340 // This is done below by having an extra '0' digit on the left.
RoundUp(char * p)341 void RoundUp(char *p) {
342 while (*p == '9' || *p == '.') {
343 if (*p == '9') *p = '0';
344 --p;
345 }
346 ++*p;
347 }
348
349 // Check the previous digit and round up or down to follow the round-to-even
350 // policy.
RoundToEven(char * p)351 void RoundToEven(char *p) {
352 if (*p == '.') --p;
353 if (*p % 2 == 1) RoundUp(p);
354 }
355
356 // Simple integral decimal digit printing for values that fit in 64-bits.
357 // Returns the pointer to the last written digit.
PrintIntegralDigitsFromRightFast(uint64_t v,char * p)358 char *PrintIntegralDigitsFromRightFast(uint64_t v, char *p) {
359 do {
360 *--p = DivideBy10WithCarry(&v, 0) + '0';
361 } while (v != 0);
362 return p;
363 }
364
365 // Simple integral decimal digit printing for values that fit in 128-bits.
366 // Returns the pointer to the last written digit.
PrintIntegralDigitsFromRightFast(uint128 v,char * p)367 char *PrintIntegralDigitsFromRightFast(uint128 v, char *p) {
368 auto high = static_cast<uint64_t>(v >> 64);
369 auto low = static_cast<uint64_t>(v);
370
371 while (high != 0) {
372 char carry = DivideBy10WithCarry(&high, 0);
373 carry = DivideBy10WithCarry(&low, carry);
374 *--p = carry + '0';
375 }
376 return PrintIntegralDigitsFromRightFast(low, p);
377 }
378
379 // Simple fractional decimal digit printing for values that fir in 64-bits after
380 // shifting.
381 // Performs rounding if necessary to fit within `precision`.
382 // Returns the pointer to one after the last character written.
PrintFractionalDigitsFast(uint64_t v,char * start,int exp,size_t precision)383 char* PrintFractionalDigitsFast(uint64_t v,
384 char* start,
385 int exp,
386 size_t precision) {
387 char *p = start;
388 v <<= (64 - exp);
389 while (precision > 0) {
390 if (!v) return p;
391 *p++ = MultiplyBy10WithCarry(&v, 0) + '0';
392 --precision;
393 }
394
395 // We need to round.
396 if (v < 0x8000000000000000) {
397 // We round down, so nothing to do.
398 } else if (v > 0x8000000000000000) {
399 // We round up.
400 RoundUp(p - 1);
401 } else {
402 RoundToEven(p - 1);
403 }
404
405 return p;
406 }
407
408 // Simple fractional decimal digit printing for values that fir in 128-bits
409 // after shifting.
410 // Performs rounding if necessary to fit within `precision`.
411 // Returns the pointer to one after the last character written.
PrintFractionalDigitsFast(uint128 v,char * start,int exp,size_t precision)412 char* PrintFractionalDigitsFast(uint128 v,
413 char* start,
414 int exp,
415 size_t precision) {
416 char *p = start;
417 v <<= (128 - exp);
418 auto high = static_cast<uint64_t>(v >> 64);
419 auto low = static_cast<uint64_t>(v);
420
421 // While we have digits to print and `low` is not empty, do the long
422 // multiplication.
423 while (precision > 0 && low != 0) {
424 char carry = MultiplyBy10WithCarry(&low, 0);
425 carry = MultiplyBy10WithCarry(&high, carry);
426
427 *p++ = carry + '0';
428 --precision;
429 }
430
431 // Now `low` is empty, so use a faster approach for the rest of the digits.
432 // This block is pretty much the same as the main loop for the 64-bit case
433 // above.
434 while (precision > 0) {
435 if (!high) return p;
436 *p++ = MultiplyBy10WithCarry(&high, 0) + '0';
437 --precision;
438 }
439
440 // We need to round.
441 if (high < 0x8000000000000000) {
442 // We round down, so nothing to do.
443 } else if (high > 0x8000000000000000 || low != 0) {
444 // We round up.
445 RoundUp(p - 1);
446 } else {
447 RoundToEven(p - 1);
448 }
449
450 return p;
451 }
452
453 struct FormatState {
454 char sign_char;
455 size_t precision;
456 const FormatConversionSpecImpl &conv;
457 FormatSinkImpl *sink;
458
459 // In `alt` mode (flag #) we keep the `.` even if there are no fractional
460 // digits. In non-alt mode, we strip it.
ShouldPrintDotabsl::str_format_internal::__anon3124a7b10111::FormatState461 bool ShouldPrintDot() const { return precision != 0 || conv.has_alt_flag(); }
462 };
463
464 struct Padding {
465 size_t left_spaces;
466 size_t zeros;
467 size_t right_spaces;
468 };
469
ExtraWidthToPadding(size_t total_size,const FormatState & state)470 Padding ExtraWidthToPadding(size_t total_size, const FormatState &state) {
471 if (state.conv.width() < 0 ||
472 static_cast<size_t>(state.conv.width()) <= total_size) {
473 return {0, 0, 0};
474 }
475 size_t missing_chars = static_cast<size_t>(state.conv.width()) - total_size;
476 if (state.conv.has_left_flag()) {
477 return {0, 0, missing_chars};
478 } else if (state.conv.has_zero_flag()) {
479 return {0, missing_chars, 0};
480 } else {
481 return {missing_chars, 0, 0};
482 }
483 }
484
FinalPrint(const FormatState & state,absl::string_view data,size_t padding_offset,size_t trailing_zeros,absl::string_view data_postfix)485 void FinalPrint(const FormatState& state,
486 absl::string_view data,
487 size_t padding_offset,
488 size_t trailing_zeros,
489 absl::string_view data_postfix) {
490 if (state.conv.width() < 0) {
491 // No width specified. Fast-path.
492 if (state.sign_char != '\0') state.sink->Append(1, state.sign_char);
493 state.sink->Append(data);
494 state.sink->Append(trailing_zeros, '0');
495 state.sink->Append(data_postfix);
496 return;
497 }
498
499 auto padding =
500 ExtraWidthToPadding((state.sign_char != '\0' ? 1 : 0) + data.size() +
501 data_postfix.size() + trailing_zeros,
502 state);
503
504 state.sink->Append(padding.left_spaces, ' ');
505 if (state.sign_char != '\0') state.sink->Append(1, state.sign_char);
506 // Padding in general needs to be inserted somewhere in the middle of `data`.
507 state.sink->Append(data.substr(0, padding_offset));
508 state.sink->Append(padding.zeros, '0');
509 state.sink->Append(data.substr(padding_offset));
510 state.sink->Append(trailing_zeros, '0');
511 state.sink->Append(data_postfix);
512 state.sink->Append(padding.right_spaces, ' ');
513 }
514
515 // Fastpath %f formatter for when the shifted value fits in a simple integral
516 // type.
517 // Prints `v*2^exp` with the options from `state`.
518 template <typename Int>
FormatFFast(Int v,int exp,const FormatState & state)519 void FormatFFast(Int v, int exp, const FormatState &state) {
520 constexpr int input_bits = sizeof(Int) * 8;
521
522 static constexpr size_t integral_size =
523 /* in case we need to round up an extra digit */ 1 +
524 /* decimal digits for uint128 */ 40 + 1;
525 char buffer[integral_size + /* . */ 1 + /* max digits uint128 */ 128];
526 buffer[integral_size] = '.';
527 char *const integral_digits_end = buffer + integral_size;
528 char *integral_digits_start;
529 char *const fractional_digits_start = buffer + integral_size + 1;
530 char *fractional_digits_end = fractional_digits_start;
531
532 if (exp >= 0) {
533 const int total_bits = input_bits - LeadingZeros(v) + exp;
534 integral_digits_start =
535 total_bits <= 64
536 ? PrintIntegralDigitsFromRightFast(static_cast<uint64_t>(v) << exp,
537 integral_digits_end)
538 : PrintIntegralDigitsFromRightFast(static_cast<uint128>(v) << exp,
539 integral_digits_end);
540 } else {
541 exp = -exp;
542
543 integral_digits_start = PrintIntegralDigitsFromRightFast(
544 exp < input_bits ? v >> exp : 0, integral_digits_end);
545 // PrintFractionalDigits may pull a carried 1 all the way up through the
546 // integral portion.
547 integral_digits_start[-1] = '0';
548
549 fractional_digits_end =
550 exp <= 64 ? PrintFractionalDigitsFast(v, fractional_digits_start, exp,
551 state.precision)
552 : PrintFractionalDigitsFast(static_cast<uint128>(v),
553 fractional_digits_start, exp,
554 state.precision);
555 // There was a carry, so include the first digit too.
556 if (integral_digits_start[-1] != '0') --integral_digits_start;
557 }
558
559 size_t size =
560 static_cast<size_t>(fractional_digits_end - integral_digits_start);
561
562 // In `alt` mode (flag #) we keep the `.` even if there are no fractional
563 // digits. In non-alt mode, we strip it.
564 if (!state.ShouldPrintDot()) --size;
565 FinalPrint(state, absl::string_view(integral_digits_start, size),
566 /*padding_offset=*/0,
567 state.precision - static_cast<size_t>(fractional_digits_end -
568 fractional_digits_start),
569 /*data_postfix=*/"");
570 }
571
572 // Slow %f formatter for when the shifted value does not fit in a uint128, and
573 // `exp > 0`.
574 // Prints `v*2^exp` with the options from `state`.
575 // This one is guaranteed to not have fractional digits, so we don't have to
576 // worry about anything after the `.`.
FormatFPositiveExpSlow(uint128 v,int exp,const FormatState & state)577 void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) {
578 BinaryToDecimal::RunConversion(v, exp, [&](BinaryToDecimal btd) {
579 const size_t total_digits =
580 btd.TotalDigits() + (state.ShouldPrintDot() ? state.precision + 1 : 0);
581
582 const auto padding = ExtraWidthToPadding(
583 total_digits + (state.sign_char != '\0' ? 1 : 0), state);
584
585 state.sink->Append(padding.left_spaces, ' ');
586 if (state.sign_char != '\0')
587 state.sink->Append(1, state.sign_char);
588 state.sink->Append(padding.zeros, '0');
589
590 do {
591 state.sink->Append(btd.CurrentDigits());
592 } while (btd.AdvanceDigits());
593
594 if (state.ShouldPrintDot())
595 state.sink->Append(1, '.');
596 state.sink->Append(state.precision, '0');
597 state.sink->Append(padding.right_spaces, ' ');
598 });
599 }
600
601 // Slow %f formatter for when the shifted value does not fit in a uint128, and
602 // `exp < 0`.
603 // Prints `v*2^exp` with the options from `state`.
604 // This one is guaranteed to be < 1.0, so we don't have to worry about integral
605 // digits.
FormatFNegativeExpSlow(uint128 v,int exp,const FormatState & state)606 void FormatFNegativeExpSlow(uint128 v, int exp, const FormatState &state) {
607 const size_t total_digits =
608 /* 0 */ 1 + (state.ShouldPrintDot() ? state.precision + 1 : 0);
609 auto padding =
610 ExtraWidthToPadding(total_digits + (state.sign_char ? 1 : 0), state);
611 padding.zeros += 1;
612 state.sink->Append(padding.left_spaces, ' ');
613 if (state.sign_char != '\0') state.sink->Append(1, state.sign_char);
614 state.sink->Append(padding.zeros, '0');
615
616 if (state.ShouldPrintDot()) state.sink->Append(1, '.');
617
618 // Print digits
619 size_t digits_to_go = state.precision;
620
621 FractionalDigitGenerator::RunConversion(
622 v, exp, [&](FractionalDigitGenerator digit_gen) {
623 // There are no digits to print here.
624 if (state.precision == 0) return;
625
626 // We go one digit at a time, while keeping track of runs of nines.
627 // The runs of nines are used to perform rounding when necessary.
628
629 while (digits_to_go > 0 && digit_gen.HasMoreDigits()) {
630 auto digits = digit_gen.GetDigits();
631
632 // Now we have a digit and a run of nines.
633 // See if we can print them all.
634 if (digits.num_nines + 1 < digits_to_go) {
635 // We don't have to round yet, so print them.
636 state.sink->Append(1, digits.digit_before_nine + '0');
637 state.sink->Append(digits.num_nines, '9');
638 digits_to_go -= digits.num_nines + 1;
639
640 } else {
641 // We can't print all the nines, see where we have to truncate.
642
643 bool round_up = false;
644 if (digits.num_nines + 1 > digits_to_go) {
645 // We round up at a nine. No need to print them.
646 round_up = true;
647 } else {
648 // We can fit all the nines, but truncate just after it.
649 if (digit_gen.IsGreaterThanHalf()) {
650 round_up = true;
651 } else if (digit_gen.IsExactlyHalf()) {
652 // Round to even
653 round_up =
654 digits.num_nines != 0 || digits.digit_before_nine % 2 == 1;
655 }
656 }
657
658 if (round_up) {
659 state.sink->Append(1, digits.digit_before_nine + '1');
660 --digits_to_go;
661 // The rest will be zeros.
662 } else {
663 state.sink->Append(1, digits.digit_before_nine + '0');
664 state.sink->Append(digits_to_go - 1, '9');
665 digits_to_go = 0;
666 }
667 return;
668 }
669 }
670 });
671
672 state.sink->Append(digits_to_go, '0');
673 state.sink->Append(padding.right_spaces, ' ');
674 }
675
676 template <typename Int>
FormatF(Int mantissa,int exp,const FormatState & state)677 void FormatF(Int mantissa, int exp, const FormatState &state) {
678 if (exp >= 0) {
679 const int total_bits =
680 static_cast<int>(sizeof(Int) * 8) - LeadingZeros(mantissa) + exp;
681
682 // Fallback to the slow stack-based approach if we can't do it in a 64 or
683 // 128 bit state.
684 if (ABSL_PREDICT_FALSE(total_bits > 128)) {
685 return FormatFPositiveExpSlow(mantissa, exp, state);
686 }
687 } else {
688 // Fallback to the slow stack-based approach if we can't do it in a 64 or
689 // 128 bit state.
690 if (ABSL_PREDICT_FALSE(exp < -128)) {
691 return FormatFNegativeExpSlow(mantissa, -exp, state);
692 }
693 }
694 return FormatFFast(mantissa, exp, state);
695 }
696
697 // Grab the group of four bits (nibble) from `n`. E.g., nibble 1 corresponds to
698 // bits 4-7.
699 template <typename Int>
GetNibble(Int n,size_t nibble_index)700 uint8_t GetNibble(Int n, size_t nibble_index) {
701 constexpr Int mask_low_nibble = Int{0xf};
702 int shift = static_cast<int>(nibble_index * 4);
703 n &= mask_low_nibble << shift;
704 return static_cast<uint8_t>((n >> shift) & 0xf);
705 }
706
707 // Add one to the given nibble, applying carry to higher nibbles. Returns true
708 // if overflow, false otherwise.
709 template <typename Int>
IncrementNibble(size_t nibble_index,Int * n)710 bool IncrementNibble(size_t nibble_index, Int* n) {
711 constexpr size_t kShift = sizeof(Int) * 8 - 1;
712 constexpr size_t kNumNibbles = sizeof(Int) * 8 / 4;
713 Int before = *n >> kShift;
714 // Here we essentially want to take the number 1 and move it into the requsted
715 // nibble, then add it to *n to effectively increment the nibble. However,
716 // ASan will complain if we try to shift the 1 beyond the limits of the Int,
717 // i.e., if the nibble_index is out of range. So therefore we check for this
718 // and if we are out of range we just add 0 which leaves *n unchanged, which
719 // seems like the reasonable thing to do in that case.
720 *n += ((nibble_index >= kNumNibbles)
721 ? 0
722 : (Int{1} << static_cast<int>(nibble_index * 4)));
723 Int after = *n >> kShift;
724 return (before && !after) || (nibble_index >= kNumNibbles);
725 }
726
727 // Return a mask with 1's in the given nibble and all lower nibbles.
728 template <typename Int>
MaskUpToNibbleInclusive(size_t nibble_index)729 Int MaskUpToNibbleInclusive(size_t nibble_index) {
730 constexpr size_t kNumNibbles = sizeof(Int) * 8 / 4;
731 static const Int ones = ~Int{0};
732 ++nibble_index;
733 return ones >> static_cast<int>(
734 4 * (std::max(kNumNibbles, nibble_index) - nibble_index));
735 }
736
737 // Return a mask with 1's below the given nibble.
738 template <typename Int>
MaskUpToNibbleExclusive(size_t nibble_index)739 Int MaskUpToNibbleExclusive(size_t nibble_index) {
740 return nibble_index == 0 ? 0 : MaskUpToNibbleInclusive<Int>(nibble_index - 1);
741 }
742
743 template <typename Int>
MoveToNibble(uint8_t nibble,size_t nibble_index)744 Int MoveToNibble(uint8_t nibble, size_t nibble_index) {
745 return Int{nibble} << static_cast<int>(4 * nibble_index);
746 }
747
748 // Given mantissa size, find optimal # of mantissa bits to put in initial digit.
749 //
750 // In the hex representation we keep a single hex digit to the left of the dot.
751 // However, the question as to how many bits of the mantissa should be put into
752 // that hex digit in theory is arbitrary, but in practice it is optimal to
753 // choose based on the size of the mantissa. E.g., for a `double`, there are 53
754 // mantissa bits, so that means that we should put 1 bit to the left of the dot,
755 // thereby leaving 52 bits to the right, which is evenly divisible by four and
756 // thus all fractional digits represent actual precision. For a `long double`,
757 // on the other hand, there are 64 bits of mantissa, thus we can use all four
758 // bits for the initial hex digit and still have a number left over (60) that is
759 // a multiple of four. Once again, the goal is to have all fractional digits
760 // represent real precision.
761 template <typename Float>
HexFloatLeadingDigitSizeInBits()762 constexpr size_t HexFloatLeadingDigitSizeInBits() {
763 return std::numeric_limits<Float>::digits % 4 > 0
764 ? static_cast<size_t>(std::numeric_limits<Float>::digits % 4)
765 : size_t{4};
766 }
767
768 // This function captures the rounding behavior of glibc for hex float
769 // representations. E.g. when rounding 0x1.ab800000 to a precision of .2
770 // ("%.2a") glibc will round up because it rounds toward the even number (since
771 // 0xb is an odd number, it will round up to 0xc). However, when rounding at a
772 // point that is not followed by 800000..., it disregards the parity and rounds
773 // up if > 8 and rounds down if < 8.
774 template <typename Int>
HexFloatNeedsRoundUp(Int mantissa,size_t final_nibble_displayed,uint8_t leading)775 bool HexFloatNeedsRoundUp(Int mantissa,
776 size_t final_nibble_displayed,
777 uint8_t leading) {
778 // If the last nibble (hex digit) to be displayed is the lowest on in the
779 // mantissa then that means that we don't have any further nibbles to inform
780 // rounding, so don't round.
781 if (final_nibble_displayed == 0) {
782 return false;
783 }
784 size_t rounding_nibble_idx = final_nibble_displayed - 1;
785 constexpr size_t kTotalNibbles = sizeof(Int) * 8 / 4;
786 assert(final_nibble_displayed <= kTotalNibbles);
787 Int mantissa_up_to_rounding_nibble_inclusive =
788 mantissa & MaskUpToNibbleInclusive<Int>(rounding_nibble_idx);
789 Int eight = MoveToNibble<Int>(8, rounding_nibble_idx);
790 if (mantissa_up_to_rounding_nibble_inclusive != eight) {
791 return mantissa_up_to_rounding_nibble_inclusive > eight;
792 }
793 // Nibble in question == 8.
794 uint8_t round_if_odd = (final_nibble_displayed == kTotalNibbles)
795 ? leading
796 : GetNibble(mantissa, final_nibble_displayed);
797 return round_if_odd % 2 == 1;
798 }
799
800 // Stores values associated with a Float type needed by the FormatA
801 // implementation in order to avoid templatizing that function by the Float
802 // type.
803 struct HexFloatTypeParams {
804 template <typename Float>
HexFloatTypeParamsabsl::str_format_internal::__anon3124a7b10111::HexFloatTypeParams805 explicit HexFloatTypeParams(Float)
806 : min_exponent(std::numeric_limits<Float>::min_exponent - 1),
807 leading_digit_size_bits(HexFloatLeadingDigitSizeInBits<Float>()) {
808 assert(leading_digit_size_bits >= 1 && leading_digit_size_bits <= 4);
809 }
810
811 int min_exponent;
812 size_t leading_digit_size_bits;
813 };
814
815 // Hex Float Rounding. First check if we need to round; if so, then we do that
816 // by manipulating (incrementing) the mantissa, that way we can later print the
817 // mantissa digits by iterating through them in the same way regardless of
818 // whether a rounding happened.
819 template <typename Int>
FormatARound(bool precision_specified,const FormatState & state,uint8_t * leading,Int * mantissa,int * exp)820 void FormatARound(bool precision_specified, const FormatState &state,
821 uint8_t *leading, Int *mantissa, int *exp) {
822 constexpr size_t kTotalNibbles = sizeof(Int) * 8 / 4;
823 // Index of the last nibble that we could display given precision.
824 size_t final_nibble_displayed =
825 precision_specified
826 ? (std::max(kTotalNibbles, state.precision) - state.precision)
827 : 0;
828 if (HexFloatNeedsRoundUp(*mantissa, final_nibble_displayed, *leading)) {
829 // Need to round up.
830 bool overflow = IncrementNibble(final_nibble_displayed, mantissa);
831 *leading += (overflow ? 1 : 0);
832 if (ABSL_PREDICT_FALSE(*leading > 15)) {
833 // We have overflowed the leading digit. This would mean that we would
834 // need two hex digits to the left of the dot, which is not allowed. So
835 // adjust the mantissa and exponent so that the result is always 1.0eXXX.
836 *leading = 1;
837 *mantissa = 0;
838 *exp += 4;
839 }
840 }
841 // Now that we have handled a possible round-up we can go ahead and zero out
842 // all the nibbles of the mantissa that we won't need.
843 if (precision_specified) {
844 *mantissa &= ~MaskUpToNibbleExclusive<Int>(final_nibble_displayed);
845 }
846 }
847
848 template <typename Int>
FormatANormalize(const HexFloatTypeParams float_traits,uint8_t * leading,Int * mantissa,int * exp)849 void FormatANormalize(const HexFloatTypeParams float_traits, uint8_t *leading,
850 Int *mantissa, int *exp) {
851 constexpr size_t kIntBits = sizeof(Int) * 8;
852 static const Int kHighIntBit = Int{1} << (kIntBits - 1);
853 const size_t kLeadDigitBitsCount = float_traits.leading_digit_size_bits;
854 // Normalize mantissa so that highest bit set is in MSB position, unless we
855 // get interrupted by the exponent threshold.
856 while (*mantissa && !(*mantissa & kHighIntBit)) {
857 if (ABSL_PREDICT_FALSE(*exp - 1 < float_traits.min_exponent)) {
858 *mantissa >>= (float_traits.min_exponent - *exp);
859 *exp = float_traits.min_exponent;
860 return;
861 }
862 *mantissa <<= 1;
863 --*exp;
864 }
865 // Extract bits for leading digit then shift them away leaving the
866 // fractional part.
867 *leading = static_cast<uint8_t>(
868 *mantissa >> static_cast<int>(kIntBits - kLeadDigitBitsCount));
869 *exp -= (*mantissa != 0) ? static_cast<int>(kLeadDigitBitsCount) : *exp;
870 *mantissa <<= static_cast<int>(kLeadDigitBitsCount);
871 }
872
873 template <typename Int>
FormatA(const HexFloatTypeParams float_traits,Int mantissa,int exp,bool uppercase,const FormatState & state)874 void FormatA(const HexFloatTypeParams float_traits, Int mantissa, int exp,
875 bool uppercase, const FormatState &state) {
876 // Int properties.
877 constexpr size_t kIntBits = sizeof(Int) * 8;
878 constexpr size_t kTotalNibbles = sizeof(Int) * 8 / 4;
879 // Did the user specify a precision explicitly?
880 const bool precision_specified = state.conv.precision() >= 0;
881
882 // ========== Normalize/Denormalize ==========
883 exp += kIntBits; // make all digits fractional digits.
884 // This holds the (up to four) bits of leading digit, i.e., the '1' in the
885 // number 0x1.e6fp+2. It's always > 0 unless number is zero or denormal.
886 uint8_t leading = 0;
887 FormatANormalize(float_traits, &leading, &mantissa, &exp);
888
889 // =============== Rounding ==================
890 // Check if we need to round; if so, then we do that by manipulating
891 // (incrementing) the mantissa before beginning to print characters.
892 FormatARound(precision_specified, state, &leading, &mantissa, &exp);
893
894 // ============= Format Result ===============
895 // This buffer holds the "0x1.ab1de3" portion of "0x1.ab1de3pe+2". Compute the
896 // size with long double which is the largest of the floats.
897 constexpr size_t kBufSizeForHexFloatRepr =
898 2 // 0x
899 + std::numeric_limits<MaxFloatType>::digits / 4 // number of hex digits
900 + 1 // round up
901 + 1; // "." (dot)
902 char digits_buffer[kBufSizeForHexFloatRepr];
903 char *digits_iter = digits_buffer;
904 const char *const digits =
905 static_cast<const char *>("0123456789ABCDEF0123456789abcdef") +
906 (uppercase ? 0 : 16);
907
908 // =============== Hex Prefix ================
909 *digits_iter++ = '0';
910 *digits_iter++ = uppercase ? 'X' : 'x';
911
912 // ========== Non-Fractional Digit ===========
913 *digits_iter++ = digits[leading];
914
915 // ================== Dot ====================
916 // There are three reasons we might need a dot. Keep in mind that, at this
917 // point, the mantissa holds only the fractional part.
918 if ((precision_specified && state.precision > 0) ||
919 (!precision_specified && mantissa > 0) || state.conv.has_alt_flag()) {
920 *digits_iter++ = '.';
921 }
922
923 // ============ Fractional Digits ============
924 size_t digits_emitted = 0;
925 while (mantissa > 0) {
926 *digits_iter++ = digits[GetNibble(mantissa, kTotalNibbles - 1)];
927 mantissa <<= 4;
928 ++digits_emitted;
929 }
930 size_t trailing_zeros = 0;
931 if (precision_specified) {
932 assert(state.precision >= digits_emitted);
933 trailing_zeros = state.precision - digits_emitted;
934 }
935 auto digits_result = string_view(
936 digits_buffer, static_cast<size_t>(digits_iter - digits_buffer));
937
938 // =============== Exponent ==================
939 constexpr size_t kBufSizeForExpDecRepr =
940 numbers_internal::kFastToBufferSize // requred for FastIntToBuffer
941 + 1 // 'p' or 'P'
942 + 1; // '+' or '-'
943 char exp_buffer[kBufSizeForExpDecRepr];
944 exp_buffer[0] = uppercase ? 'P' : 'p';
945 exp_buffer[1] = exp >= 0 ? '+' : '-';
946 numbers_internal::FastIntToBuffer(exp < 0 ? -exp : exp, exp_buffer + 2);
947
948 // ============ Assemble Result ==============
949 FinalPrint(state,
950 digits_result, // 0xN.NNN...
951 2, // offset of any padding
952 static_cast<size_t>(trailing_zeros), // remaining mantissa padding
953 exp_buffer); // exponent
954 }
955
CopyStringTo(absl::string_view v,char * out)956 char *CopyStringTo(absl::string_view v, char *out) {
957 std::memcpy(out, v.data(), v.size());
958 return out + v.size();
959 }
960
961 template <typename Float>
FallbackToSnprintf(const Float v,const FormatConversionSpecImpl & conv,FormatSinkImpl * sink)962 bool FallbackToSnprintf(const Float v, const FormatConversionSpecImpl &conv,
963 FormatSinkImpl *sink) {
964 int w = conv.width() >= 0 ? conv.width() : 0;
965 int p = conv.precision() >= 0 ? conv.precision() : -1;
966 char fmt[32];
967 {
968 char *fp = fmt;
969 *fp++ = '%';
970 fp = CopyStringTo(FormatConversionSpecImplFriend::FlagsToString(conv), fp);
971 fp = CopyStringTo("*.*", fp);
972 if (std::is_same<long double, Float>()) {
973 *fp++ = 'L';
974 }
975 *fp++ = FormatConversionCharToChar(conv.conversion_char());
976 *fp = 0;
977 assert(fp < fmt + sizeof(fmt));
978 }
979 std::string space(512, '\0');
980 absl::string_view result;
981 while (true) {
982 int n = snprintf(&space[0], space.size(), fmt, w, p, v);
983 if (n < 0) return false;
984 if (static_cast<size_t>(n) < space.size()) {
985 result = absl::string_view(space.data(), static_cast<size_t>(n));
986 break;
987 }
988 space.resize(static_cast<size_t>(n) + 1);
989 }
990 sink->Append(result);
991 return true;
992 }
993
994 // 128-bits in decimal: ceil(128*log(2)/log(10))
995 // or std::numeric_limits<__uint128_t>::digits10
996 constexpr size_t kMaxFixedPrecision = 39;
997
998 constexpr size_t kBufferLength = /*sign*/ 1 +
999 /*integer*/ kMaxFixedPrecision +
1000 /*point*/ 1 +
1001 /*fraction*/ kMaxFixedPrecision +
1002 /*exponent e+123*/ 5;
1003
1004 struct Buffer {
push_frontabsl::str_format_internal::__anon3124a7b10111::Buffer1005 void push_front(char c) {
1006 assert(begin > data);
1007 *--begin = c;
1008 }
push_backabsl::str_format_internal::__anon3124a7b10111::Buffer1009 void push_back(char c) {
1010 assert(end < data + sizeof(data));
1011 *end++ = c;
1012 }
pop_backabsl::str_format_internal::__anon3124a7b10111::Buffer1013 void pop_back() {
1014 assert(begin < end);
1015 --end;
1016 }
1017
backabsl::str_format_internal::__anon3124a7b10111::Buffer1018 char &back() {
1019 assert(begin < end);
1020 return end[-1];
1021 }
1022
last_digitabsl::str_format_internal::__anon3124a7b10111::Buffer1023 char last_digit() const { return end[-1] == '.' ? end[-2] : end[-1]; }
1024
sizeabsl::str_format_internal::__anon3124a7b10111::Buffer1025 size_t size() const { return static_cast<size_t>(end - begin); }
1026
1027 char data[kBufferLength];
1028 char *begin;
1029 char *end;
1030 };
1031
1032 enum class FormatStyle { Fixed, Precision };
1033
1034 // If the value is Inf or Nan, print it and return true.
1035 // Otherwise, return false.
1036 template <typename Float>
ConvertNonNumericFloats(char sign_char,Float v,const FormatConversionSpecImpl & conv,FormatSinkImpl * sink)1037 bool ConvertNonNumericFloats(char sign_char, Float v,
1038 const FormatConversionSpecImpl &conv,
1039 FormatSinkImpl *sink) {
1040 char text[4], *ptr = text;
1041 if (sign_char != '\0') *ptr++ = sign_char;
1042 if (std::isnan(v)) {
1043 ptr = std::copy_n(
1044 FormatConversionCharIsUpper(conv.conversion_char()) ? "NAN" : "nan", 3,
1045 ptr);
1046 } else if (std::isinf(v)) {
1047 ptr = std::copy_n(
1048 FormatConversionCharIsUpper(conv.conversion_char()) ? "INF" : "inf", 3,
1049 ptr);
1050 } else {
1051 return false;
1052 }
1053
1054 return sink->PutPaddedString(
1055 string_view(text, static_cast<size_t>(ptr - text)), conv.width(), -1,
1056 conv.has_left_flag());
1057 }
1058
1059 // Round up the last digit of the value.
1060 // It will carry over and potentially overflow. 'exp' will be adjusted in that
1061 // case.
1062 template <FormatStyle mode>
RoundUp(Buffer * buffer,int * exp)1063 void RoundUp(Buffer *buffer, int *exp) {
1064 char *p = &buffer->back();
1065 while (p >= buffer->begin && (*p == '9' || *p == '.')) {
1066 if (*p == '9') *p = '0';
1067 --p;
1068 }
1069
1070 if (p < buffer->begin) {
1071 *p = '1';
1072 buffer->begin = p;
1073 if (mode == FormatStyle::Precision) {
1074 std::swap(p[1], p[2]); // move the .
1075 ++*exp;
1076 buffer->pop_back();
1077 }
1078 } else {
1079 ++*p;
1080 }
1081 }
1082
PrintExponent(int exp,char e,Buffer * out)1083 void PrintExponent(int exp, char e, Buffer *out) {
1084 out->push_back(e);
1085 if (exp < 0) {
1086 out->push_back('-');
1087 exp = -exp;
1088 } else {
1089 out->push_back('+');
1090 }
1091 // Exponent digits.
1092 if (exp > 99) {
1093 out->push_back(static_cast<char>(exp / 100 + '0'));
1094 out->push_back(static_cast<char>(exp / 10 % 10 + '0'));
1095 out->push_back(static_cast<char>(exp % 10 + '0'));
1096 } else {
1097 out->push_back(static_cast<char>(exp / 10 + '0'));
1098 out->push_back(static_cast<char>(exp % 10 + '0'));
1099 }
1100 }
1101
1102 template <typename Float, typename Int>
CanFitMantissa()1103 constexpr bool CanFitMantissa() {
1104 return
1105 #if defined(__clang__) && !defined(__SSE3__)
1106 // Workaround for clang bug: https://bugs.llvm.org/show_bug.cgi?id=38289
1107 // Casting from long double to uint64_t is miscompiled and drops bits.
1108 (!std::is_same<Float, long double>::value ||
1109 !std::is_same<Int, uint64_t>::value) &&
1110 #endif
1111 std::numeric_limits<Float>::digits <= std::numeric_limits<Int>::digits;
1112 }
1113
1114 template <typename Float>
1115 struct Decomposed {
1116 using MantissaType =
1117 absl::conditional_t<std::is_same<long double, Float>::value, uint128,
1118 uint64_t>;
1119 static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8,
1120 "");
1121 MantissaType mantissa;
1122 int exponent;
1123 };
1124
1125 // Decompose the double into an integer mantissa and an exponent.
1126 template <typename Float>
Decompose(Float v)1127 Decomposed<Float> Decompose(Float v) {
1128 int exp;
1129 Float m = std::frexp(v, &exp);
1130 m = std::ldexp(m, std::numeric_limits<Float>::digits);
1131 exp -= std::numeric_limits<Float>::digits;
1132
1133 return {static_cast<typename Decomposed<Float>::MantissaType>(m), exp};
1134 }
1135
1136 // Print 'digits' as decimal.
1137 // In Fixed mode, we add a '.' at the end.
1138 // In Precision mode, we add a '.' after the first digit.
1139 template <FormatStyle mode, typename Int>
PrintIntegralDigits(Int digits,Buffer * out)1140 size_t PrintIntegralDigits(Int digits, Buffer* out) {
1141 size_t printed = 0;
1142 if (digits) {
1143 for (; digits; digits /= 10) out->push_front(digits % 10 + '0');
1144 printed = out->size();
1145 if (mode == FormatStyle::Precision) {
1146 out->push_front(*out->begin);
1147 out->begin[1] = '.';
1148 } else {
1149 out->push_back('.');
1150 }
1151 } else if (mode == FormatStyle::Fixed) {
1152 out->push_front('0');
1153 out->push_back('.');
1154 printed = 1;
1155 }
1156 return printed;
1157 }
1158
1159 // Back out 'extra_digits' digits and round up if necessary.
RemoveExtraPrecision(size_t extra_digits,bool has_leftover_value,Buffer * out,int * exp_out)1160 void RemoveExtraPrecision(size_t extra_digits,
1161 bool has_leftover_value,
1162 Buffer* out,
1163 int* exp_out) {
1164 // Back out the extra digits
1165 out->end -= extra_digits;
1166
1167 bool needs_to_round_up = [&] {
1168 // We look at the digit just past the end.
1169 // There must be 'extra_digits' extra valid digits after end.
1170 if (*out->end > '5') return true;
1171 if (*out->end < '5') return false;
1172 if (has_leftover_value || std::any_of(out->end + 1, out->end + extra_digits,
1173 [](char c) { return c != '0'; }))
1174 return true;
1175
1176 // Ends in ...50*, round to even.
1177 return out->last_digit() % 2 == 1;
1178 }();
1179
1180 if (needs_to_round_up) {
1181 RoundUp<FormatStyle::Precision>(out, exp_out);
1182 }
1183 }
1184
1185 // Print the value into the buffer.
1186 // This will not include the exponent, which will be returned in 'exp_out' for
1187 // Precision mode.
1188 template <typename Int, typename Float, FormatStyle mode>
FloatToBufferImpl(Int int_mantissa,int exp,size_t precision,Buffer * out,int * exp_out)1189 bool FloatToBufferImpl(Int int_mantissa,
1190 int exp,
1191 size_t precision,
1192 Buffer* out,
1193 int* exp_out) {
1194 assert((CanFitMantissa<Float, Int>()));
1195
1196 const int int_bits = std::numeric_limits<Int>::digits;
1197
1198 // In precision mode, we start printing one char to the right because it will
1199 // also include the '.'
1200 // In fixed mode we put the dot afterwards on the right.
1201 out->begin = out->end =
1202 out->data + 1 + kMaxFixedPrecision + (mode == FormatStyle::Precision);
1203
1204 if (exp >= 0) {
1205 if (std::numeric_limits<Float>::digits + exp > int_bits) {
1206 // The value will overflow the Int
1207 return false;
1208 }
1209 size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa << exp, out);
1210 size_t digits_to_zero_pad = precision;
1211 if (mode == FormatStyle::Precision) {
1212 *exp_out = static_cast<int>(digits_printed - 1);
1213 if (digits_to_zero_pad < digits_printed - 1) {
1214 RemoveExtraPrecision(digits_printed - 1 - digits_to_zero_pad, false,
1215 out, exp_out);
1216 return true;
1217 }
1218 digits_to_zero_pad -= digits_printed - 1;
1219 }
1220 for (; digits_to_zero_pad-- > 0;) out->push_back('0');
1221 return true;
1222 }
1223
1224 exp = -exp;
1225 // We need at least 4 empty bits for the next decimal digit.
1226 // We will multiply by 10.
1227 if (exp > int_bits - 4) return false;
1228
1229 const Int mask = (Int{1} << exp) - 1;
1230
1231 // Print the integral part first.
1232 size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa >> exp, out);
1233 int_mantissa &= mask;
1234
1235 size_t fractional_count = precision;
1236 if (mode == FormatStyle::Precision) {
1237 if (digits_printed == 0) {
1238 // Find the first non-zero digit, when in Precision mode.
1239 *exp_out = 0;
1240 if (int_mantissa) {
1241 while (int_mantissa <= mask) {
1242 int_mantissa *= 10;
1243 --*exp_out;
1244 }
1245 }
1246 out->push_front(static_cast<char>(int_mantissa >> exp) + '0');
1247 out->push_back('.');
1248 int_mantissa &= mask;
1249 } else {
1250 // We already have a digit, and a '.'
1251 *exp_out = static_cast<int>(digits_printed - 1);
1252 if (fractional_count < digits_printed - 1) {
1253 // If we had enough digits, return right away.
1254 // The code below will try to round again otherwise.
1255 RemoveExtraPrecision(digits_printed - 1 - fractional_count,
1256 int_mantissa != 0, out, exp_out);
1257 return true;
1258 }
1259 fractional_count -= digits_printed - 1;
1260 }
1261 }
1262
1263 auto get_next_digit = [&] {
1264 int_mantissa *= 10;
1265 char digit = static_cast<char>(int_mantissa >> exp);
1266 int_mantissa &= mask;
1267 return digit;
1268 };
1269
1270 // Print fractional_count more digits, if available.
1271 for (; fractional_count > 0; --fractional_count) {
1272 out->push_back(get_next_digit() + '0');
1273 }
1274
1275 char next_digit = get_next_digit();
1276 if (next_digit > 5 ||
1277 (next_digit == 5 && (int_mantissa || out->last_digit() % 2 == 1))) {
1278 RoundUp<mode>(out, exp_out);
1279 }
1280
1281 return true;
1282 }
1283
1284 template <FormatStyle mode, typename Float>
FloatToBuffer(Decomposed<Float> decomposed,size_t precision,Buffer * out,int * exp)1285 bool FloatToBuffer(Decomposed<Float> decomposed,
1286 size_t precision,
1287 Buffer* out,
1288 int* exp) {
1289 if (precision > kMaxFixedPrecision) return false;
1290
1291 // Try with uint64_t.
1292 if (CanFitMantissa<Float, std::uint64_t>() &&
1293 FloatToBufferImpl<std::uint64_t, Float, mode>(
1294 static_cast<std::uint64_t>(decomposed.mantissa), decomposed.exponent,
1295 precision, out, exp))
1296 return true;
1297
1298 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1299 // If that is not enough, try with __uint128_t.
1300 return CanFitMantissa<Float, __uint128_t>() &&
1301 FloatToBufferImpl<__uint128_t, Float, mode>(
1302 static_cast<__uint128_t>(decomposed.mantissa), decomposed.exponent,
1303 precision, out, exp);
1304 #endif
1305 return false;
1306 }
1307
WriteBufferToSink(char sign_char,absl::string_view str,const FormatConversionSpecImpl & conv,FormatSinkImpl * sink)1308 void WriteBufferToSink(char sign_char, absl::string_view str,
1309 const FormatConversionSpecImpl &conv,
1310 FormatSinkImpl *sink) {
1311 size_t left_spaces = 0, zeros = 0, right_spaces = 0;
1312 size_t missing_chars = 0;
1313 if (conv.width() >= 0) {
1314 const size_t conv_width_size_t = static_cast<size_t>(conv.width());
1315 const size_t existing_chars =
1316 str.size() + static_cast<size_t>(sign_char != 0);
1317 if (conv_width_size_t > existing_chars)
1318 missing_chars = conv_width_size_t - existing_chars;
1319 }
1320 if (conv.has_left_flag()) {
1321 right_spaces = missing_chars;
1322 } else if (conv.has_zero_flag()) {
1323 zeros = missing_chars;
1324 } else {
1325 left_spaces = missing_chars;
1326 }
1327
1328 sink->Append(left_spaces, ' ');
1329 if (sign_char != '\0') sink->Append(1, sign_char);
1330 sink->Append(zeros, '0');
1331 sink->Append(str);
1332 sink->Append(right_spaces, ' ');
1333 }
1334
1335 template <typename Float>
FloatToSink(const Float v,const FormatConversionSpecImpl & conv,FormatSinkImpl * sink)1336 bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv,
1337 FormatSinkImpl *sink) {
1338 // Print the sign or the sign column.
1339 Float abs_v = v;
1340 char sign_char = 0;
1341 if (std::signbit(abs_v)) {
1342 sign_char = '-';
1343 abs_v = -abs_v;
1344 } else if (conv.has_show_pos_flag()) {
1345 sign_char = '+';
1346 } else if (conv.has_sign_col_flag()) {
1347 sign_char = ' ';
1348 }
1349
1350 // Print nan/inf.
1351 if (ConvertNonNumericFloats(sign_char, abs_v, conv, sink)) {
1352 return true;
1353 }
1354
1355 size_t precision =
1356 conv.precision() < 0 ? 6 : static_cast<size_t>(conv.precision());
1357
1358 int exp = 0;
1359
1360 auto decomposed = Decompose(abs_v);
1361
1362 Buffer buffer;
1363
1364 FormatConversionChar c = conv.conversion_char();
1365
1366 if (c == FormatConversionCharInternal::f ||
1367 c == FormatConversionCharInternal::F) {
1368 FormatF(decomposed.mantissa, decomposed.exponent,
1369 {sign_char, precision, conv, sink});
1370 return true;
1371 } else if (c == FormatConversionCharInternal::e ||
1372 c == FormatConversionCharInternal::E) {
1373 if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer,
1374 &exp)) {
1375 return FallbackToSnprintf(v, conv, sink);
1376 }
1377 if (!conv.has_alt_flag() && buffer.back() == '.') buffer.pop_back();
1378 PrintExponent(
1379 exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e',
1380 &buffer);
1381 } else if (c == FormatConversionCharInternal::g ||
1382 c == FormatConversionCharInternal::G) {
1383 precision = std::max(precision, size_t{1}) - 1;
1384 if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer,
1385 &exp)) {
1386 return FallbackToSnprintf(v, conv, sink);
1387 }
1388 if ((exp < 0 || precision + 1 > static_cast<size_t>(exp)) && exp >= -4) {
1389 if (exp < 0) {
1390 // Have 1.23456, needs 0.00123456
1391 // Move the first digit
1392 buffer.begin[1] = *buffer.begin;
1393 // Add some zeros
1394 for (; exp < -1; ++exp) *buffer.begin-- = '0';
1395 *buffer.begin-- = '.';
1396 *buffer.begin = '0';
1397 } else if (exp > 0) {
1398 // Have 1.23456, needs 1234.56
1399 // Move the '.' exp positions to the right.
1400 std::rotate(buffer.begin + 1, buffer.begin + 2, buffer.begin + exp + 2);
1401 }
1402 exp = 0;
1403 }
1404 if (!conv.has_alt_flag()) {
1405 while (buffer.back() == '0') buffer.pop_back();
1406 if (buffer.back() == '.') buffer.pop_back();
1407 }
1408 if (exp) {
1409 PrintExponent(
1410 exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e',
1411 &buffer);
1412 }
1413 } else if (c == FormatConversionCharInternal::a ||
1414 c == FormatConversionCharInternal::A) {
1415 bool uppercase = (c == FormatConversionCharInternal::A);
1416 FormatA(HexFloatTypeParams(Float{}), decomposed.mantissa,
1417 decomposed.exponent, uppercase, {sign_char, precision, conv, sink});
1418 return true;
1419 } else {
1420 return false;
1421 }
1422
1423 WriteBufferToSink(
1424 sign_char,
1425 absl::string_view(buffer.begin,
1426 static_cast<size_t>(buffer.end - buffer.begin)),
1427 conv, sink);
1428
1429 return true;
1430 }
1431
1432 } // namespace
1433
ConvertFloatImpl(long double v,const FormatConversionSpecImpl & conv,FormatSinkImpl * sink)1434 bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv,
1435 FormatSinkImpl *sink) {
1436 if (IsDoubleDouble()) {
1437 // This is the `double-double` representation of `long double`. We do not
1438 // handle it natively. Fallback to snprintf.
1439 return FallbackToSnprintf(v, conv, sink);
1440 }
1441
1442 return FloatToSink(v, conv, sink);
1443 }
1444
ConvertFloatImpl(float v,const FormatConversionSpecImpl & conv,FormatSinkImpl * sink)1445 bool ConvertFloatImpl(float v, const FormatConversionSpecImpl &conv,
1446 FormatSinkImpl *sink) {
1447 return FloatToSink(static_cast<double>(v), conv, sink);
1448 }
1449
ConvertFloatImpl(double v,const FormatConversionSpecImpl & conv,FormatSinkImpl * sink)1450 bool ConvertFloatImpl(double v, const FormatConversionSpecImpl &conv,
1451 FormatSinkImpl *sink) {
1452 return FloatToSink(v, conv, sink);
1453 }
1454
1455 } // namespace str_format_internal
1456 ABSL_NAMESPACE_END
1457 } // namespace absl
1458