Coverage Report

Created: 2026-01-13 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/external/com_google_absl/absl/strings/internal/str_format/float_conversion.cc
Line
Count
Source
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 <array>
21
#include <cassert>
22
#include <cmath>
23
#include <cstdint>
24
#include <cstring>
25
#include <limits>
26
#include <optional>
27
#include <string>
28
29
#include "absl/base/attributes.h"
30
#include "absl/base/config.h"
31
#include "absl/base/optimization.h"
32
#include "absl/functional/function_ref.h"
33
#include "absl/meta/type_traits.h"
34
#include "absl/numeric/bits.h"
35
#include "absl/numeric/int128.h"
36
#include "absl/numeric/internal/representation.h"
37
#include "absl/strings/internal/str_format/extension.h"
38
#include "absl/strings/numbers.h"
39
#include "absl/strings/string_view.h"
40
#include "absl/types/optional.h"
41
#include "absl/types/span.h"
42
43
namespace absl {
44
ABSL_NAMESPACE_BEGIN
45
namespace str_format_internal {
46
47
namespace {
48
49
using ::absl::numeric_internal::IsDoubleDouble;
50
51
// The code below wants to avoid heap allocations.
52
// To do so it needs to allocate memory on the stack.
53
// `StackArray` will allocate memory on the stack in the form of a uint32_t
54
// array and call the provided callback with said memory.
55
// It will allocate memory in increments of 512 bytes. We could allocate the
56
// largest needed unconditionally, but that is more than we need in most of
57
// cases. This way we use less stack in the common cases.
58
class StackArray {
59
  using Func = absl::FunctionRef<void(absl::Span<uint32_t>)>;
60
  static constexpr size_t kStep = 512 / sizeof(uint32_t);
61
  // 5 steps is 2560 bytes, which is enough to hold a long double with the
62
  // largest/smallest exponents.
63
  // The operations below will static_assert their particular maximum.
64
  static constexpr size_t kNumSteps = 5;
65
66
  // We do not want this function to be inlined.
67
  // Otherwise the caller will allocate the stack space unnecessarily for all
68
  // the variants even though it only calls one.
69
  template <size_t steps>
70
0
  ABSL_ATTRIBUTE_NOINLINE static void RunWithCapacityImpl(Func f) {
71
0
    uint32_t values[steps * kStep]{};
72
0
    f(absl::MakeSpan(values));
73
0
  }
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::StackArray::RunWithCapacityImpl<1ul>(absl::FunctionRef<void (absl::Span<unsigned int>)>)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::StackArray::RunWithCapacityImpl<2ul>(absl::FunctionRef<void (absl::Span<unsigned int>)>)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::StackArray::RunWithCapacityImpl<3ul>(absl::FunctionRef<void (absl::Span<unsigned int>)>)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::StackArray::RunWithCapacityImpl<4ul>(absl::FunctionRef<void (absl::Span<unsigned int>)>)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::StackArray::RunWithCapacityImpl<5ul>(absl::FunctionRef<void (absl::Span<unsigned int>)>)
74
75
 public:
76
  static constexpr size_t kMaxCapacity = kStep * kNumSteps;
77
78
0
  static void RunWithCapacity(size_t capacity, Func f) {
79
0
    assert(capacity <= kMaxCapacity);
80
0
    const size_t step = (capacity + kStep - 1) / kStep;
81
0
    assert(step <= kNumSteps);
82
0
    switch (step) {
83
0
      case 1:
84
0
        return RunWithCapacityImpl<1>(f);
85
0
      case 2:
86
0
        return RunWithCapacityImpl<2>(f);
87
0
      case 3:
88
0
        return RunWithCapacityImpl<3>(f);
89
0
      case 4:
90
0
        return RunWithCapacityImpl<4>(f);
91
0
      case 5:
92
0
        return RunWithCapacityImpl<5>(f);
93
0
    }
94
95
0
    assert(false && "Invalid capacity");
96
0
  }
97
};
98
99
// Calculates `10 * (*v) + carry` and stores the result in `*v` and returns
100
// the carry.
101
// Requires: `0 <= carry <= 9`
102
template <typename Int>
103
0
inline char MultiplyBy10WithCarry(Int* v, char carry) {
104
0
  using BiggerInt = absl::conditional_t<sizeof(Int) == 4, uint64_t, uint128>;
105
0
  BiggerInt tmp =
106
0
      10 * static_cast<BiggerInt>(*v) + static_cast<BiggerInt>(carry);
107
0
  *v = static_cast<Int>(tmp);
108
0
  return static_cast<char>(tmp >> (sizeof(Int) * 8));
109
0
}
Unexecuted instantiation: float_conversion.cc:char absl::str_format_internal::(anonymous namespace)::MultiplyBy10WithCarry<unsigned int>(unsigned int*, char)
Unexecuted instantiation: float_conversion.cc:char absl::str_format_internal::(anonymous namespace)::MultiplyBy10WithCarry<unsigned long>(unsigned long*, char)
110
111
// Calculates `(2^64 * carry + *v) / 10`.
112
// Stores the quotient in `*v` and returns the remainder.
113
// Requires: `0 <= carry <= 9`
114
0
inline char DivideBy10WithCarry(uint64_t* v, char carry) {
115
0
  constexpr uint64_t divisor = 10;
116
  // 2^64 / divisor = chunk_quotient + chunk_remainder / divisor
117
0
  constexpr uint64_t chunk_quotient = (uint64_t{1} << 63) / (divisor / 2);
118
0
  constexpr uint64_t chunk_remainder = uint64_t{} - chunk_quotient * divisor;
119
120
0
  const uint64_t carry_u64 = static_cast<uint64_t>(carry);
121
0
  const uint64_t mod = *v % divisor;
122
0
  const uint64_t next_carry = chunk_remainder * carry_u64 + mod;
123
0
  *v = *v / divisor + carry_u64 * chunk_quotient + next_carry / divisor;
124
0
  return static_cast<char>(next_carry % divisor);
125
0
}
126
127
using MaxFloatType =
128
    typename std::conditional<IsDoubleDouble(), double, long double>::type;
129
130
// Generates the decimal representation for an integer of the form `v * 2^exp`,
131
// where `v` and `exp` are both positive integers.
132
// It generates the digits from the left (ie the most significant digit first)
133
// to allow for direct printing into the sink.
134
//
135
// Requires `0 <= exp` and `exp <= numeric_limits<MaxFloatType>::max_exponent`.
136
class BinaryToDecimal {
137
0
  static constexpr size_t ChunksNeeded(int exp) {
138
    // We will left shift a uint128 by `exp` bits, so we need `128+exp` total
139
    // bits. Round up to 32.
140
    // See constructor for details about adding `10%` to the value.
141
0
    return static_cast<size_t>((128 + exp + 31) / 32 * 11 / 10);
142
0
  }
143
144
 public:
145
  // Run the conversion for `v * 2^exp` and call `f(binary_to_decimal)`.
146
  // This function will allocate enough stack space to perform the conversion.
147
  static void RunConversion(uint128 v, int exp,
148
0
                            absl::FunctionRef<void(BinaryToDecimal)> f) {
149
0
    assert(exp > 0);
150
0
    assert(exp <= std::numeric_limits<MaxFloatType>::max_exponent);
151
0
    static_assert(
152
0
        StackArray::kMaxCapacity >=
153
0
            ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent),
154
0
        "");
155
156
0
    StackArray::RunWithCapacity(
157
0
        ChunksNeeded(exp),
158
0
        [=](absl::Span<uint32_t> input) { f(BinaryToDecimal(input, v, exp)); });
159
0
  }
160
161
0
  size_t TotalDigits() const {
162
0
    return (decimal_end_ - decimal_start_) * kDigitsPerChunk +
163
0
           CurrentDigits().size();
164
0
  }
165
166
  // See the current block of digits.
167
0
  absl::string_view CurrentDigits() const {
168
0
    return absl::string_view(&digits_[kDigitsPerChunk - size_], size_);
169
0
  }
170
171
  // Advance the current view of digits.
172
  // Returns `false` when no more digits are available.
173
0
  bool AdvanceDigits() {
174
0
    if (decimal_start_ >= decimal_end_) return false;
175
176
0
    uint32_t w = data_[decimal_start_++];
177
0
    for (size_ = 0; size_ < kDigitsPerChunk; w /= 10) {
178
0
      digits_[kDigitsPerChunk - ++size_] = w % 10 + '0';
179
0
    }
180
0
    return true;
181
0
  }
182
183
 private:
184
0
  BinaryToDecimal(absl::Span<uint32_t> data, uint128 v, int exp) : data_(data) {
185
    // We need to print the digits directly into the sink object without
186
    // buffering them all first. To do this we need two things:
187
    // - to know the total number of digits to do padding when necessary
188
    // - to generate the decimal digits from the left.
189
    //
190
    // In order to do this, we do a two pass conversion.
191
    // On the first pass we convert the binary representation of the value into
192
    // a decimal representation in which each uint32_t chunk holds up to 9
193
    // decimal digits.  In the second pass we take each decimal-holding-uint32_t
194
    // value and generate the ascii decimal digits into `digits_`.
195
    //
196
    // The binary and decimal representations actually share the same memory
197
    // region. As we go converting the chunks from binary to decimal we free
198
    // them up and reuse them for the decimal representation. One caveat is that
199
    // the decimal representation is around 7% less efficient in space than the
200
    // binary one. We allocate an extra 10% memory to account for this. See
201
    // ChunksNeeded for this calculation.
202
0
    size_t after_chunk_index = static_cast<size_t>(exp / 32 + 1);
203
0
    decimal_start_ = decimal_end_ = ChunksNeeded(exp);
204
0
    const int offset = exp % 32;
205
    // Left shift v by exp bits.
206
0
    data_[after_chunk_index - 1] = static_cast<uint32_t>(v << offset);
207
0
    for (v >>= (32 - offset); v; v >>= 32)
208
0
      data_[++after_chunk_index - 1] = static_cast<uint32_t>(v);
209
210
0
    while (after_chunk_index > 0) {
211
      // While we have more than one chunk available, go in steps of 1e9.
212
      // `data_[after_chunk_index - 1]` holds the highest non-zero binary chunk,
213
      // so keep the variable updated.
214
0
      uint32_t carry = 0;
215
0
      for (size_t i = after_chunk_index; i > 0; --i) {
216
0
        uint64_t tmp = uint64_t{data_[i - 1]} + (uint64_t{carry} << 32);
217
0
        data_[i - 1] = static_cast<uint32_t>(tmp / uint64_t{1000000000});
218
0
        carry = static_cast<uint32_t>(tmp % uint64_t{1000000000});
219
0
      }
220
221
      // If the highest chunk is now empty, remove it from view.
222
0
      if (data_[after_chunk_index - 1] == 0)
223
0
        --after_chunk_index;
224
225
0
      --decimal_start_;
226
0
      assert(decimal_start_ != after_chunk_index - 1);
227
0
      data_[decimal_start_] = carry;
228
0
    }
229
230
    // Fill the first set of digits. The first chunk might not be complete, so
231
    // handle differently.
232
0
    for (uint32_t first = data_[decimal_start_++]; first != 0; first /= 10) {
233
0
      digits_[kDigitsPerChunk - ++size_] = first % 10 + '0';
234
0
    }
235
0
  }
236
237
 private:
238
  static constexpr size_t kDigitsPerChunk = 9;
239
240
  size_t decimal_start_;
241
  size_t decimal_end_;
242
243
  std::array<char, kDigitsPerChunk> digits_;
244
  size_t size_ = 0;
245
246
  absl::Span<uint32_t> data_;
247
};
248
249
// Converts a value of the form `x * 2^-exp` into a sequence of decimal digits.
250
// Requires `-exp < 0` and
251
// `-exp >= limits<MaxFloatType>::min_exponent - limits<MaxFloatType>::digits`.
252
class FractionalDigitGenerator {
253
 public:
254
  // Run the conversion for `v * 2^exp` and call `f(generator)`.
255
  // This function will allocate enough stack space to perform the conversion.
256
  static void RunConversion(
257
0
      uint128 v, int exp, absl::FunctionRef<void(FractionalDigitGenerator)> f) {
258
0
    using Limits = std::numeric_limits<MaxFloatType>;
259
0
    assert(-exp < 0);
260
0
    assert(-exp >= Limits::min_exponent - 128);
261
0
    static_assert(StackArray::kMaxCapacity >=
262
0
                      (Limits::digits + 128 - Limits::min_exponent + 31) / 32,
263
0
                  "");
264
0
    StackArray::RunWithCapacity(
265
0
        static_cast<size_t>((Limits::digits + exp + 31) / 32),
266
0
        [=](absl::Span<uint32_t> input) {
267
0
          f(FractionalDigitGenerator(input, v, exp));
268
0
        });
269
0
  }
270
271
  // Returns true if there are any more non-zero digits left.
272
0
  bool HasMoreDigits() const { return next_digit_ != 0 || after_chunk_index_; }
273
274
  // Returns true if the remainder digits are greater than 5000...
275
0
  bool IsGreaterThanHalf() const {
276
0
    return next_digit_ > 5 || (next_digit_ == 5 && after_chunk_index_);
277
0
  }
278
  // Returns true if the remainder digits are exactly 5000...
279
0
  bool IsExactlyHalf() const { return next_digit_ == 5 && !after_chunk_index_; }
280
281
  struct Digits {
282
    char digit_before_nine;
283
    size_t num_nines;
284
  };
285
286
  // Get the next set of digits.
287
  // They are composed by a non-9 digit followed by a runs of zero or more 9s.
288
0
  Digits GetDigits() {
289
0
    Digits digits{next_digit_, 0};
290
291
0
    next_digit_ = GetOneDigit();
292
0
    while (next_digit_ == 9) {
293
0
      ++digits.num_nines;
294
0
      next_digit_ = GetOneDigit();
295
0
    }
296
297
0
    return digits;
298
0
  }
299
300
 private:
301
  // Return the next digit.
302
0
  char GetOneDigit() {
303
0
    if (!after_chunk_index_)
304
0
      return 0;
305
306
0
    char carry = 0;
307
0
    for (size_t i = after_chunk_index_; i > 0; --i) {
308
0
      carry = MultiplyBy10WithCarry(&data_[i - 1], carry);
309
0
    }
310
    // If the lowest chunk is now empty, remove it from view.
311
0
    if (data_[after_chunk_index_ - 1] == 0)
312
0
      --after_chunk_index_;
313
0
    return carry;
314
0
  }
315
316
  FractionalDigitGenerator(absl::Span<uint32_t> data, uint128 v, int exp)
317
0
      : after_chunk_index_(static_cast<size_t>(exp / 32 + 1)), data_(data) {
318
0
    const int offset = exp % 32;
319
    // Right shift `v` by `exp` bits.
320
0
    data_[after_chunk_index_ - 1] = static_cast<uint32_t>(v << (32 - offset));
321
0
    v >>= offset;
322
    // Make sure we don't overflow the data. We already calculated that
323
    // non-zero bits fit, so we might not have space for leading zero bits.
324
0
    for (size_t pos = after_chunk_index_ - 1; v; v >>= 32)
325
0
      data_[--pos] = static_cast<uint32_t>(v);
326
327
    // Fill next_digit_, as GetDigits expects it to be populated always.
328
0
    next_digit_ = GetOneDigit();
329
0
  }
330
331
  char next_digit_;
332
  size_t after_chunk_index_;
333
  absl::Span<uint32_t> data_;
334
};
335
336
// Count the number of leading zero bits.
337
0
int LeadingZeros(uint64_t v) { return countl_zero(v); }
338
0
int LeadingZeros(uint128 v) {
339
0
  auto high = static_cast<uint64_t>(v >> 64);
340
0
  auto low = static_cast<uint64_t>(v);
341
0
  return high != 0 ? countl_zero(high) : 64 + countl_zero(low);
342
0
}
343
344
// Round up the text digits starting at `p`.
345
// The buffer must have an extra digit that is known to not need rounding.
346
// This is done below by having an extra '0' digit on the left.
347
0
void RoundUp(char *p) {
348
0
  while (*p == '9' || *p == '.') {
349
0
    if (*p == '9') *p = '0';
350
0
    --p;
351
0
  }
352
0
  ++*p;
353
0
}
354
355
// Check the previous digit and round up or down to follow the round-to-even
356
// policy.
357
0
void RoundToEven(char *p) {
358
0
  if (*p == '.') --p;
359
0
  if (*p % 2 == 1) RoundUp(p);
360
0
}
361
362
// Simple integral decimal digit printing for values that fit in 64-bits.
363
// Returns the pointer to the last written digit.
364
0
char *PrintIntegralDigitsFromRightFast(uint64_t v, char *p) {
365
0
  do {
366
0
    *--p = DivideBy10WithCarry(&v, 0) + '0';
367
0
  } while (v != 0);
368
0
  return p;
369
0
}
370
371
// Simple integral decimal digit printing for values that fit in 128-bits.
372
// Returns the pointer to the last written digit.
373
0
char *PrintIntegralDigitsFromRightFast(uint128 v, char *p) {
374
0
  auto high = static_cast<uint64_t>(v >> 64);
375
0
  auto low = static_cast<uint64_t>(v);
376
377
0
  while (high != 0) {
378
0
    char carry = DivideBy10WithCarry(&high, 0);
379
0
    carry = DivideBy10WithCarry(&low, carry);
380
0
    *--p = carry + '0';
381
0
  }
382
0
  return PrintIntegralDigitsFromRightFast(low, p);
383
0
}
384
385
// Simple fractional decimal digit printing for values that fir in 64-bits after
386
// shifting.
387
// Performs rounding if necessary to fit within `precision`.
388
// Returns the pointer to one after the last character written.
389
char* PrintFractionalDigitsFast(uint64_t v,
390
                                char* start,
391
                                int exp,
392
0
                                size_t precision) {
393
0
  char *p = start;
394
0
  v <<= (64 - exp);
395
0
  while (precision > 0) {
396
0
    if (!v) return p;
397
0
    *p++ = MultiplyBy10WithCarry(&v, 0) + '0';
398
0
    --precision;
399
0
  }
400
401
  // We need to round.
402
0
  if (v < 0x8000000000000000) {
403
    // We round down, so nothing to do.
404
0
  } else if (v > 0x8000000000000000) {
405
    // We round up.
406
0
    RoundUp(p - 1);
407
0
  } else {
408
0
    RoundToEven(p - 1);
409
0
  }
410
411
0
  return p;
412
0
}
413
414
// Simple fractional decimal digit printing for values that fir in 128-bits
415
// after shifting.
416
// Performs rounding if necessary to fit within `precision`.
417
// Returns the pointer to one after the last character written.
418
char* PrintFractionalDigitsFast(uint128 v,
419
                                char* start,
420
                                int exp,
421
0
                                size_t precision) {
422
0
  char *p = start;
423
0
  v <<= (128 - exp);
424
0
  auto high = static_cast<uint64_t>(v >> 64);
425
0
  auto low = static_cast<uint64_t>(v);
426
427
  // While we have digits to print and `low` is not empty, do the long
428
  // multiplication.
429
0
  while (precision > 0 && low != 0) {
430
0
    char carry = MultiplyBy10WithCarry(&low, 0);
431
0
    carry = MultiplyBy10WithCarry(&high, carry);
432
433
0
    *p++ = carry + '0';
434
0
    --precision;
435
0
  }
436
437
  // Now `low` is empty, so use a faster approach for the rest of the digits.
438
  // This block is pretty much the same as the main loop for the 64-bit case
439
  // above.
440
0
  while (precision > 0) {
441
0
    if (!high) return p;
442
0
    *p++ = MultiplyBy10WithCarry(&high, 0) + '0';
443
0
    --precision;
444
0
  }
445
446
  // We need to round.
447
0
  if (high < 0x8000000000000000) {
448
    // We round down, so nothing to do.
449
0
  } else if (high > 0x8000000000000000 || low != 0) {
450
    // We round up.
451
0
    RoundUp(p - 1);
452
0
  } else {
453
0
    RoundToEven(p - 1);
454
0
  }
455
456
0
  return p;
457
0
}
458
459
struct FractionalDigitPrinterResult {
460
  char* end;
461
  size_t skipped_zeros;
462
  bool nonzero_remainder;
463
};
464
465
FractionalDigitPrinterResult PrintFractionalDigitsScientific(
466
0
    uint64_t v, char* start, int exp, size_t precision, bool skip_zeros) {
467
0
  char* p = start;
468
0
  v <<= (64 - exp);
469
470
0
  size_t skipped_zeros = 0;
471
0
  while (v != 0 && precision > 0) {
472
0
    char carry = MultiplyBy10WithCarry(&v, 0);
473
0
    if (skip_zeros) {
474
0
      if (carry == 0) {
475
0
        ++skipped_zeros;
476
0
        continue;
477
0
      }
478
0
      skip_zeros = false;
479
0
    }
480
0
    *p++ = carry + '0';
481
0
    --precision;
482
0
  }
483
0
  return {p, skipped_zeros, v != 0};
484
0
}
485
486
FractionalDigitPrinterResult PrintFractionalDigitsScientific(
487
0
    uint128 v, char* start, int exp, size_t precision, bool skip_zeros) {
488
0
  char* p = start;
489
0
  v <<= (128 - exp);
490
0
  auto high = static_cast<uint64_t>(v >> 64);
491
0
  auto low = static_cast<uint64_t>(v);
492
493
0
  size_t skipped_zeros = 0;
494
0
  while (precision > 0 && low != 0) {
495
0
    char carry = MultiplyBy10WithCarry(&low, 0);
496
0
    carry = MultiplyBy10WithCarry(&high, carry);
497
0
    if (skip_zeros) {
498
0
      if (carry == 0) {
499
0
        ++skipped_zeros;
500
0
        continue;
501
0
      }
502
0
      skip_zeros = false;
503
0
    }
504
0
    *p++ = carry + '0';
505
0
    --precision;
506
0
  }
507
508
0
  while (precision > 0 && high != 0) {
509
0
    char carry = MultiplyBy10WithCarry(&high, 0);
510
0
    if (skip_zeros) {
511
0
      if (carry == 0) {
512
0
        ++skipped_zeros;
513
0
        continue;
514
0
      }
515
0
      skip_zeros = false;
516
0
    }
517
0
    *p++ = carry + '0';
518
0
    --precision;
519
0
  }
520
521
0
  return {p, skipped_zeros, high != 0 || low != 0};
522
0
}
523
524
struct FormatState {
525
  char sign_char;
526
  size_t precision;
527
  const FormatConversionSpecImpl &conv;
528
  FormatSinkImpl *sink;
529
530
  // In `alt` mode (flag #) we keep the `.` even if there are no fractional
531
  // digits. In non-alt mode, we strip it.
532
0
  bool ShouldPrintDot() const { return precision != 0 || conv.has_alt_flag(); }
533
};
534
535
struct Padding {
536
  size_t left_spaces;
537
  size_t zeros;
538
  size_t right_spaces;
539
};
540
541
0
Padding ExtraWidthToPadding(size_t total_size, const FormatState &state) {
542
0
  if (state.conv.width() < 0 ||
543
0
      static_cast<size_t>(state.conv.width()) <= total_size) {
544
0
    return {0, 0, 0};
545
0
  }
546
0
  size_t missing_chars = static_cast<size_t>(state.conv.width()) - total_size;
547
0
  if (state.conv.has_left_flag()) {
548
0
    return {0, 0, missing_chars};
549
0
  } else if (state.conv.has_zero_flag()) {
550
0
    return {0, missing_chars, 0};
551
0
  } else {
552
0
    return {missing_chars, 0, 0};
553
0
  }
554
0
}
555
556
void FinalPrint(const FormatState& state,
557
                absl::string_view data,
558
                size_t padding_offset,
559
                size_t trailing_zeros,
560
0
                absl::string_view data_postfix) {
561
0
  if (state.conv.width() < 0) {
562
    // No width specified. Fast-path.
563
0
    if (state.sign_char != '\0') state.sink->Append(1, state.sign_char);
564
0
    state.sink->Append(data);
565
0
    state.sink->Append(trailing_zeros, '0');
566
0
    state.sink->Append(data_postfix);
567
0
    return;
568
0
  }
569
570
0
  auto padding =
571
0
      ExtraWidthToPadding((state.sign_char != '\0' ? 1 : 0) + data.size() +
572
0
                              data_postfix.size() + trailing_zeros,
573
0
                          state);
574
575
0
  state.sink->Append(padding.left_spaces, ' ');
576
0
  if (state.sign_char != '\0') state.sink->Append(1, state.sign_char);
577
  // Padding in general needs to be inserted somewhere in the middle of `data`.
578
0
  state.sink->Append(data.substr(0, padding_offset));
579
0
  state.sink->Append(padding.zeros, '0');
580
0
  state.sink->Append(data.substr(padding_offset));
581
0
  state.sink->Append(trailing_zeros, '0');
582
0
  state.sink->Append(data_postfix);
583
0
  state.sink->Append(padding.right_spaces, ' ');
584
0
}
585
586
// Fastpath %f formatter for when the shifted value fits in a simple integral
587
// type.
588
// Prints `v*2^exp` with the options from `state`.
589
template <typename Int>
590
0
void FormatFFast(Int v, int exp, const FormatState &state) {
591
0
  constexpr int input_bits = sizeof(Int) * 8;
592
593
0
  static constexpr size_t integral_size =
594
0
      /* in case we need to round up an extra digit */ 1 +
595
0
      /* decimal digits for uint128 */ 40 + 1;
596
0
  char buffer[integral_size + /* . */ 1 + /* max digits uint128 */ 128];
597
0
  buffer[integral_size] = '.';
598
0
  char *const integral_digits_end = buffer + integral_size;
599
0
  char *integral_digits_start;
600
0
  char *const fractional_digits_start = buffer + integral_size + 1;
601
0
  char *fractional_digits_end = fractional_digits_start;
602
603
0
  if (exp >= 0) {
604
0
    const int total_bits = input_bits - LeadingZeros(v) + exp;
605
0
    integral_digits_start =
606
0
        total_bits <= 64
607
0
            ? PrintIntegralDigitsFromRightFast(static_cast<uint64_t>(v) << exp,
608
0
                                               integral_digits_end)
609
0
            : PrintIntegralDigitsFromRightFast(static_cast<uint128>(v) << exp,
610
0
                                               integral_digits_end);
611
0
  } else {
612
0
    exp = -exp;
613
614
0
    integral_digits_start = PrintIntegralDigitsFromRightFast(
615
0
        exp < input_bits ? v >> exp : 0, integral_digits_end);
616
    // PrintFractionalDigits may pull a carried 1 all the way up through the
617
    // integral portion.
618
0
    integral_digits_start[-1] = '0';
619
620
0
    fractional_digits_end =
621
0
        exp <= 64 ? PrintFractionalDigitsFast(v, fractional_digits_start, exp,
622
0
                                              state.precision)
623
0
                  : PrintFractionalDigitsFast(static_cast<uint128>(v),
624
0
                                              fractional_digits_start, exp,
625
0
                                              state.precision);
626
    // There was a carry, so include the first digit too.
627
0
    if (integral_digits_start[-1] != '0') --integral_digits_start;
628
0
  }
629
630
0
  size_t size =
631
0
      static_cast<size_t>(fractional_digits_end - integral_digits_start);
632
633
  // In `alt` mode (flag #) we keep the `.` even if there are no fractional
634
  // digits. In non-alt mode, we strip it.
635
0
  if (!state.ShouldPrintDot()) --size;
636
0
  FinalPrint(state, absl::string_view(integral_digits_start, size),
637
0
             /*padding_offset=*/0,
638
0
             state.precision - static_cast<size_t>(fractional_digits_end -
639
0
                                                   fractional_digits_start),
640
0
             /*data_postfix=*/"");
641
0
}
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatFFast<absl::uint128>(absl::uint128, int, absl::str_format_internal::(anonymous namespace)::FormatState const&)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatFFast<unsigned long>(unsigned long, int, absl::str_format_internal::(anonymous namespace)::FormatState const&)
642
643
// Slow %f formatter for when the shifted value does not fit in a uint128, and
644
// `exp > 0`.
645
// Prints `v*2^exp` with the options from `state`.
646
// This one is guaranteed to not have fractional digits, so we don't have to
647
// worry about anything after the `.`.
648
0
void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) {
649
0
  BinaryToDecimal::RunConversion(v, exp, [&](BinaryToDecimal btd) {
650
0
    const size_t total_digits =
651
0
        btd.TotalDigits() + (state.ShouldPrintDot() ? state.precision + 1 : 0);
652
653
0
    const auto padding = ExtraWidthToPadding(
654
0
        total_digits + (state.sign_char != '\0' ? 1 : 0), state);
655
656
0
    state.sink->Append(padding.left_spaces, ' ');
657
0
    if (state.sign_char != '\0')
658
0
      state.sink->Append(1, state.sign_char);
659
0
    state.sink->Append(padding.zeros, '0');
660
661
0
    do {
662
0
      state.sink->Append(btd.CurrentDigits());
663
0
    } while (btd.AdvanceDigits());
664
665
0
    if (state.ShouldPrintDot())
666
0
      state.sink->Append(1, '.');
667
0
    state.sink->Append(state.precision, '0');
668
0
    state.sink->Append(padding.right_spaces, ' ');
669
0
  });
670
0
}
671
672
// Slow %f formatter for when the shifted value does not fit in a uint128, and
673
// `exp < 0`.
674
// Prints `v*2^exp` with the options from `state`.
675
// This one is guaranteed to be < 1.0, so we don't have to worry about integral
676
// digits.
677
0
void FormatFNegativeExpSlow(uint128 v, int exp, const FormatState &state) {
678
0
  const size_t total_digits =
679
0
      /* 0 */ 1 + (state.ShouldPrintDot() ? state.precision + 1 : 0);
680
0
  auto padding =
681
0
      ExtraWidthToPadding(total_digits + (state.sign_char ? 1 : 0), state);
682
0
  padding.zeros += 1;
683
0
  state.sink->Append(padding.left_spaces, ' ');
684
0
  if (state.sign_char != '\0') state.sink->Append(1, state.sign_char);
685
0
  state.sink->Append(padding.zeros, '0');
686
687
0
  if (state.ShouldPrintDot()) state.sink->Append(1, '.');
688
689
  // Print digits
690
0
  size_t digits_to_go = state.precision;
691
692
0
  FractionalDigitGenerator::RunConversion(
693
0
      v, exp, [&](FractionalDigitGenerator digit_gen) {
694
        // There are no digits to print here.
695
0
        if (state.precision == 0) return;
696
697
        // We go one digit at a time, while keeping track of runs of nines.
698
        // The runs of nines are used to perform rounding when necessary.
699
700
0
        while (digits_to_go > 0 && digit_gen.HasMoreDigits()) {
701
0
          auto digits = digit_gen.GetDigits();
702
703
          // Now we have a digit and a run of nines.
704
          // See if we can print them all.
705
0
          if (digits.num_nines + 1 < digits_to_go) {
706
            // We don't have to round yet, so print them.
707
0
            state.sink->Append(1, digits.digit_before_nine + '0');
708
0
            state.sink->Append(digits.num_nines, '9');
709
0
            digits_to_go -= digits.num_nines + 1;
710
711
0
          } else {
712
            // We can't print all the nines, see where we have to truncate.
713
714
0
            bool round_up = false;
715
0
            if (digits.num_nines + 1 > digits_to_go) {
716
              // We round up at a nine. No need to print them.
717
0
              round_up = true;
718
0
            } else {
719
              // We can fit all the nines, but truncate just after it.
720
0
              if (digit_gen.IsGreaterThanHalf()) {
721
0
                round_up = true;
722
0
              } else if (digit_gen.IsExactlyHalf()) {
723
                // Round to even
724
0
                round_up =
725
0
                    digits.num_nines != 0 || digits.digit_before_nine % 2 == 1;
726
0
              }
727
0
            }
728
729
0
            if (round_up) {
730
0
              state.sink->Append(1, digits.digit_before_nine + '1');
731
0
              --digits_to_go;
732
              // The rest will be zeros.
733
0
            } else {
734
0
              state.sink->Append(1, digits.digit_before_nine + '0');
735
0
              state.sink->Append(digits_to_go - 1, '9');
736
0
              digits_to_go = 0;
737
0
            }
738
0
            return;
739
0
          }
740
0
        }
741
0
      });
742
743
0
  state.sink->Append(digits_to_go, '0');
744
0
  state.sink->Append(padding.right_spaces, ' ');
745
0
}
746
747
template <typename Int>
748
0
void FormatF(Int mantissa, int exp, const FormatState &state) {
749
0
  if (exp >= 0) {
750
0
    const int total_bits =
751
0
        static_cast<int>(sizeof(Int) * 8) - LeadingZeros(mantissa) + exp;
752
753
    // Fallback to the slow stack-based approach if we can't do it in a 64 or
754
    // 128 bit state.
755
0
    if (ABSL_PREDICT_FALSE(total_bits > 128)) {
756
0
      return FormatFPositiveExpSlow(mantissa, exp, state);
757
0
    }
758
0
  } else {
759
    // Fallback to the slow stack-based approach if we can't do it in a 64 or
760
    // 128 bit state.
761
0
    if (ABSL_PREDICT_FALSE(exp < -128)) {
762
0
      return FormatFNegativeExpSlow(mantissa, -exp, state);
763
0
    }
764
0
  }
765
0
  return FormatFFast(mantissa, exp, state);
766
0
}
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatF<absl::uint128>(absl::uint128, int, absl::str_format_internal::(anonymous namespace)::FormatState const&)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatF<unsigned long>(unsigned long, int, absl::str_format_internal::(anonymous namespace)::FormatState const&)
767
768
// Grab the group of four bits (nibble) from `n`. E.g., nibble 1 corresponds to
769
// bits 4-7.
770
template <typename Int>
771
0
uint8_t GetNibble(Int n, size_t nibble_index) {
772
0
  constexpr Int mask_low_nibble = Int{0xf};
773
0
  int shift = static_cast<int>(nibble_index * 4);
774
0
  n &= mask_low_nibble << shift;
775
0
  return static_cast<uint8_t>((n >> shift) & 0xf);
776
0
}
Unexecuted instantiation: float_conversion.cc:unsigned char absl::str_format_internal::(anonymous namespace)::GetNibble<absl::uint128>(absl::uint128, unsigned long)
Unexecuted instantiation: float_conversion.cc:unsigned char absl::str_format_internal::(anonymous namespace)::GetNibble<unsigned long>(unsigned long, unsigned long)
777
778
// Add one to the given nibble, applying carry to higher nibbles. Returns true
779
// if overflow, false otherwise.
780
template <typename Int>
781
0
bool IncrementNibble(size_t nibble_index, Int* n) {
782
0
  constexpr size_t kShift = sizeof(Int) * 8 - 1;
783
0
  constexpr size_t kNumNibbles = sizeof(Int) * 8 / 4;
784
0
  Int before = *n >> kShift;
785
  // Here we essentially want to take the number 1 and move it into the
786
  // requested nibble, then add it to *n to effectively increment the nibble.
787
  // However, ASan will complain if we try to shift the 1 beyond the limits of
788
  // the Int, i.e., if the nibble_index is out of range. So therefore we check
789
  // for this and if we are out of range we just add 0 which leaves *n
790
  // unchanged, which seems like the reasonable thing to do in that case.
791
0
  *n += ((nibble_index >= kNumNibbles)
792
0
             ? 0
793
0
             : (Int{1} << static_cast<int>(nibble_index * 4)));
794
0
  Int after = *n >> kShift;
795
0
  return (before && !after) || (nibble_index >= kNumNibbles);
796
0
}
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::IncrementNibble<absl::uint128>(unsigned long, absl::uint128*)
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::IncrementNibble<unsigned long>(unsigned long, unsigned long*)
797
798
// Return a mask with 1's in the given nibble and all lower nibbles.
799
template <typename Int>
800
0
Int MaskUpToNibbleInclusive(size_t nibble_index) {
801
0
  constexpr size_t kNumNibbles = sizeof(Int) * 8 / 4;
802
0
  static const Int ones = ~Int{0};
803
0
  ++nibble_index;
804
0
  return ones >> static_cast<int>(
805
0
                     4 * (std::max(kNumNibbles, nibble_index) - nibble_index));
806
0
}
Unexecuted instantiation: float_conversion.cc:absl::uint128 absl::str_format_internal::(anonymous namespace)::MaskUpToNibbleInclusive<absl::uint128>(unsigned long)
Unexecuted instantiation: float_conversion.cc:unsigned long absl::str_format_internal::(anonymous namespace)::MaskUpToNibbleInclusive<unsigned long>(unsigned long)
807
808
// Return a mask with 1's below the given nibble.
809
template <typename Int>
810
0
Int MaskUpToNibbleExclusive(size_t nibble_index) {
811
0
  return nibble_index == 0 ? 0 : MaskUpToNibbleInclusive<Int>(nibble_index - 1);
812
0
}
Unexecuted instantiation: float_conversion.cc:absl::uint128 absl::str_format_internal::(anonymous namespace)::MaskUpToNibbleExclusive<absl::uint128>(unsigned long)
Unexecuted instantiation: float_conversion.cc:unsigned long absl::str_format_internal::(anonymous namespace)::MaskUpToNibbleExclusive<unsigned long>(unsigned long)
813
814
template <typename Int>
815
0
Int MoveToNibble(uint8_t nibble, size_t nibble_index) {
816
0
  return Int{nibble} << static_cast<int>(4 * nibble_index);
817
0
}
Unexecuted instantiation: float_conversion.cc:absl::uint128 absl::str_format_internal::(anonymous namespace)::MoveToNibble<absl::uint128>(unsigned char, unsigned long)
Unexecuted instantiation: float_conversion.cc:unsigned long absl::str_format_internal::(anonymous namespace)::MoveToNibble<unsigned long>(unsigned char, unsigned long)
818
819
// Given mantissa size, find optimal # of mantissa bits to put in initial digit.
820
//
821
// In the hex representation we keep a single hex digit to the left of the dot.
822
// However, the question as to how many bits of the mantissa should be put into
823
// that hex digit in theory is arbitrary, but in practice it is optimal to
824
// choose based on the size of the mantissa. E.g., for a `double`, there are 53
825
// mantissa bits, so that means that we should put 1 bit to the left of the dot,
826
// thereby leaving 52 bits to the right, which is evenly divisible by four and
827
// thus all fractional digits represent actual precision. For a `long double`,
828
// on the other hand, there are 64 bits of mantissa, thus we can use all four
829
// bits for the initial hex digit and still have a number left over (60) that is
830
// a multiple of four. Once again, the goal is to have all fractional digits
831
// represent real precision.
832
template <typename Float>
833
0
constexpr size_t HexFloatLeadingDigitSizeInBits() {
834
0
  return std::numeric_limits<Float>::digits % 4 > 0
835
0
             ? static_cast<size_t>(std::numeric_limits<Float>::digits % 4)
836
0
             : size_t{4};
837
0
}
Unexecuted instantiation: float_conversion.cc:unsigned long absl::str_format_internal::(anonymous namespace)::HexFloatLeadingDigitSizeInBits<long double>()
Unexecuted instantiation: float_conversion.cc:unsigned long absl::str_format_internal::(anonymous namespace)::HexFloatLeadingDigitSizeInBits<double>()
838
839
// This function captures the rounding behavior of glibc for hex float
840
// representations. E.g. when rounding 0x1.ab800000 to a precision of .2
841
// ("%.2a") glibc will round up because it rounds toward the even number (since
842
// 0xb is an odd number, it will round up to 0xc). However, when rounding at a
843
// point that is not followed by 800000..., it disregards the parity and rounds
844
// up if > 8 and rounds down if < 8.
845
template <typename Int>
846
bool HexFloatNeedsRoundUp(Int mantissa,
847
                          size_t final_nibble_displayed,
848
0
                          uint8_t leading) {
849
  // If the last nibble (hex digit) to be displayed is the lowest on in the
850
  // mantissa then that means that we don't have any further nibbles to inform
851
  // rounding, so don't round.
852
0
  if (final_nibble_displayed == 0) {
853
0
    return false;
854
0
  }
855
0
  size_t rounding_nibble_idx = final_nibble_displayed - 1;
856
0
  constexpr size_t kTotalNibbles = sizeof(Int) * 8 / 4;
857
0
  assert(final_nibble_displayed <= kTotalNibbles);
858
0
  Int mantissa_up_to_rounding_nibble_inclusive =
859
0
      mantissa & MaskUpToNibbleInclusive<Int>(rounding_nibble_idx);
860
0
  Int eight = MoveToNibble<Int>(8, rounding_nibble_idx);
861
0
  if (mantissa_up_to_rounding_nibble_inclusive != eight) {
862
0
    return mantissa_up_to_rounding_nibble_inclusive > eight;
863
0
  }
864
  // Nibble in question == 8.
865
0
  uint8_t round_if_odd = (final_nibble_displayed == kTotalNibbles)
866
0
                             ? leading
867
0
                             : GetNibble(mantissa, final_nibble_displayed);
868
0
  return round_if_odd % 2 == 1;
869
0
}
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::HexFloatNeedsRoundUp<absl::uint128>(absl::uint128, unsigned long, unsigned char)
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::HexFloatNeedsRoundUp<unsigned long>(unsigned long, unsigned long, unsigned char)
870
871
// Stores values associated with a Float type needed by the FormatA
872
// implementation in order to avoid templatizing that function by the Float
873
// type.
874
struct HexFloatTypeParams {
875
  template <typename Float>
876
  explicit HexFloatTypeParams(Float)
877
0
      : min_exponent(std::numeric_limits<Float>::min_exponent - 1),
878
0
        leading_digit_size_bits(HexFloatLeadingDigitSizeInBits<Float>()) {
879
0
    assert(leading_digit_size_bits >= 1 && leading_digit_size_bits <= 4);
880
0
  }
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::HexFloatTypeParams::HexFloatTypeParams<long double>(long double)
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::HexFloatTypeParams::HexFloatTypeParams<double>(double)
881
882
  int min_exponent;
883
  size_t leading_digit_size_bits;
884
};
885
886
// Hex Float Rounding. First check if we need to round; if so, then we do that
887
// by manipulating (incrementing) the mantissa, that way we can later print the
888
// mantissa digits by iterating through them in the same way regardless of
889
// whether a rounding happened.
890
template <typename Int>
891
void FormatARound(bool precision_specified, const FormatState &state,
892
0
                  uint8_t *leading, Int *mantissa, int *exp) {
893
0
  constexpr size_t kTotalNibbles = sizeof(Int) * 8 / 4;
894
  // Index of the last nibble that we could display given precision.
895
0
  size_t final_nibble_displayed =
896
0
      precision_specified
897
0
          ? (std::max(kTotalNibbles, state.precision) - state.precision)
898
0
          : 0;
899
0
  if (HexFloatNeedsRoundUp(*mantissa, final_nibble_displayed, *leading)) {
900
    // Need to round up.
901
0
    bool overflow = IncrementNibble(final_nibble_displayed, mantissa);
902
0
    *leading += (overflow ? 1 : 0);
903
0
    if (ABSL_PREDICT_FALSE(*leading > 15)) {
904
      // We have overflowed the leading digit. This would mean that we would
905
      // need two hex digits to the left of the dot, which is not allowed. So
906
      // adjust the mantissa and exponent so that the result is always 1.0eXXX.
907
0
      *leading = 1;
908
0
      *mantissa = 0;
909
0
      *exp += 4;
910
0
    }
911
0
  }
912
  // Now that we have handled a possible round-up we can go ahead and zero out
913
  // all the nibbles of the mantissa that we won't need.
914
0
  if (precision_specified) {
915
0
    *mantissa &= ~MaskUpToNibbleExclusive<Int>(final_nibble_displayed);
916
0
  }
917
0
}
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatARound<absl::uint128>(bool, absl::str_format_internal::(anonymous namespace)::FormatState const&, unsigned char*, absl::uint128*, int*)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatARound<unsigned long>(bool, absl::str_format_internal::(anonymous namespace)::FormatState const&, unsigned char*, unsigned long*, int*)
918
919
template <typename Int>
920
void FormatANormalize(const HexFloatTypeParams float_traits, uint8_t *leading,
921
0
                      Int *mantissa, int *exp) {
922
0
  constexpr size_t kIntBits = sizeof(Int) * 8;
923
0
  static const Int kHighIntBit = Int{1} << (kIntBits - 1);
924
0
  const size_t kLeadDigitBitsCount = float_traits.leading_digit_size_bits;
925
  // Normalize mantissa so that highest bit set is in MSB position, unless we
926
  // get interrupted by the exponent threshold.
927
0
  while (*mantissa && !(*mantissa & kHighIntBit)) {
928
0
    if (ABSL_PREDICT_FALSE(*exp - 1 < float_traits.min_exponent)) {
929
0
      *mantissa >>= (float_traits.min_exponent - *exp);
930
0
      *exp = float_traits.min_exponent;
931
0
      return;
932
0
    }
933
0
    *mantissa <<= 1;
934
0
    --*exp;
935
0
  }
936
  // Extract bits for leading digit then shift them away leaving the
937
  // fractional part.
938
0
  *leading = static_cast<uint8_t>(
939
0
      *mantissa >> static_cast<int>(kIntBits - kLeadDigitBitsCount));
940
0
  *exp -= (*mantissa != 0) ? static_cast<int>(kLeadDigitBitsCount) : *exp;
941
0
  *mantissa <<= static_cast<int>(kLeadDigitBitsCount);
942
0
}
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatANormalize<absl::uint128>(absl::str_format_internal::(anonymous namespace)::HexFloatTypeParams, unsigned char*, absl::uint128*, int*)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatANormalize<unsigned long>(absl::str_format_internal::(anonymous namespace)::HexFloatTypeParams, unsigned char*, unsigned long*, int*)
943
944
template <typename Int>
945
void FormatA(const HexFloatTypeParams float_traits, Int mantissa, int exp,
946
0
             bool uppercase, const FormatState &state) {
947
  // Int properties.
948
0
  constexpr size_t kIntBits = sizeof(Int) * 8;
949
0
  constexpr size_t kTotalNibbles = sizeof(Int) * 8 / 4;
950
  // Did the user specify a precision explicitly?
951
0
  const bool precision_specified = state.conv.precision() >= 0;
952
953
  // ========== Normalize/Denormalize ==========
954
0
  exp += kIntBits;  // make all digits fractional digits.
955
  // This holds the (up to four) bits of leading digit, i.e., the '1' in the
956
  // number 0x1.e6fp+2. It's always > 0 unless number is zero or denormal.
957
0
  uint8_t leading = 0;
958
0
  FormatANormalize(float_traits, &leading, &mantissa, &exp);
959
960
  // =============== Rounding ==================
961
  // Check if we need to round; if so, then we do that by manipulating
962
  // (incrementing) the mantissa before beginning to print characters.
963
0
  FormatARound(precision_specified, state, &leading, &mantissa, &exp);
964
965
  // ============= Format Result ===============
966
  // This buffer holds the "0x1.ab1de3" portion of "0x1.ab1de3pe+2". Compute the
967
  // size with long double which is the largest of the floats.
968
0
  constexpr size_t kBufSizeForHexFloatRepr =
969
0
      2                                                // 0x
970
0
      + std::numeric_limits<MaxFloatType>::digits / 4  // number of hex digits
971
0
      + 1                                              // round up
972
0
      + 1;                                             // "." (dot)
973
0
  char digits_buffer[kBufSizeForHexFloatRepr];
974
0
  char *digits_iter = digits_buffer;
975
0
  const char *const digits =
976
0
      static_cast<const char *>("0123456789ABCDEF0123456789abcdef") +
977
0
      (uppercase ? 0 : 16);
978
979
  // =============== Hex Prefix ================
980
0
  *digits_iter++ = '0';
981
0
  *digits_iter++ = uppercase ? 'X' : 'x';
982
983
  // ========== Non-Fractional Digit ===========
984
0
  *digits_iter++ = digits[leading];
985
986
  // ================== Dot ====================
987
  // There are three reasons we might need a dot. Keep in mind that, at this
988
  // point, the mantissa holds only the fractional part.
989
0
  if ((precision_specified && state.precision > 0) ||
990
0
      (!precision_specified && mantissa > 0) || state.conv.has_alt_flag()) {
991
0
    *digits_iter++ = '.';
992
0
  }
993
994
  // ============ Fractional Digits ============
995
0
  size_t digits_emitted = 0;
996
0
  while (mantissa > 0) {
997
0
    *digits_iter++ = digits[GetNibble(mantissa, kTotalNibbles - 1)];
998
0
    mantissa <<= 4;
999
0
    ++digits_emitted;
1000
0
  }
1001
0
  size_t trailing_zeros = 0;
1002
0
  if (precision_specified) {
1003
0
    assert(state.precision >= digits_emitted);
1004
0
    trailing_zeros = state.precision - digits_emitted;
1005
0
  }
1006
0
  auto digits_result = string_view(
1007
0
      digits_buffer, static_cast<size_t>(digits_iter - digits_buffer));
1008
1009
  // =============== Exponent ==================
1010
0
  constexpr size_t kBufSizeForExpDecRepr =
1011
0
      numbers_internal::kFastToBufferSize  // required for FastIntToBuffer
1012
0
      + 1                                  // 'p' or 'P'
1013
0
      + 1;                                 // '+' or '-'
1014
0
  char exp_buffer[kBufSizeForExpDecRepr];
1015
0
  exp_buffer[0] = uppercase ? 'P' : 'p';
1016
0
  exp_buffer[1] = exp >= 0 ? '+' : '-';
1017
0
  numbers_internal::FastIntToBuffer(exp < 0 ? -exp : exp, exp_buffer + 2);
1018
1019
  // ============ Assemble Result ==============
1020
0
  FinalPrint(state,
1021
0
             digits_result,                        // 0xN.NNN...
1022
0
             2,                                    // offset of any padding
1023
0
             static_cast<size_t>(trailing_zeros),  // remaining mantissa padding
1024
0
             exp_buffer);                          // exponent
1025
0
}
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatA<absl::uint128>(absl::str_format_internal::(anonymous namespace)::HexFloatTypeParams, absl::uint128, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatA<unsigned long>(absl::str_format_internal::(anonymous namespace)::HexFloatTypeParams, unsigned long, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)
1026
1027
2.84k
char *CopyStringTo(absl::string_view v, char *out) {
1028
2.84k
  std::memcpy(out, v.data(), v.size());
1029
2.84k
  return out + v.size();
1030
2.84k
}
1031
1032
template <typename Float>
1033
bool FallbackToSnprintf(const Float v, const FormatConversionSpecImpl &conv,
1034
1.42k
                        FormatSinkImpl *sink) {
1035
1.42k
  int w = conv.width() >= 0 ? conv.width() : 0;
1036
1.42k
  int p = conv.precision() >= 0 ? conv.precision() : -1;
1037
1.42k
  char fmt[32];
1038
1.42k
  {
1039
1.42k
    char *fp = fmt;
1040
1.42k
    *fp++ = '%';
1041
1.42k
    fp = CopyStringTo(FormatConversionSpecImplFriend::FlagsToString(conv), fp);
1042
1.42k
    fp = CopyStringTo("*.*", fp);
1043
1.42k
    if (std::is_same<long double, Float>()) {
1044
0
      *fp++ = 'L';
1045
0
    }
1046
1.42k
    *fp++ = FormatConversionCharToChar(conv.conversion_char());
1047
1.42k
    *fp = 0;
1048
1.42k
    assert(fp < fmt + sizeof(fmt));
1049
1.42k
  }
1050
1.42k
  std::string space(512, '\0');
1051
1.42k
  absl::string_view result;
1052
1.42k
  while (true) {
1053
1.42k
    int n = snprintf(&space[0], space.size(), fmt, w, p, v);
1054
1.42k
    if (n < 0) return false;
1055
1.42k
    if (static_cast<size_t>(n) < space.size()) {
1056
1.42k
      result = absl::string_view(space.data(), static_cast<size_t>(n));
1057
1.42k
      break;
1058
1.42k
    }
1059
0
    space.resize(static_cast<size_t>(n) + 1);
1060
0
  }
1061
1.42k
  sink->Append(result);
1062
1.42k
  return true;
1063
1.42k
}
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FallbackToSnprintf<long double>(long double, absl::str_format_internal::FormatConversionSpecImpl const&, absl::str_format_internal::FormatSinkImpl*)
float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FallbackToSnprintf<double>(double, absl::str_format_internal::FormatConversionSpecImpl const&, absl::str_format_internal::FormatSinkImpl*)
Line
Count
Source
1034
1.42k
                        FormatSinkImpl *sink) {
1035
1.42k
  int w = conv.width() >= 0 ? conv.width() : 0;
1036
1.42k
  int p = conv.precision() >= 0 ? conv.precision() : -1;
1037
1.42k
  char fmt[32];
1038
1.42k
  {
1039
1.42k
    char *fp = fmt;
1040
1.42k
    *fp++ = '%';
1041
1.42k
    fp = CopyStringTo(FormatConversionSpecImplFriend::FlagsToString(conv), fp);
1042
1.42k
    fp = CopyStringTo("*.*", fp);
1043
1.42k
    if (std::is_same<long double, Float>()) {
1044
0
      *fp++ = 'L';
1045
0
    }
1046
1.42k
    *fp++ = FormatConversionCharToChar(conv.conversion_char());
1047
1.42k
    *fp = 0;
1048
1.42k
    assert(fp < fmt + sizeof(fmt));
1049
1.42k
  }
1050
1.42k
  std::string space(512, '\0');
1051
1.42k
  absl::string_view result;
1052
1.42k
  while (true) {
1053
1.42k
    int n = snprintf(&space[0], space.size(), fmt, w, p, v);
1054
1.42k
    if (n < 0) return false;
1055
1.42k
    if (static_cast<size_t>(n) < space.size()) {
1056
1.42k
      result = absl::string_view(space.data(), static_cast<size_t>(n));
1057
1.42k
      break;
1058
1.42k
    }
1059
0
    space.resize(static_cast<size_t>(n) + 1);
1060
0
  }
1061
1.42k
  sink->Append(result);
1062
1.42k
  return true;
1063
1.42k
}
1064
1065
// 128-bits in decimal: ceil(128*log(2)/log(10))
1066
//   or std::numeric_limits<__uint128_t>::digits10
1067
constexpr size_t kMaxFixedPrecision = 39;
1068
1069
constexpr size_t kBufferLength = /*sign*/ 1 +
1070
                                 /*integer*/ kMaxFixedPrecision +
1071
                                 /*point*/ 1 +
1072
                                 /*fraction*/ kMaxFixedPrecision +
1073
                                 /*exponent e+123*/ 5;
1074
1075
struct Buffer {
1076
54.5k
  void push_front(char c) {
1077
54.5k
    assert(begin > data);
1078
54.5k
    *--begin = c;
1079
54.5k
  }
1080
5.86k
  void push_back(char c) {
1081
5.86k
    assert(end < data + sizeof(data));
1082
5.86k
    *end++ = c;
1083
5.86k
  }
1084
960
  void pop_back() {
1085
960
    assert(begin < end);
1086
960
    --end;
1087
960
  }
1088
1089
4.31k
  char &back() const {
1090
4.31k
    assert(begin < end);
1091
4.31k
    return end[-1];
1092
4.31k
  }
1093
1094
0
  char last_digit() const { return end[-1] == '.' ? end[-2] : end[-1]; }
1095
1096
1.40k
  size_t size() const { return static_cast<size_t>(end - begin); }
1097
1098
  char data[kBufferLength];
1099
  char *begin;
1100
  char *end;
1101
};
1102
1103
enum class FormatStyle { Fixed, Precision };
1104
1105
// If the value is Inf or Nan, print it and return true.
1106
// Otherwise, return false.
1107
template <typename Float>
1108
bool ConvertNonNumericFloats(char sign_char, Float v,
1109
                             const FormatConversionSpecImpl &conv,
1110
2.86k
                             FormatSinkImpl *sink) {
1111
2.86k
  char text[4], *ptr = text;
1112
2.86k
  if (sign_char != '\0') *ptr++ = sign_char;
1113
2.86k
  if (std::isnan(v)) {
1114
0
    ptr = std::copy_n(
1115
0
        FormatConversionCharIsUpper(conv.conversion_char()) ? "NAN" : "nan", 3,
1116
0
        ptr);
1117
2.86k
  } else if (std::isinf(v)) {
1118
0
    ptr = std::copy_n(
1119
0
        FormatConversionCharIsUpper(conv.conversion_char()) ? "INF" : "inf", 3,
1120
0
        ptr);
1121
2.86k
  } else {
1122
2.86k
    return false;
1123
2.86k
  }
1124
1125
0
  return sink->PutPaddedString(
1126
0
      string_view(text, static_cast<size_t>(ptr - text)), conv.width(), -1,
1127
0
      conv.has_left_flag());
1128
2.86k
}
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::ConvertNonNumericFloats<long double>(char, long double, absl::str_format_internal::FormatConversionSpecImpl const&, absl::str_format_internal::FormatSinkImpl*)
float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::ConvertNonNumericFloats<double>(char, double, absl::str_format_internal::FormatConversionSpecImpl const&, absl::str_format_internal::FormatSinkImpl*)
Line
Count
Source
1110
2.86k
                             FormatSinkImpl *sink) {
1111
2.86k
  char text[4], *ptr = text;
1112
2.86k
  if (sign_char != '\0') *ptr++ = sign_char;
1113
2.86k
  if (std::isnan(v)) {
1114
0
    ptr = std::copy_n(
1115
0
        FormatConversionCharIsUpper(conv.conversion_char()) ? "NAN" : "nan", 3,
1116
0
        ptr);
1117
2.86k
  } else if (std::isinf(v)) {
1118
0
    ptr = std::copy_n(
1119
0
        FormatConversionCharIsUpper(conv.conversion_char()) ? "INF" : "inf", 3,
1120
0
        ptr);
1121
2.86k
  } else {
1122
2.86k
    return false;
1123
2.86k
  }
1124
1125
0
  return sink->PutPaddedString(
1126
0
      string_view(text, static_cast<size_t>(ptr - text)), conv.width(), -1,
1127
0
      conv.has_left_flag());
1128
2.86k
}
1129
1130
// Round up the last digit of the value.
1131
// It will carry over and potentially overflow. 'exp' will be adjusted in that
1132
// case.
1133
template <FormatStyle mode>
1134
651
void RoundUp(Buffer *buffer, int *exp) {
1135
651
  char *p = &buffer->back();
1136
1.26k
  while (p >= buffer->begin && (*p == '9' || *p == '.')) {
1137
617
    if (*p == '9') *p = '0';
1138
617
    --p;
1139
617
  }
1140
1141
651
  if (p < buffer->begin) {
1142
65
    *p = '1';
1143
65
    buffer->begin = p;
1144
65
    if (mode == FormatStyle::Precision) {
1145
65
      std::swap(p[1], p[2]);  // move the .
1146
65
      ++*exp;
1147
65
      buffer->pop_back();
1148
65
    }
1149
586
  } else {
1150
586
    ++*p;
1151
586
  }
1152
651
}
1153
1154
1.40k
void PrintExponent(int exp, char e, Buffer *out) {
1155
1.40k
  out->push_back(e);
1156
1.40k
  if (exp < 0) {
1157
0
    out->push_back('-');
1158
0
    exp = -exp;
1159
1.40k
  } else {
1160
1.40k
    out->push_back('+');
1161
1.40k
  }
1162
  // Exponent digits.
1163
1.40k
  if (exp > 99) {
1164
0
    out->push_back(static_cast<char>(exp / 100 + '0'));
1165
0
    out->push_back(static_cast<char>(exp / 10 % 10 + '0'));
1166
0
    out->push_back(static_cast<char>(exp % 10 + '0'));
1167
1.40k
  } else {
1168
1.40k
    out->push_back(static_cast<char>(exp / 10 + '0'));
1169
1.40k
    out->push_back(static_cast<char>(exp % 10 + '0'));
1170
1.40k
  }
1171
1.40k
}
1172
1173
template <typename Float, typename Int>
1174
0
constexpr bool CanFitMantissa() {
1175
0
  return
1176
0
#if defined(__clang__) && (__clang_major__ < 9) && !defined(__SSE3__)
1177
0
      // Workaround for clang bug: https://bugs.llvm.org/show_bug.cgi?id=38289
1178
0
      // Casting from long double to uint64_t is miscompiled and drops bits.
1179
0
      (!std::is_same<Float, long double>::value ||
1180
0
       !std::is_same<Int, uint64_t>::value) &&
1181
0
#endif
1182
0
      std::numeric_limits<Float>::digits <= std::numeric_limits<Int>::digits;
1183
0
}
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::CanFitMantissa<long double, unsigned long>()
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::CanFitMantissa<long double, unsigned __int128>()
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::CanFitMantissa<double, unsigned long>()
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::CanFitMantissa<double, unsigned __int128>()
1184
1185
template <typename Float>
1186
struct Decomposed {
1187
  using MantissaType =
1188
      absl::conditional_t<std::is_same<long double, Float>::value, uint128,
1189
                          uint64_t>;
1190
  static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8,
1191
                "");
