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