Coverage Report

Created: 2024-09-08 06:07

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