1192
  MantissaType mantissa;
1193
  int exponent;
1194
};
1195
1196
// Decompose the double into an integer mantissa and an exponent.
1197
template <typename Float>
1198
2.86k
Decomposed<Float> Decompose(Float v) {
1199
2.86k
  int exp;
1200
2.86k
  Float m = std::frexp(v, &exp);
1201
2.86k
  m = std::ldexp(m, std::numeric_limits<Float>::digits);
1202
2.86k
  exp -= std::numeric_limits<Float>::digits;
1203
1204
2.86k
  return {static_cast<typename Decomposed<Float>::MantissaType>(m), exp};
1205
2.86k
}
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::Decomposed<long double> absl::str_format_internal::(anonymous namespace)::Decompose<long double>(long double)
float_conversion.cc:absl::str_format_internal::(anonymous namespace)::Decomposed<double> absl::str_format_internal::(anonymous namespace)::Decompose<double>(double)
Line
Count
Source
1198
2.86k
Decomposed<Float> Decompose(Float v) {
1199
2.86k
  int exp;
1200
2.86k
  Float m = std::frexp(v, &exp);
1201
2.86k
  m = std::ldexp(m, std::numeric_limits<Float>::digits);
1202
2.86k
  exp -= std::numeric_limits<Float>::digits;
1203
1204
2.86k
  return {static_cast<typename Decomposed<Float>::MantissaType>(m), exp};
1205
2.86k
}
1206
1207
// Print 'digits' as decimal.
1208
// In Fixed mode, we add a '.' at the end.
1209
// In Precision mode, we add a '.' after the first digit.
1210
template <FormatStyle mode, typename Int>
1211
1.44k
size_t PrintIntegralDigits(Int digits, Buffer* out) {
1212
1.44k
  size_t printed = 0;
1213
1.44k
  if (digits) {
1214
54.4k
    for (; digits; digits /= 10) out->push_front(digits % 10 + '0');
1215
1.40k
    printed = out->size();
1216
1.40k
    if (mode == FormatStyle::Precision) {
1217
1.40k
      out->push_front(*out->begin);
1218
1.40k
      out->begin[1] = '.';
1219
1.40k
    } else {
1220
0
      out->push_back('.');
1221
0
    }
1222
1.40k
  } else if (mode == FormatStyle::Fixed) {
1223
0
    out->push_front('0');
1224
0
    out->push_back('.');
1225
0
    printed = 1;
1226
0
  }
1227
1.44k
  return printed;
1228
1.44k
}
float_conversion.cc:unsigned long absl::str_format_internal::(anonymous namespace)::PrintIntegralDigits<(absl::str_format_internal::(anonymous namespace)::FormatStyle)1, unsigned long>(unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*)
Line
Count
Source
1211
43
size_t PrintIntegralDigits(Int digits, Buffer* out) {
1212
43
  size_t printed = 0;
1213
43
  if (digits) {
1214
0
    for (; digits; digits /= 10) out->push_front(digits % 10 + '0');
1215
0
    printed = out->size();
1216
0
    if (mode == FormatStyle::Precision) {
1217
0
      out->push_front(*out->begin);
1218
0
      out->begin[1] = '.';
1219
0
    } else {
1220
0
      out->push_back('.');
1221
0
    }
1222
43
  } else if (mode == FormatStyle::Fixed) {
1223
0
    out->push_front('0');
1224
0
    out->push_back('.');
1225
0
    printed = 1;
1226
0
  }
1227
43
  return printed;
1228
43
}
float_conversion.cc:unsigned long absl::str_format_internal::(anonymous namespace)::PrintIntegralDigits<(absl::str_format_internal::(anonymous namespace)::FormatStyle)1, unsigned __int128>(unsigned __int128, absl::str_format_internal::(anonymous namespace)::Buffer*)
Line
Count
Source
1211
1.40k
size_t PrintIntegralDigits(Int digits, Buffer* out) {
1212
1.40k
  size_t printed = 0;
1213
1.40k
  if (digits) {
1214
54.4k
    for (; digits; digits /= 10) out->push_front(digits % 10 + '0');
1215
1.40k
    printed = out->size();
1216
1.40k
    if (mode == FormatStyle::Precision) {
1217
1.40k
      out->push_front(*out->begin);
1218
1.40k
      out->begin[1] = '.';
1219
1.40k
    } else {
1220
0
      out->push_back('.');
1221
0
    }
1222
1.40k
  } else if (mode == FormatStyle::Fixed) {
1223
0
    out->push_front('0');
1224
0
    out->push_back('.');
1225
0
    printed = 1;
1226
0
  }
1227
1.40k
  return printed;
1228
1.40k
}
1229
1230
// Back out 'extra_digits' digits and round up if necessary.
1231
void RemoveExtraPrecision(size_t extra_digits,
1232
                          bool has_leftover_value,
1233
                          Buffer* out,
1234
1.40k
                          int* exp_out) {
1235
  // Back out the extra digits
1236
1.40k
  out->end -= extra_digits;
1237
1238
1.40k
  bool needs_to_round_up = [&] {
1239
    // We look at the digit just past the end.
1240
    // There must be 'extra_digits' extra valid digits after end.
1241
1.40k
    if (*out->end > '5') return true;
1242
887
    if (*out->end < '5') return false;
1243
136
    if (has_leftover_value || std::any_of(out->end + 1, out->end + extra_digits,
1244
188
                                          [](char c) { return c != '0'; }))
1245
136
      return true;
1246
1247
    // Ends in ...50*, round to even.
1248
0
    return out->last_digit() % 2 == 1;
1249
136
  }();
1250
1251
1.40k
  if (needs_to_round_up) {
1252
651
    RoundUp<FormatStyle::Precision>(out, exp_out);
1253
651
  }
1254
1.40k
}
1255
1256
// Print the value into the buffer.
1257
// This will not include the exponent, which will be returned in 'exp_out' for
1258
// Precision mode.
1259
template <typename Int, typename Float, FormatStyle mode>
1260
bool FloatToBufferImpl(Int int_mantissa,
1261
                       int exp,
1262
                       size_t precision,
1263
                       Buffer* out,
1264
5.69k
                       int* exp_out) {
1265
5.69k
  assert((CanFitMantissa<Float, Int>()));
1266
1267
5.69k
  const int int_bits = std::numeric_limits<Int>::digits;
1268
1269
  // In precision mode, we start printing one char to the right because it will
1270
  // also include the '.'
1271
  // In fixed mode we put the dot afterwards on the right.
1272
5.69k
  out->begin = out->end =
1273
5.69k
      out->data + 1 + kMaxFixedPrecision + (mode == FormatStyle::Precision);
1274
1275
5.69k
  if (exp >= 0) {
1276
5.65k
    if (std::numeric_limits<Float>::digits + exp > int_bits) {
1277
      // The value will overflow the Int
1278
4.24k
      return false;
1279
4.24k
    }
1280
1.40k
    size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa << exp, out);
1281
1.40k
    size_t digits_to_zero_pad = precision;
1282
1.40k
    if (mode == FormatStyle::Precision) {
1283
1.40k
      *exp_out = static_cast<int>(digits_printed - 1);
1284
1.40k
      if (digits_to_zero_pad < digits_printed - 1) {
1285
1.40k
        RemoveExtraPrecision(digits_printed - 1 - digits_to_zero_pad, false,
1286
1.40k
                             out, exp_out);
1287
1.40k
        return true;
1288
1.40k
      }
1289
0
      digits_to_zero_pad -= digits_printed - 1;
1290
0
    }
1291
0
    for (; digits_to_zero_pad-- > 0;) out->push_back('0');
1292
0
    return true;
1293
1.40k
  }
1294
1295
43
  exp = -exp;
1296
  // We need at least 4 empty bits for the next decimal digit.
1297
  // We will multiply by 10.
1298
43
  if (exp > int_bits - 4) return false;
1299
1300
43
  const Int mask = (Int{1} << exp) - 1;
1301
1302
  // Print the integral part first.
1303
43
  size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa >> exp, out);
1304
43
  int_mantissa &= mask;
1305
1306
43
  size_t fractional_count = precision;
1307
43
  if (mode == FormatStyle::Precision) {
1308
43
    if (digits_printed == 0) {
1309
      // Find the first non-zero digit, when in Precision mode.
1310
43
      *exp_out = 0;
1311
43
      if (int_mantissa) {
1312
0
        while (int_mantissa <= mask) {
1313
0
          int_mantissa *= 10;
1314
0
          --*exp_out;
1315
0
        }
1316
0
      }
1317
43
      out->push_front(static_cast<char>(int_mantissa >> exp) + '0');
1318
43
      out->push_back('.');
1319
43
      int_mantissa &= mask;
1320
43
    } else {
1321
      // We already have a digit, and a '.'
1322
0
      *exp_out = static_cast<int>(digits_printed - 1);
1323
0
      if (fractional_count < digits_printed - 1) {
1324
        // If we had enough digits, return right away.
1325
        // The code below will try to round again otherwise.
1326
0
        RemoveExtraPrecision(digits_printed - 1 - fractional_count,
1327
0
                             int_mantissa != 0, out, exp_out);
1328
0
        return true;
1329
0
      }
1330
0
      fractional_count -= digits_printed - 1;
1331
0
    }
1332
43
  }
1333
1334
258
  auto get_next_digit = [&] {
1335
258
    int_mantissa *= 10;
1336
258
    char digit = static_cast<char>(int_mantissa >> exp);
1337
258
    int_mantissa &= mask;
1338
258
    return digit;
1339
258
  };
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::FloatToBufferImpl<unsigned long, long double, (absl::str_format_internal::(anonymous namespace)::FormatStyle)1>(unsigned long, int, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)::{lambda()#1}::operator()() const
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::FloatToBufferImpl<unsigned __int128, long double, (absl::str_format_internal::(anonymous namespace)::FormatStyle)1>(unsigned __int128, int, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)::{lambda()#1}::operator()() const
float_conversion.cc:absl::str_format_internal::(anonymous namespace)::FloatToBufferImpl<unsigned long, double, (absl::str_format_internal::(anonymous namespace)::FormatStyle)1>(unsigned long, int, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)::{lambda()#1}::operator()() const
Line
Count
Source
1334
258
  auto get_next_digit = [&] {
1335
258
    int_mantissa *= 10;
1336
258
    char digit = static_cast<char>(int_mantissa >> exp);
1337
258
    int_mantissa &= mask;
1338
258
    return digit;
1339
258
  };
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::FloatToBufferImpl<unsigned __int128, double, (absl::str_format_internal::(anonymous namespace)::FormatStyle)1>(unsigned __int128, int, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)::{lambda()#1}::operator()() const
1340
1341
  // Print fractional_count more digits, if available.
1342
258
  for (; fractional_count > 0; --fractional_count) {
1343
215
    out->push_back(get_next_digit() + '0');
1344
215
  }
1345
1346
43
  char next_digit = get_next_digit();
1347
43
  if (next_digit > 5 ||
1348
43
      (next_digit == 5 && (int_mantissa || out->last_digit() % 2 == 1))) {
1349
0
    RoundUp<mode>(out, exp_out);
1350
0
  }
1351
1352
43
  return true;
1353
43
}
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FloatToBufferImpl<unsigned long, long double, (absl::str_format_internal::(anonymous namespace)::FormatStyle)1>(unsigned long, int, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FloatToBufferImpl<unsigned __int128, long double, (absl::str_format_internal::(anonymous namespace)::FormatStyle)1>(unsigned __int128, int, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)
float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FloatToBufferImpl<unsigned long, double, (absl::str_format_internal::(anonymous namespace)::FormatStyle)1>(unsigned long, int, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)
Line
Count
Source
1264
2.86k
                       int* exp_out) {
1265
2.86k
  assert((CanFitMantissa<Float, Int>()));
1266
1267
2.86k
  const int int_bits = std::numeric_limits<Int>::digits;
1268
1269
  // In precision mode, we start printing one char to the right because it will
1270
  // also include the '.'
1271
  // In fixed mode we put the dot afterwards on the right.
1272
2.86k
  out->begin = out->end =
1273
2.86k
      out->data + 1 + kMaxFixedPrecision + (mode == FormatStyle::Precision);
1274
1275
2.86k
  if (exp >= 0) {
1276
2.82k
    if (std::numeric_limits<Float>::digits + exp > int_bits) {
1277
      // The value will overflow the Int
1278
2.82k
      return false;
1279
2.82k
    }
1280
0
    size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa << exp, out);
1281
0
    size_t digits_to_zero_pad = precision;
1282
0
    if (mode == FormatStyle::Precision) {
1283
0
      *exp_out = static_cast<int>(digits_printed - 1);
1284
0
      if (digits_to_zero_pad < digits_printed - 1) {
1285
0
        RemoveExtraPrecision(digits_printed - 1 - digits_to_zero_pad, false,
1286
0
                             out, exp_out);
1287
0
        return true;
1288
0
      }
1289
0
      digits_to_zero_pad -= digits_printed - 1;
1290
0
    }
1291
0
    for (; digits_to_zero_pad-- > 0;) out->push_back('0');
1292
0
    return true;
1293
0
  }
1294
1295
43
  exp = -exp;
1296
  // We need at least 4 empty bits for the next decimal digit.
1297
  // We will multiply by 10.
1298
43
  if (exp > int_bits - 4) return false;
1299
1300
43
  const Int mask = (Int{1} << exp) - 1;
1301
1302
  // Print the integral part first.
1303
43
  size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa >> exp, out);
1304
43
  int_mantissa &= mask;
1305
1306
43
  size_t fractional_count = precision;
1307
43
  if (mode == FormatStyle::Precision) {
1308
43
    if (digits_printed == 0) {
1309
      // Find the first non-zero digit, when in Precision mode.
1310
43
      *exp_out = 0;
1311
43
      if (int_mantissa) {
1312
0
        while (int_mantissa <= mask) {
1313
0
          int_mantissa *= 10;
1314
0
          --*exp_out;
1315
0
        }
1316
0
      }
1317
43
      out->push_front(static_cast<char>(int_mantissa >> exp) + '0');
1318
43
      out->push_back('.');
1319
43
      int_mantissa &= mask;
1320
43
    } else {
1321
      // We already have a digit, and a '.'
1322
0
      *exp_out = static_cast<int>(digits_printed - 1);
1323
0
      if (fractional_count < digits_printed - 1) {
1324
        // If we had enough digits, return right away.
1325
        // The code below will try to round again otherwise.
1326
0
        RemoveExtraPrecision(digits_printed - 1 - fractional_count,
1327
0
                             int_mantissa != 0, out, exp_out);
1328
0
        return true;
1329
0
      }
1330
0
      fractional_count -= digits_printed - 1;
1331
0
    }
1332
43
  }
1333
1334
43
  auto get_next_digit = [&] {
1335
43
    int_mantissa *= 10;
1336
43
    char digit = static_cast<char>(int_mantissa >> exp);
1337
43
    int_mantissa &= mask;
1338
43
    return digit;
1339
43
  };
1340
1341
  // Print fractional_count more digits, if available.
1342
258
  for (; fractional_count > 0; --fractional_count) {
1343
215
    out->push_back(get_next_digit() + '0');
1344
215
  }
1345
1346
43
  char next_digit = get_next_digit();
1347
43
  if (next_digit > 5 ||
1348
43
      (next_digit == 5 && (int_mantissa || out->last_digit() % 2 == 1))) {
1349
0
    RoundUp<mode>(out, exp_out);
1350
0
  }
1351
1352
43
  return true;
1353
43
}
float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FloatToBufferImpl<unsigned __int128, double, (absl::str_format_internal::(anonymous namespace)::FormatStyle)1>(unsigned __int128, int, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)
Line
Count
Source
1264
2.82k
                       int* exp_out) {
1265
2.82k
  assert((CanFitMantissa<Float, Int>()));
1266
1267
2.82k
  const int int_bits = std::numeric_limits<Int>::digits;
1268
1269
  // In precision mode, we start printing one char to the right because it will
1270
  // also include the '.'
1271
  // In fixed mode we put the dot afterwards on the right.
1272
2.82k
  out->begin = out->end =
1273
2.82k
      out->data + 1 + kMaxFixedPrecision + (mode == FormatStyle::Precision);
1274
1275
2.82k
  if (exp >= 0) {
1276
2.82k
    if (std::numeric_limits<Float>::digits + exp > int_bits) {
1277
      // The value will overflow the Int
1278
1.42k
      return false;
1279
1.42k
    }
1280
1.40k
    size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa << exp, out);
1281
1.40k
    size_t digits_to_zero_pad = precision;
1282
1.40k
    if (mode == FormatStyle::Precision) {
1283
1.40k
      *exp_out = static_cast<int>(digits_printed - 1);
1284
1.40k
      if (digits_to_zero_pad < digits_printed - 1) {
1285
1.40k
        RemoveExtraPrecision(digits_printed - 1 - digits_to_zero_pad, false,
1286
1.40k
                             out, exp_out);
1287
1.40k
        return true;
1288
1.40k
      }
1289
0
      digits_to_zero_pad -= digits_printed - 1;
1290
0
    }
1291
0
    for (; digits_to_zero_pad-- > 0;) out->push_back('0');
1292
0
    return true;
1293
1.40k
  }
1294
1295
0
  exp = -exp;
1296
  // We need at least 4 empty bits for the next decimal digit.
1297
  // We will multiply by 10.
1298
0
  if (exp > int_bits - 4) return false;
1299
1300
0
  const Int mask = (Int{1} << exp) - 1;
1301
1302
  // Print the integral part first.
1303
0
  size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa >> exp, out);
1304
0
  int_mantissa &= mask;
1305
1306
0
  size_t fractional_count = precision;
1307
0
  if (mode == FormatStyle::Precision) {
1308
0
    if (digits_printed == 0) {
1309
      // Find the first non-zero digit, when in Precision mode.
1310
0
      *exp_out = 0;
1311
0
      if (int_mantissa) {
1312
0
        while (int_mantissa <= mask) {
1313
0
          int_mantissa *= 10;
1314
0
          --*exp_out;
1315
0
        }
1316
0
      }
1317
0
      out->push_front(static_cast<char>(int_mantissa >> exp) + '0');
1318
0
      out->push_back('.');
1319
0
      int_mantissa &= mask;
1320
0
    } else {
1321
      // We already have a digit, and a '.'
1322
0
      *exp_out = static_cast<int>(digits_printed - 1);
1323
0
      if (fractional_count < digits_printed - 1) {
1324
        // If we had enough digits, return right away.
1325
        // The code below will try to round again otherwise.
1326
0
        RemoveExtraPrecision(digits_printed - 1 - fractional_count,
1327
0
                             int_mantissa != 0, out, exp_out);
1328
0
        return true;
1329
0
      }
1330
0
      fractional_count -= digits_printed - 1;
1331
0
    }
1332
0
  }
1333
1334
0
  auto get_next_digit = [&] {
1335
0
    int_mantissa *= 10;
1336
0
    char digit = static_cast<char>(int_mantissa >> exp);
1337
0
    int_mantissa &= mask;
1338
0
    return digit;
1339
0
  };
1340
1341
  // Print fractional_count more digits, if available.
1342
0
  for (; fractional_count > 0; --fractional_count) {
1343
0
    out->push_back(get_next_digit() + '0');
1344
0
  }
1345
1346
0
  char next_digit = get_next_digit();
1347
0
  if (next_digit > 5 ||
1348
0
      (next_digit == 5 && (int_mantissa || out->last_digit() % 2 == 1))) {
1349
0
    RoundUp<mode>(out, exp_out);
1350
0
  }
1351
1352
0
  return true;
1353
0
}
1354
1355
template <FormatStyle mode, typename Float>
1356
bool FloatToBuffer(Decomposed<Float> decomposed,
1357
                   size_t precision,
1358
                   Buffer* out,
1359
2.86k
                   int* exp) {
1360
2.86k
  if (precision > kMaxFixedPrecision) return false;
1361
1362
  // Try with uint64_t.
1363
2.86k
  if (CanFitMantissa<Float, std::uint64_t>() &&
1364
2.86k
      FloatToBufferImpl<std::uint64_t, Float, mode>(
1365
2.86k
          static_cast<std::uint64_t>(decomposed.mantissa), decomposed.exponent,
1366
2.86k
          precision, out, exp))
1367
43
    return true;
1368
1369
2.82k
#if defined(ABSL_HAVE_INTRINSIC_INT128)
1370
  // If that is not enough, try with __uint128_t.
1371
2.82k
  return CanFitMantissa<Float, __uint128_t>() &&
1372
2.82k
         FloatToBufferImpl<__uint128_t, Float, mode>(
1373
2.82k
             static_cast<__uint128_t>(decomposed.mantissa), decomposed.exponent,
1374
2.82k
             precision, out, exp);
1375
0
#endif
1376
0
  return false;
1377
2.86k
}
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FloatToBuffer<(absl::str_format_internal::(anonymous namespace)::FormatStyle)1, long double>(absl::str_format_internal::(anonymous namespace)::Decomposed<long double>, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)
float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FloatToBuffer<(absl::str_format_internal::(anonymous namespace)::FormatStyle)1, double>(absl::str_format_internal::(anonymous namespace)::Decomposed<double>, unsigned long, absl::str_format_internal::(anonymous namespace)::Buffer*, int*)
Line
Count
Source
1359
2.86k
                   int* exp) {
1360
2.86k
  if (precision > kMaxFixedPrecision) return false;
1361
1362
  // Try with uint64_t.
1363
2.86k
  if (CanFitMantissa<Float, std::uint64_t>() &&
1364
2.86k
      FloatToBufferImpl<std::uint64_t, Float, mode>(
1365
2.86k
          static_cast<std::uint64_t>(decomposed.mantissa), decomposed.exponent,
1366
2.86k
          precision, out, exp))
1367
43
    return true;
1368
1369
2.82k
#if defined(ABSL_HAVE_INTRINSIC_INT128)
1370
  // If that is not enough, try with __uint128_t.
1371
2.82k
  return CanFitMantissa<Float, __uint128_t>() &&
1372
2.82k
         FloatToBufferImpl<__uint128_t, Float, mode>(
1373
2.82k
             static_cast<__uint128_t>(decomposed.mantissa), decomposed.exponent,
1374
2.82k
             precision, out, exp);
1375
0
#endif
1376
0
  return false;
1377
2.86k
}
1378
1379
void WriteBufferToSink(char sign_char, absl::string_view str,
1380
                       const FormatConversionSpecImpl &conv,
1381
1.44k
                       FormatSinkImpl *sink) {
1382
1.44k
  size_t left_spaces = 0, zeros = 0, right_spaces = 0;
1383
1.44k
  size_t missing_chars = 0;
1384
1.44k
  if (conv.width() >= 0) {
1385
0
    const size_t conv_width_size_t = static_cast<size_t>(conv.width());
1386
0
    const size_t existing_chars =
1387
0
        str.size() + static_cast<size_t>(sign_char != 0);
1388
0
    if (conv_width_size_t > existing_chars)
1389
0
      missing_chars = conv_width_size_t - existing_chars;
1390
0
  }
1391
1.44k
  if (conv.has_left_flag()) {
1392
0
    right_spaces = missing_chars;
1393
1.44k
  } else if (conv.has_zero_flag()) {
1394
0
    zeros = missing_chars;
1395
1.44k
  } else {
1396
1.44k
    left_spaces = missing_chars;
1397
1.44k
  }
1398
1399
1.44k
  sink->Append(left_spaces, ' ');
1400
1.44k
  if (sign_char != '\0') sink->Append(1, sign_char);
1401
1.44k
  sink->Append(zeros, '0');
1402
1.44k
  sink->Append(str);
1403
1.44k
  sink->Append(right_spaces, ' ');
1404
1.44k
}
1405
1406
template <typename Int>
1407
0
void FormatE(Int mantissa, int exp, bool uppercase, const FormatState& state) {
1408
0
  if (exp > 0) {
1409
0
    const int total_bits =
1410
0
        static_cast<int>(sizeof(Int) * 8) - LeadingZeros(mantissa) + exp;
1411
0
    if (total_bits > 128) {
1412
0
      FormatEPositiveExpSlow(mantissa, exp, uppercase, state);
1413
0
      return;
1414
0
    }
1415
0
  } else {
1416
0
    if (ABSL_PREDICT_FALSE(exp < -128)) {
1417
0
      FormatENegativeExpSlow(mantissa, exp, uppercase, state);
1418
0
      return;
1419
0
    }
1420
0
  }
1421
0
  FormatEFast(mantissa, exp, uppercase, state);
1422
0
}
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatE<absl::uint128>(absl::uint128, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatE<unsigned long>(unsigned long, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)
1423
1424
// Guaranteed to fit into 128 bits at this point
1425
template <typename Int>
1426
0
void FormatEFast(Int v, int exp, bool uppercase, const FormatState& state) {
1427
0
  if (!v) {
1428
0
    absl::string_view mantissa_str = state.ShouldPrintDot() ? "0." : "0";
1429
0
    FinalPrint(state, mantissa_str, 0, state.precision,
1430
0
               uppercase ? "E+00" : "e+00");
1431
0
    return;
1432
0
  }
1433
0
  constexpr int kInputBits = sizeof(Int) * 8;
1434
0
  constexpr int kMaxFractionalDigits = 128;
1435
0
  constexpr int kBufferSize = 2 +                    // '.' + rounding
1436
0
                              kMaxFixedPrecision +   // Integral
1437
0
                              kMaxFractionalDigits;  // Fractional
1438
0
  const int total_bits = kInputBits - LeadingZeros(v) + exp;
1439
0
  char buffer[kBufferSize];
1440
0
  char* integral_start = buffer + 2;
1441
0
  char* integral_end = buffer + 2 + kMaxFixedPrecision;
1442
0
  char* final_start;
1443
0
  char* final_end;
1444
0
  bool zero_integral = false;
1445
0
  int scientific_exp = 0;
1446
0
  size_t digits_printed = 0;
1447
0
  size_t trailing_zeros = 0;
1448
0
  bool has_more_non_zero = false;
1449
1450
0
  auto check_integral_zeros =
1451
0
      [](char* const begin, char* const end,
1452
0
         const size_t precision, size_t digits_processed) -> bool {
1453
    // When considering rounding to even, we care about the digits after the
1454
    // round digit which means the total digits to move from the start is
1455
    // precision + 2 since the first digit we print before the decimal point
1456
    // is not a part of precision.
1457
0
    size_t digit_upper_bound = precision + 2;
1458
0
    if (digits_processed > digit_upper_bound) {
1459
0
      return std::any_of(begin + digit_upper_bound, end,
1460
0
                         [](char c) { return c != '0'; });
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::FormatEFast<absl::uint128>(absl::uint128, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)::{lambda(char*, char*, unsigned long, unsigned long)#1}::operator()(char*, char*, unsigned long, unsigned long) const::{lambda(char)#1}::operator()(char) const
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::FormatEFast<unsigned long>(unsigned long, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)::{lambda(char*, char*, unsigned long, unsigned long)#1}::operator()(char*, char*, unsigned long, unsigned long) const::{lambda(char)#1}::operator()(char) const
1461
0
    }
1462
0
    return false;
1463
0
  };
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::FormatEFast<absl::uint128>(absl::uint128, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)::{lambda(char*, char*, unsigned long, unsigned long)#1}::operator()(char*, char*, unsigned long, unsigned long) const
Unexecuted instantiation: float_conversion.cc:absl::str_format_internal::(anonymous namespace)::FormatEFast<unsigned long>(unsigned long, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)::{lambda(char*, char*, unsigned long, unsigned long)#1}::operator()(char*, char*, unsigned long, unsigned long) const
1464
1465
0
  if (exp >= 0) {
1466
0
    integral_end = total_bits <= 64 ? numbers_internal::FastIntToBuffer(
1467
0
                               static_cast<uint64_t>(v) << exp, integral_start)
1468
0
                         : numbers_internal::FastIntToBuffer(
1469
0
                               static_cast<uint128>(v) << exp, integral_start);
1470
0
    *integral_end = '0';
1471
0
    final_start = integral_start;
1472
    // Integral is guaranteed to be non-zero at this point.
1473
0
    scientific_exp = static_cast<int>(integral_end - integral_start) - 1;
1474
0
    digits_printed = static_cast<size_t>(integral_end - integral_start);
1475
0
    final_end = integral_end;
1476
0
    has_more_non_zero = check_integral_zeros(integral_start, integral_end,
1477
0
                                             state.precision, digits_printed);
1478
0
  } else {
1479
0
    exp = -exp;
1480
0
    if (exp < kInputBits) {
1481
0
      integral_end =
1482
0
          numbers_internal::FastIntToBuffer(v >> exp, integral_start);
1483
0
    }
1484
0
    *integral_end = '0';
1485
    // We didn't move integral_start and it gets set to 0 in
1486
0
    zero_integral = exp >= kInputBits || v >> exp == 0;
1487
0
    if (!zero_integral) {
1488
0
      digits_printed = static_cast<size_t>(integral_end - integral_start);
1489
0
      has_more_non_zero = check_integral_zeros(integral_start, integral_end,
1490
0
                                               state.precision, digits_printed);
1491
0
      final_end = integral_end;
1492
0
    }
1493
    // Print fractional digits
1494
0
    char* fractional_start = integral_end;
1495
1496
0
    size_t digits_to_print = (state.precision + 1) >= digits_printed
1497
0
                                 ? state.precision + 1 - digits_printed
1498
0
                                 : 0;
1499
0
    bool print_extra = digits_printed <= state.precision + 1;
1500
0
    auto [fractional_end, skipped_zeros, has_nonzero_rem] =
1501
0
        exp <= 64 ? PrintFractionalDigitsScientific(
1502
0
                        v, fractional_start, exp, digits_to_print + print_extra,
1503
0
                        zero_integral)
1504
0
                  : PrintFractionalDigitsScientific(
1505
0
                        static_cast<uint128>(v), fractional_start, exp,
1506
0
                        digits_to_print + print_extra, zero_integral);
1507
0
    final_end = fractional_end;
1508
0
    *fractional_end = '0';
1509
0
    has_more_non_zero |= has_nonzero_rem;
1510
0
    digits_printed += static_cast<size_t>(fractional_end - fractional_start);
1511
0
    if (zero_integral) {
1512
0
      scientific_exp = -1 * static_cast<int>(skipped_zeros + 1);
1513
0
    } else {
1514
0
      scientific_exp = static_cast<int>(integral_end - integral_start) - 1;
1515
0
    }
1516
    // Don't do any rounding here, we will do it ourselves.
1517
0
    final_start = zero_integral ? fractional_start : integral_start;
1518
0
  }
1519
1520
  // For rounding
1521
0
  if (digits_printed >= state.precision + 1) {
1522
0
    final_start[-1] = '0';
1523
0
    char* round_digit_ptr = final_start + 1 + state.precision;
1524
0
    if (*round_digit_ptr > '5') {
1525
0
      RoundUp(round_digit_ptr - 1);
1526
0
    } else if (*round_digit_ptr == '5') {
1527
0
      if (has_more_non_zero) {
1528
0
        RoundUp(round_digit_ptr - 1);
1529
0
      } else {
1530
0
        RoundToEven(round_digit_ptr - 1);
1531
0
      }
1532
0
    }
1533
0
    final_end = round_digit_ptr;
1534
0
    if (final_start[-1] == '1') {
1535
0
      --final_start;
1536
0
      ++scientific_exp;
1537
0
      --final_end;
1538
0
    }
1539
0
  } else {
1540
    // Need to pad with zeros.
1541
0
    trailing_zeros = state.precision - (digits_printed - 1);
1542
0
  }
1543
1544
0
  if (state.precision > 0 || state.ShouldPrintDot()) {
1545
0
    final_start[-1] = *final_start;
1546
0
    *final_start = '.';
1547
0
    --final_start;
1548
0
  }
1549
1550
  // We need to add 2 to the buffer size for the +/- sign and the e
1551
0
  constexpr size_t kExpBufferSize = numbers_internal::kFastToBufferSize + 2;
1552
0
  char exp_buffer[kExpBufferSize];
1553
0
  char* exp_ptr_start = exp_buffer;
1554
0
  char* exp_ptr = exp_ptr_start;
1555
0
  *exp_ptr++ = uppercase ? 'E' : 'e';
1556
0
  if (scientific_exp >= 0) {
1557
0
    *exp_ptr++ = '+';
1558
0
  } else {
1559
0
    *exp_ptr++ = '-';
1560
0
    scientific_exp = -scientific_exp;
1561
0
  }
1562
1563
0
  if (scientific_exp < 10) {
1564
0
    *exp_ptr++ = '0';
1565
0
  }
1566
0
  exp_ptr = numbers_internal::FastIntToBuffer(scientific_exp, exp_ptr);
1567
0
  FinalPrint(state,
1568
0
             absl::string_view(final_start,
1569
0
                               static_cast<size_t>(final_end - final_start)),
1570
0
             0, trailing_zeros,
1571
0
             absl::string_view(exp_ptr_start,
1572
0
                               static_cast<size_t>(exp_ptr - exp_ptr_start)));
1573
0
}
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatEFast<absl::uint128>(absl::uint128, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)
Unexecuted instantiation: float_conversion.cc:void absl::str_format_internal::(anonymous namespace)::FormatEFast<unsigned long>(unsigned long, int, bool, absl::str_format_internal::(anonymous namespace)::FormatState const&)
1574
1575
void FormatENegativeExpSlow(uint128 mantissa, int exp, bool uppercase,
1576
0
                            const FormatState& state) {
1577
0
  assert(exp < 0);
1578
1579
0
  FractionalDigitGenerator::RunConversion(
1580
0
      mantissa, -exp,
1581
0
      [&](FractionalDigitGenerator digit_gen) {
1582
0
        int first_digit = 0;
1583
0
        size_t nines = 0;
1584
0
        int num_leading_zeros = 0;
1585
0
        while (digit_gen.HasMoreDigits()) {
1586
0
          auto digits = digit_gen.GetDigits();
1587
0
          if (digits.digit_before_nine != 0) {
1588
0
            first_digit = digits.digit_before_nine;
1589
0
            nines = digits.num_nines;
1590
0
            break;
1591
0
          } else if (digits.num_nines > 0) {
1592
            // This also means the first digit is 0
1593
0
            first_digit = 9;
1594
0
            nines = digits.num_nines - 1;
1595
0
            num_leading_zeros++;
1596
0
            break;
1597
0
          }
1598
0
          num_leading_zeros++;
1599
0
        }
1600
1601
0
        bool change_to_zeros = false;
1602
0
        if (nines >= state.precision || state.precision == 0) {
1603
0
          bool round_up = false;
1604
0
          if (nines == state.precision) {
1605
0
            round_up = digit_gen.IsGreaterThanHalf();
1606
0
          } else {
1607
0
            round_up = nines > 0 || digit_gen.IsGreaterThanHalf();
1608
0
          }
1609
0
          if (round_up) {
1610
0
            first_digit = (first_digit == 9 ? 1 : first_digit + 1);
1611
0
            num_leading_zeros -= (first_digit == 1);
1612
0
            change_to_zeros = true;
1613
0
          }
1614
0
        }
1615
0
        int scientific_exp = -(num_leading_zeros + 1);
1616
0
        assert(scientific_exp < 0);
1617
0
        char exp_buffer[numbers_internal::kFastToBufferSize];
1618
0
        char* exp_start = exp_buffer;
1619
0
        *exp_start++ = '-';
1620
0
        if (scientific_exp > -10) {
1621
0
          *exp_start++ = '0';
1622
0
        }
1623
0
        scientific_exp *= -1;
1624
0
        char* exp_end =
1625
0
            numbers_internal::FastIntToBuffer(scientific_exp, exp_start);
1626
0
        const size_t total_digits =
1627
0
            1                                   // First digit
1628
0
            + (state.ShouldPrintDot() ? 1 : 0)  // Decimal point
1629
0
            + state.precision                   // Digits after decimal
1630
0
            + 1                                 // 'e' or 'E'
1631
0
            + static_cast<size_t>(exp_end - exp_buffer);  // Exponent digits
1632
1633
0
        const auto padding = ExtraWidthToPadding(
1634
0
            total_digits + (state.sign_char != '\0' ? 1 : 0), state);
1635
0
        state.sink->Append(padding.left_spaces, ' ');
1636
1637
0
        if (state.sign_char != '\0') {
1638
0
          state.sink->Append(1, state.sign_char);
1639
0
        }
1640
1641
0
        state.sink->Append(1, static_cast<char>(first_digit + '0'));
1642
0
        if (state.ShouldPrintDot()) {
1643
0
          state.sink->Append(1, '.');
1644
0
        }
1645
0
        size_t digits_to_go = state.precision;
1646
0
        size_t nines_to_print = std::min(nines, digits_to_go);
1647
0
        state.sink->Append(nines_to_print, change_to_zeros ? '0' : '9');
1648
0
        digits_to_go -= nines_to_print;
1649
0
        while (digits_to_go > 0 && digit_gen.HasMoreDigits()) {
1650
0
          auto digits = digit_gen.GetDigits();
1651
1652
0
          if (digits.num_nines + 1 < digits_to_go) {
1653
0
            state.sink->Append(1, digits.digit_before_nine + '0');
1654
0
            state.sink->Append(digits.num_nines, '9');
1655
0
            digits_to_go -= digits.num_nines + 1;
1656
0
          } else {
1657
0
            bool round_up = false;
1658
0
            if (digits.num_nines + 1 > digits_to_go) {
1659
0
              round_up = true;
1660
0
            } else if (digit_gen.IsGreaterThanHalf()) {
1661
0
              round_up = true;
1662
0
            } else if (digit_gen.IsExactlyHalf()) {
1663
0
              round_up =
1664
0
                  digits.num_nines != 0 || digits.digit_before_nine % 2 == 1;
1665
0
            }
1666
0
            if (round_up) {
1667
0
              state.sink->Append(1, digits.digit_before_nine + '1');
1668
0
              --digits_to_go;
1669
0
            } else {
1670
0
              state.sink->Append(1, digits.digit_before_nine + '0');
1671
0
              state.sink->Append(digits_to_go - 1, '9');
1672
0
              digits_to_go = 0;
1673
0
            }
1674
0
            break;
1675
0
          }
1676
0
        }
1677
0
        state.sink->Append(digits_to_go, '0');
1678
0
        state.sink->Append(1, uppercase ? 'E' : 'e');
1679
0
        state.sink->Append(absl::string_view(
1680
0
            exp_buffer, static_cast<size_t>(exp_end - exp_buffer)));
1681
0
        state.sink->Append(padding.right_spaces, ' ');
1682
0
      });
1683
0
}
1684
1685
std::optional<int> GetOneDigit(BinaryToDecimal& btd,
1686
0
                               absl::string_view& digits_view) {
1687
0
  if (digits_view.empty()) {
1688
0
    if (!btd.AdvanceDigits()) return std::nullopt;
1689
0
    digits_view = btd.CurrentDigits();
1690
0
  }
1691
0
  char d = digits_view.front();
1692
0
  digits_view.remove_prefix(1);
1693
0
  return d - '0';
1694
0
}
1695
1696
struct DigitRun {
1697
  std::optional<int> digit;
1698
  size_t nines;
1699
};
1700
1701
0
DigitRun GetDigits(BinaryToDecimal& btd, absl::string_view& digits_view) {
1702
0
  auto peek_digit = [&]() -> std::optional<int> {
1703
0
    if (digits_view.empty()) {
1704
0
      if (!btd.AdvanceDigits()) return std::nullopt;
1705
0
      digits_view = btd.CurrentDigits();
1706
0
    }
1707
0
    return digits_view.front() - '0';
1708
0
  };
1709
1710
0
  auto digit_before_nines = GetOneDigit(btd, digits_view);
1711
0
  if (!digit_before_nines.has_value()) return {std::nullopt, 0};
1712
1713
0
  auto next_digit = peek_digit();
1714
0
  size_t num_nines = 0;
1715
0
  while (next_digit == 9) {
1716
    // consume the 9
1717
0
    GetOneDigit(btd, digits_view);
1718
0
    ++num_nines;
1719
0
    next_digit = peek_digit();
1720
0
  }
1721
0
  return digit_before_nines == 9
1722
0
             ? DigitRun{std::nullopt, num_nines + 1}
1723
0
             : DigitRun{digit_before_nines, num_nines};
1724
0
}
1725
1726
void FormatEPositiveExpSlow(uint128 mantissa, int exp, bool uppercase,
1727
0
                            const FormatState& state) {
1728
0
  BinaryToDecimal::RunConversion(
1729
0
      mantissa, exp, [&](BinaryToDecimal btd) {
1730
0
        int scientific_exp = static_cast<int>(btd.TotalDigits() - 1);
1731
0
        absl::string_view digits_view = btd.CurrentDigits();
1732
1733
0
        size_t digits_to_go = state.precision + 1;
1734
0
        auto [first_digit_opt, nines] = GetDigits(btd, digits_view);
1735
0
        if (!first_digit_opt.has_value() && nines == 0) {
1736
0
          return;
1737
0
        }
1738
1739
0
        int first_digit = first_digit_opt.value_or(9);
1740
0
        if (!first_digit_opt) {
1741
0
          --nines;
1742
0
        }
1743
1744
        // At this point we are guaranteed to have some sort of first digit
1745
0
        bool change_to_zeros = false;
1746
0
        if (nines + 1 >= digits_to_go) {
1747
          // Everything we need to print is in the first DigitRun
1748
0
          auto next_digit_opt = GetDigits(btd, digits_view).digit;
1749
0
          if (nines == state.precision) {
1750
0
            change_to_zeros = next_digit_opt.value_or(0) > 4;
1751
0
          } else {
1752
0
            change_to_zeros = true;
1753
0
          }
1754
0
          if (change_to_zeros) {
1755
0
            if (first_digit != 9) {
1756
0
              first_digit = first_digit + 1;
1757
0
            } else {
1758
0
              first_digit = 1;
1759
0
              ++scientific_exp;
1760
0
            }
1761
0
          }
1762
0
        }
1763
1764
0
        char exp_buffer[numbers_internal::kFastToBufferSize];
1765
0
        char* exp_buffer_end =
1766
0
            numbers_internal::FastIntToBuffer(scientific_exp, exp_buffer);
1767
0
        const size_t total_digits_out =
1768
0
            1 + state.ShouldPrintDot() + state.precision + 2 +
1769
0
            (static_cast<size_t>(exp_buffer_end - exp_buffer));
1770
1771
0
        const auto padding = ExtraWidthToPadding(
1772
0
            total_digits_out + (state.sign_char != '\0' ? 1 : 0), state);
1773
1774
0
        state.sink->Append(padding.left_spaces, ' ');
1775
0
        if (state.sign_char != '\0') {
1776
0
          state.sink->Append(1, state.sign_char);
1777
0
        }
1778
0
        state.sink->Append(1, static_cast<char>(first_digit + '0'));
1779
0
        --digits_to_go;
1780
0
        if (state.precision > 0 || state.ShouldPrintDot()) {
1781
0
          state.sink->Append(1, '.');
1782
0
        }
1783
0
        state.sink->Append(std::min(digits_to_go, nines),
1784
0
                           change_to_zeros ? '0' : '9');
1785
0
        digits_to_go -= std::min(digits_to_go, nines);
1786
0
        while (digits_to_go > 0) {
1787
0
          auto [digit_opt, curr_nines] = GetDigits(btd, digits_view);
1788
0
          if (!digit_opt.has_value()) break;
1789
0
          int digit = *digit_opt;
1790
0
          if (curr_nines + 1 < digits_to_go) {
1791
0
            state.sink->Append(1, static_cast<char>(digit + '0'));
1792
0
            state.sink->Append(curr_nines, '9');
1793
0
            digits_to_go -= curr_nines + 1;
1794
0
          } else {
1795
0
            bool need_round_up = false;
1796
0
            auto next_digit_opt = GetDigits(btd, digits_view).digit;
1797
0
            if (digits_to_go == 1) {
1798
0
              need_round_up = curr_nines > 0 || next_digit_opt > 4;
1799
0
            } else if (digits_to_go == curr_nines + 1) {
1800
              // Only round if next digit is > 4
1801
0
              need_round_up = next_digit_opt.value_or(0) > 4;
1802
0
            } else {
1803
              // we know we need to round since nine is after precision ends
1804
0
              need_round_up = true;
1805
0
            }
1806
0
            state.sink->Append(1,
1807
0
                               static_cast<char>(digit + need_round_up + '0'));
1808
0
            state.sink->Append(digits_to_go - 1, need_round_up ? '0' : '9');
1809
0
            digits_to_go = 0;
1810
0
          }
1811
0
        }
1812
1813
0
        if (digits_to_go > 0) {
1814
0
          state.sink->Append(digits_to_go, '0');
1815
0
        }
1816
0
        state.sink->Append(1, uppercase ? 'E' : 'e');
1817
0
        state.sink->Append(1, scientific_exp >= 0 ? '+' : '-');
1818
0
        if (scientific_exp < 10) {
1819
0
          state.sink->Append(1, '0');
1820
0
        }
1821
0
        state.sink->Append(absl::string_view(
1822
0
            exp_buffer, static_cast<size_t>(exp_buffer_end - exp_buffer)));
1823
0
        state.sink->Append(padding.right_spaces, ' ');
1824
0
      });
1825
0
}
1826
1827
template <typename Float>
1828
bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv,
1829
2.86k
                 FormatSinkImpl *sink) {
1830
  // Print the sign or the sign column.
1831
2.86k
  Float abs_v = v;
1832
2.86k
  char sign_char = 0;
1833
2.86k
  if (std::signbit(abs_v)) {
1834
1.81k
    sign_char = '-';
1835
1.81k
    abs_v = -abs_v;
1836
1.81k
  } else if (conv.has_show_pos_flag()) {
1837
0
    sign_char = '+';
1838
1.05k
  } else if (conv.has_sign_col_flag()) {
1839
0
    sign_char = ' ';
1840
0
  }
1841
1842
  // Print nan/inf.
1843
2.86k
  if (ConvertNonNumericFloats(sign_char, abs_v, conv, sink)) {
1844
0
    return true;
1845
0
  }
1846
1847
2.86k
  size_t precision =
1848
2.86k
      conv.precision() < 0 ? 6 : static_cast<size_t>(conv.precision());
1849
1850
2.86k
  int exp = 0;
1851
1852
2.86k
  auto decomposed = Decompose(abs_v);
1853
1854
2.86k
  Buffer buffer;
1855
1856
2.86k
  FormatConversionChar c = conv.conversion_char();
1857
1858
2.86k
  if (c == FormatConversionCharInternal::f ||
1859
2.86k
      c == FormatConversionCharInternal::F) {
1860
0
    FormatF(decomposed.mantissa, decomposed.exponent,
1861
0
            {sign_char, precision, conv, sink});
1862
0
    return true;
1863
2.86k
  } else if (c == FormatConversionCharInternal::e ||
1864
2.86k
             c == FormatConversionCharInternal::E) {
1865
0
    FormatE(decomposed.mantissa, decomposed.exponent,
1866
0
            FormatConversionCharIsUpper(conv.conversion_char()),
1867
0
            {sign_char, precision, conv, sink});
1868
0
    return true;
1869
2.86k
  } else if (c == FormatConversionCharInternal::g ||
1870
2.86k
             c == FormatConversionCharInternal::G) {
1871
2.86k
    precision = std::max(precision, size_t{1}) - 1;
1872
2.86k
    if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer,
1873
2.86k
                                               &exp)) {
1874
1.42k
      return FallbackToSnprintf(v, conv, sink);
1875
1.42k
    }
1876
1.44k
    if ((exp < 0 || precision + 1 > static_cast<size_t>(exp)) && exp >= -4) {
1877
43
      if (exp < 0) {
1878
        // Have 1.23456, needs 0.00123456
1879
        // Move the first digit
1880
0
        buffer.begin[1] = *buffer.begin;
1881
        // Add some zeros
1882
0
        for (; exp < -1; ++exp) *buffer.begin-- = '0';
1883
0
        *buffer.begin-- = '.';
1884
0
        *buffer.begin = '0';
1885
43
      } else if (exp > 0) {
1886
        // Have 1.23456, needs 1234.56
1887
        // Move the '.' exp positions to the right.
1888
0
        std::rotate(buffer.begin + 1, buffer.begin + 2, buffer.begin + exp + 2);
1889
0
      }
1890
43
      exp = 0;
1891
43
    }
1892
1.44k
    if (!conv.has_alt_flag()) {
1893
2.22k
      while (buffer.back() == '0') buffer.pop_back();
1894
1.44k
      if (buffer.back() == '.') buffer.pop_back();
1895
1.44k
    }
1896
1.44k
    if (exp) {
1897
1.40k
      PrintExponent(
1898
1.40k
          exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e',
1899
1.40k
          &buffer);
1900
1.40k
    }
1901
1.44k
  } else if (c == FormatConversionCharInternal::a ||
1902
0
             c == FormatConversionCharInternal::A) {
1903
0
    bool uppercase = (c == FormatConversionCharInternal::A);
1904
0
    FormatA(HexFloatTypeParams(Float{}), decomposed.mantissa,
1905
0
            decomposed.exponent, uppercase, {sign_char, precision, conv, sink});
1906
0
    return true;
1907
0
  } else {
1908
0
    return false;
1909
0
  }
1910
1911
1.44k
  WriteBufferToSink(
1912
1.44k
      sign_char,
1913
1.44k
      absl::string_view(buffer.begin,
1914
1.44k
                        static_cast<size_t>(buffer.end - buffer.begin)),
1915
1.44k
      conv, sink);
1916
1917
1.44k
  return true;
1918
2.86k
}
Unexecuted instantiation: float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FloatToSink<long double>(long double, absl::str_format_internal::FormatConversionSpecImpl const&, absl::str_format_internal::FormatSinkImpl*)
float_conversion.cc:bool absl::str_format_internal::(anonymous namespace)::FloatToSink<double>(double, absl::str_format_internal::FormatConversionSpecImpl const&, absl::str_format_internal::FormatSinkImpl*)
Line
Count
Source
1829
2.86k
                 FormatSinkImpl *sink) {
1830
  // Print the sign or the sign column.
1831
2.86k
  Float abs_v = v;
1832
2.86k
  char sign_char = 0;
1833
2.86k
  if (std::signbit(abs_v)) {
1834
1.81k
    sign_char = '-';
1835
1.81k
    abs_v = -abs_v;
1836
1.81k
  } else if (conv.has_show_pos_flag()) {
1837
0
    sign_char = '+';
1838
1.05k
  } else if (conv.has_sign_col_flag()) {
1839
0
    sign_char = ' ';
1840
0
  }
1841
1842
  // Print nan/inf.
1843
2.86k
  if (ConvertNonNumericFloats(sign_char, abs_v, conv, sink)) {
1844
0
    return true;
1845
0
  }
1846
1847
2.86k
  size_t precision =
1848
2.86k
      conv.precision() < 0 ? 6 : static_cast<size_t>(conv.precision());
1849
1850
2.86k
  int exp = 0;
1851
1852
2.86k
  auto decomposed = Decompose(abs_v);
1853
1854
2.86k
  Buffer buffer;
1855
1856
2.86k
  FormatConversionChar c = conv.conversion_char();
1857
1858
2.86k
  if (c == FormatConversionCharInternal::f ||
1859
2.86k
      c == FormatConversionCharInternal::F) {
1860
0
    FormatF(decomposed.mantissa, decomposed.exponent,
1861
0
            {sign_char, precision, conv, sink});
1862
0
    return true;
1863
2.86k
  } else if (c == FormatConversionCharInternal::e ||
1864
2.86k
             c == FormatConversionCharInternal::E) {
1865
0
    FormatE(decomposed.mantissa, decomposed.exponent,
1866
0
            FormatConversionCharIsUpper(conv.conversion_char()),
1867
0
            {sign_char, precision, conv, sink});
1868
0
    return true;
1869
2.86k
  } else if (c == FormatConversionCharInternal::g ||
1870
2.86k
             c == FormatConversionCharInternal::G) {
1871
2.86k
    precision = std::max(precision, size_t{1}) - 1;
1872
2.86k
    if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer,
1873
2.86k
                                               &exp)) {
1874
1.42k
      return FallbackToSnprintf(v, conv, sink);
1875
1.42k
    }
1876
1.44k
    if ((exp < 0 || precision + 1 > static_cast<size_t>(exp)) && exp >= -4) {
1877
43
      if (exp < 0) {
1878
        // Have 1.23456, needs 0.00123456
1879
        // Move the first digit
1880
0
        buffer.begin[1] = *buffer.begin;
1881
        // Add some zeros
1882
0
        for (; exp < -1; ++exp) *buffer.begin-- = '0';
1883
0
        *buffer.begin-- = '.';
1884
0
        *buffer.begin = '0';
1885
43
      } else if (exp > 0) {
1886
        // Have 1.23456, needs 1234.56
1887
        // Move the '.' exp positions to the right.
1888
0
        std::rotate(buffer.begin + 1, buffer.begin + 2, buffer.begin + exp + 2);
1889
0
      }
1890
43
      exp = 0;
1891
43
    }
1892
1.44k
    if (!conv.has_alt_flag()) {
1893
2.22k
      while (buffer.back() == '0') buffer.pop_back();
1894
1.44k
      if (buffer.back() == '.') buffer.pop_back();
1895
1.44k
    }
1896
1.44k
    if (exp) {
1897
1.40k
      PrintExponent(
1898
1.40k
          exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e',
1899
1.40k
          &buffer);
1900
1.40k
    }
1901
1.44k
  } else if (c == FormatConversionCharInternal::a ||
1902
0
             c == FormatConversionCharInternal::A) {
1903
0
    bool uppercase = (c == FormatConversionCharInternal::A);
1904
0
    FormatA(HexFloatTypeParams(Float{}), decomposed.mantissa,
1905
0
            decomposed.exponent, uppercase, {sign_char, precision, conv, sink});
1906
0
    return true;
1907
0
  } else {
1908
0
    return false;
1909
0
  }
1910
1911
1.44k
  WriteBufferToSink(
1912
1.44k
      sign_char,
1913
1.44k
      absl::string_view(buffer.begin,
1914
1.44k
                        static_cast<size_t>(buffer.end - buffer.begin)),
1915
1.44k
      conv, sink);
1916
1917
1.44k
  return true;
1918
2.86k
}
1919
1920
}  // namespace
1921
1922
bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv,
1923
0
                      FormatSinkImpl *sink) {
1924
0
  if (IsDoubleDouble()) {
1925
    // This is the `double-double` representation of `long double`. We do not
1926
    // handle it natively. Fallback to snprintf.
1927
0
    return FallbackToSnprintf(v, conv, sink);
1928
0
  }
1929
1930
0
  return FloatToSink(v, conv, sink);
1931
0
}
1932
1933
bool ConvertFloatImpl(float v, const FormatConversionSpecImpl &conv,
1934
1.43k
                      FormatSinkImpl *sink) {
1935
1.43k
  return FloatToSink(static_cast<double>(v), conv, sink);
1936
1.43k
}
1937
1938
bool ConvertFloatImpl(double v, const FormatConversionSpecImpl &conv,
1939
1.43k
                      FormatSinkImpl *sink) {
1940
1.43k
  return FloatToSink(v, conv, sink);
1941
1.43k
}
1942
1943
}  // namespace str_format_internal
1944
ABSL_NAMESPACE_END
1945
}  // namespace absl