Flutter Engine
The Flutter Engine
Namespaces | Classes | Enumerations | Functions | Variables
double_conversion Namespace Reference

Namespaces

namespace  PowersOfTenCache
 

Classes

class  Bignum
 
class  DiyFp
 
class  Double
 
class  DoubleToStringConverter
 
class  Single
 
class  StringBuilder
 
class  StringToDoubleConverter
 
class  UInt128
 
class  Vector
 

Enumerations

enum  BignumDtoaMode { BIGNUM_DTOA_SHORTEST , BIGNUM_DTOA_SHORTEST_SINGLE , BIGNUM_DTOA_FIXED , BIGNUM_DTOA_PRECISION }
 
enum  FastDtoaMode { FAST_DTOA_SHORTEST , FAST_DTOA_SHORTEST_SINGLE , FAST_DTOA_PRECISION }
 

Functions

static int NormalizedExponent (uint64_t significand, int exponent)
 
static int EstimatePower (int exponent)
 
static void InitialScaledStartValues (uint64_t significand, int exponent, bool lower_boundary_is_closer, int estimated_power, bool need_boundary_deltas, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
 
static void FixupMultiply10 (int estimated_power, bool is_even, int *decimal_point, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
 
static void GenerateShortestDigits (Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus, bool is_even, Vector< char > buffer, int *length)
 
static void BignumToFixed (int requested_digits, int *decimal_point, Bignum *numerator, Bignum *denominator, Vector< char > buffer, int *length)
 
static void GenerateCountedDigits (int count, int *decimal_point, Bignum *numerator, Bignum *denominator, Vector< char > buffer, int *length)
 
void BignumDtoa (double v, BignumDtoaMode mode, int requested_digits, Vector< char > buffer, int *length, int *decimal_point)
 
static void InitialScaledStartValuesPositiveExponent (uint64_t significand, int exponent, int estimated_power, bool need_boundary_deltas, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
 
static void InitialScaledStartValuesNegativeExponentPositivePower (uint64_t significand, int exponent, int estimated_power, bool need_boundary_deltas, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
 
static void InitialScaledStartValuesNegativeExponentNegativePower (uint64_t significand, int exponent, int estimated_power, bool need_boundary_deltas, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
 
template<typename S >
static int BitSize (const S value)
 
static uint64_t ReadUInt64 (const Vector< const char > buffer, const int from, const int digits_to_read)
 
static uint64_t HexCharValue (const int c)
 
template<typename S >
static int SizeInHexChars (S number)
 
static char HexCharOfValue (const int value)
 
static BignumDtoaMode DtoaToBignumDtoaMode (DoubleToStringConverter::DtoaMode dtoa_mode)
 
static bool RoundWeed (Vector< char > buffer, int length, uint64_t distance_too_high_w, uint64_t unsafe_interval, uint64_t rest, uint64_t ten_kappa, uint64_t unit)
 
static bool RoundWeedCounted (Vector< char > buffer, int length, uint64_t rest, uint64_t ten_kappa, uint64_t unit, int *kappa)
 
static void BiggestPowerTen (uint32_t number, int number_bits, uint32_t *power, int *exponent_plus_one)
 
static bool DigitGen (DiyFp low, DiyFp w, DiyFp high, Vector< char > buffer, int *length, int *kappa)
 
static bool DigitGenCounted (DiyFp w, int requested_digits, Vector< char > buffer, int *length, int *kappa)
 
static bool Grisu3 (double v, FastDtoaMode mode, Vector< char > buffer, int *length, int *decimal_exponent)
 
static bool Grisu3Counted (double v, int requested_digits, Vector< char > buffer, int *length, int *decimal_exponent)
 
bool FastDtoa (double v, FastDtoaMode mode, int requested_digits, Vector< char > buffer, int *length, int *decimal_point)
 
static void FillDigits32FixedLength (uint32_t number, int requested_length, Vector< char > buffer, int *length)
 
static void FillDigits32 (uint32_t number, Vector< char > buffer, int *length)
 
static void FillDigits64FixedLength (uint64_t number, Vector< char > buffer, int *length)
 
static void FillDigits64 (uint64_t number, Vector< char > buffer, int *length)
 
static void RoundUp (Vector< char > buffer, int *length, int *decimal_point)
 
static void FillFractionals (uint64_t fractionals, int exponent, int fractional_count, Vector< char > buffer, int *length, int *decimal_point)
 
static void TrimZeros (Vector< char > buffer, int *length, int *decimal_point)
 
bool FastFixedDtoa (double v, int fractional_count, Vector< char > buffer, int *length, int *decimal_point)
 
static uint64_t double_to_uint64 (double d)
 
static double uint64_to_double (uint64_t d64)
 
static uint32_t float_to_uint32 (float f)
 
static float uint32_to_float (uint32_t d32)
 
static bool isWhitespace (int x)
 
template<class Iterator >
static bool AdvanceToNonspace (Iterator *current, Iterator end)
 
static bool isDigit (int x, int radix)
 
static double SignedZero (bool sign)
 
static bool IsDecimalDigitForRadix (int c, int radix)
 
static bool IsCharacterDigitForRadix (int c, int radix, char a_character)
 
template<class Iterator >
static bool Advance (Iterator *it, uc16 separator, int base, Iterator &end)
 
template<class Iterator >
static bool IsHexFloatString (Iterator start, Iterator end, uc16 separator, bool allow_trailing_junk)
 
template<int radix_log_2, class Iterator >
static double RadixStringToIeee (Iterator *current, Iterator end, bool sign, uc16 separator, bool parse_as_hex_float, bool allow_trailing_junk, double junk_string_value, bool read_as_double, bool *result_is_junk)
 
static Vector< const char > TrimLeadingZeros (Vector< const char > buffer)
 
static void CutToMaxSignificantDigits (Vector< const char > buffer, int exponent, char *significant_buffer, int *significant_exponent)
 
static void TrimAndCut (Vector< const char > buffer, int exponent, char *buffer_copy_space, int space_size, Vector< const char > *trimmed, int *updated_exponent)
 
static uint64_t ReadUint64 (Vector< const char > buffer, int *number_of_read_digits)
 
static void ReadDiyFp (Vector< const char > buffer, DiyFp *result, int *remaining_decimals)
 
static bool DoubleStrtod (Vector< const char > trimmed, int exponent, double *result)
 
static DiyFp AdjustmentPowerOfTen (int exponent)
 
static bool DiyFpStrtod (Vector< const char > buffer, int exponent, double *result)
 
static int CompareBufferWithDiyFp (Vector< const char > buffer, int exponent, DiyFp diy_fp)
 
static bool ComputeGuess (Vector< const char > trimmed, int exponent, double *guess)
 
static bool IsDigit (const char d)
 
static bool IsNonZeroDigit (const char d)
 
static bool AssertTrimmedDigits (const Vector< const char > &buffer)
 
double StrtodTrimmed (Vector< const char > trimmed, int exponent)
 
double Strtod (Vector< const char > buffer, int exponent)
 
static float SanitizedDoubletof (double d)
 
float Strtof (Vector< const char > buffer, int exponent)
 
float StrtofTrimmed (Vector< const char > trimmed, int exponent)
 
Vector< const char > TrimTrailingZeros (Vector< const char > buffer)
 
int StrLength (const char *string)
 
template<class Dest , class Source >
Dest BitCast (const Source &source)
 
template<class Dest , class Source >
Dest BitCast (Source *source)
 

Variables

static const int kMinimalTargetExponent = -60
 
static const int kMaximalTargetExponent = -32
 
static unsigned int const kSmallPowersOfTen []
 
static const int kFastDtoaMaximalLength = 17
 
static const int kFastDtoaMaximalSingleLength = 9
 
static const int kDoubleSignificandSize = 53
 
const int kMaxSignificantDigits = 772
 
static const char kWhitespaceTable7 [] = { 32, 13, 10, 9, 11, 12 }
 
static const int kWhitespaceTable7Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable7)
 
static const uc16 kWhitespaceTable16 []
 
static const int kWhitespaceTable16Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable16)
 
static const int kMaxUint64DecimalDigits = 19
 
static const int kMaxDecimalPower = 309
 
static const int kMinDecimalPower = -324
 
static const uint64_t kMaxUint64 = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF)
 
static const int kMaxSignificantDecimalDigits = 780
 

Enumeration Type Documentation

◆ BignumDtoaMode

Enumerator
BIGNUM_DTOA_SHORTEST 
BIGNUM_DTOA_SHORTEST_SINGLE 
BIGNUM_DTOA_FIXED 
BIGNUM_DTOA_PRECISION 

Definition at line 35 of file bignum-dtoa.h.

35 {
36 // Return the shortest correct representation.
37 // For example the output of 0.299999999999999988897 is (the less accurate but
38 // correct) 0.3.
40 // Same as BIGNUM_DTOA_SHORTEST but for single-precision floats.
42 // Return a fixed number of digits after the decimal point.
43 // For instance fixed(0.1, 4) becomes 0.1000
44 // If the input number is big, the output will be big.
46 // Return a fixed number of digits, no matter what the exponent is.
48};

◆ FastDtoaMode

Enumerator
FAST_DTOA_SHORTEST 
FAST_DTOA_SHORTEST_SINGLE 
FAST_DTOA_PRECISION 

Definition at line 35 of file fast-dtoa.h.

35 {
36 // Computes the shortest representation of the given input. The returned
37 // result will be the most accurate number of this length. Longer
38 // representations might be more accurate.
40 // Same as FAST_DTOA_SHORTEST but for single-precision floats.
42 // Computes a representation where the precision (number of digits) is
43 // given as input. The precision is independent of the decimal point.
45};
@ FAST_DTOA_SHORTEST_SINGLE
Definition: fast-dtoa.h:41

Function Documentation

◆ AdjustmentPowerOfTen()

static DiyFp double_conversion::AdjustmentPowerOfTen ( int  exponent)
static

Definition at line 247 of file strtod.cc.

247 {
248 DOUBLE_CONVERSION_ASSERT(0 < exponent);
250 // Simply hardcode the remaining powers for the given decimal exponent
251 // distance.
253 switch (exponent) {
254 case 1: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xa0000000, 00000000), -60);
255 case 2: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xc8000000, 00000000), -57);
256 case 3: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xfa000000, 00000000), -54);
257 case 4: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x9c400000, 00000000), -50);
258 case 5: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xc3500000, 00000000), -47);
259 case 6: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xf4240000, 00000000), -44);
260 case 7: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x98968000, 00000000), -40);
261 default:
263 }
264}
static const int kDecimalExponentDistance
Definition: cached-powers.h:39
#define DOUBLE_CONVERSION_ASSERT(condition)
Definition: utils.h:46
#define DOUBLE_CONVERSION_UINT64_2PART_C(a, b)
Definition: utils.h:195
#define DOUBLE_CONVERSION_UNREACHABLE()
Definition: utils.h:77

◆ Advance()

template<class Iterator >
static bool double_conversion::Advance ( Iterator *  it,
uc16  separator,
int  base,
Iterator &  end 
)
static

Definition at line 190 of file string-to-double.cc.

190 {
191 if (separator == StringToDoubleConverter::kNoSeparator) {
192 ++(*it);
193 return *it == end;
194 }
195 if (!isDigit(**it, base)) {
196 ++(*it);
197 return *it == end;
198 }
199 ++(*it);
200 if (*it == end) return true;
201 if (*it + 1 == end) return false;
202 if (**it == separator && isDigit(*(*it + 1), base)) {
203 ++(*it);
204 }
205 return *it == end;
206}
glong glong end
static bool isDigit(int x, int radix)

◆ AdvanceToNonspace()

template<class Iterator >
static bool double_conversion::AdvanceToNonspace ( Iterator *  current,
Iterator  end 
)
inlinestatic

Definition at line 139 of file string-to-double.cc.

139 {
140 while (*current != end) {
141 if (!isWhitespace(**current)) return true;
142 ++*current;
143 }
144 return false;
145}
static bool isWhitespace(int x)

◆ AssertTrimmedDigits()

static bool double_conversion::AssertTrimmedDigits ( const Vector< const char > &  buffer)
static

Definition at line 457 of file strtod.cc.

457 {
458 for(int i = 0; i < buffer.length(); ++i) {
459 if(!IsDigit(buffer[i])) {
460 return false;
461 }
462 }
463 return (buffer.length() == 0) || (IsNonZeroDigit(buffer[0]) && IsNonZeroDigit(buffer[buffer.length()-1]));
464}
static bool IsDigit(const char d)
Definition: strtod.cc:444
static bool IsNonZeroDigit(const char d)
Definition: strtod.cc:448
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126

◆ BiggestPowerTen()

static void double_conversion::BiggestPowerTen ( uint32_t  number,
int  number_bits,
uint32_t *  power,
int exponent_plus_one 
)
static

Definition at line 240 of file fast-dtoa.cc.

243 {
244 DOUBLE_CONVERSION_ASSERT(number < (1u << (number_bits + 1)));
245 // 1233/4096 is approximately 1/lg(10).
246 int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12);
247 // We increment to skip over the first entry in the kPowersOf10 table.
248 // Note: kPowersOf10[i] == 10^(i-1).
249 exponent_plus_one_guess++;
250 // We don't have any guarantees that 2^number_bits <= number.
251 if (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
252 exponent_plus_one_guess--;
253 }
254 *power = kSmallPowersOfTen[exponent_plus_one_guess];
255 *exponent_plus_one = exponent_plus_one_guess;
256}
static unsigned int const kSmallPowersOfTen[]
Definition: fast-dtoa.cc:236

◆ BignumDtoa()

void double_conversion::BignumDtoa ( double  v,
BignumDtoaMode  mode,
int  requested_digits,
Vector< char >  buffer,
int length,
int decimal_point 
)

Definition at line 89 of file bignum-dtoa.cc.

90 {
92 DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial());
93 uint64_t significand;
94 int exponent;
95 bool lower_boundary_is_closer;
97 float f = static_cast<float>(v);
99 significand = Single(f).Significand();
100 exponent = Single(f).Exponent();
101 lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser();
102 } else {
103 significand = Double(v).Significand();
104 exponent = Double(v).Exponent();
105 lower_boundary_is_closer = Double(v).LowerBoundaryIsCloser();
106 }
107 bool need_boundary_deltas =
109
110 bool is_even = (significand & 1) == 0;
111 int normalized_exponent = NormalizedExponent(significand, exponent);
112 // estimated_power might be too low by 1.
113 int estimated_power = EstimatePower(normalized_exponent);
114
115 // Shortcut for Fixed.
116 // The requested digits correspond to the digits after the point. If the
117 // number is much too small, then there is no need in trying to get any
118 // digits.
119 if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) {
120 buffer[0] = '\0';
121 *length = 0;
122 // Set decimal-point to -requested_digits. This is what Gay does.
123 // Note that it should not have any effect anyways since the string is
124 // empty.
125 *decimal_point = -requested_digits;
126 return;
127 }
128
129 Bignum numerator;
130 Bignum denominator;
131 Bignum delta_minus;
132 Bignum delta_plus;
133 // Make sure the bignum can grow large enough. The smallest double equals
134 // 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
135 // The maximum double is 1.7976931348623157e308 which needs fewer than
136 // 308*4 binary digits.
137 DOUBLE_CONVERSION_ASSERT(Bignum::kMaxSignificantBits >= 324*4);
138 InitialScaledStartValues(significand, exponent, lower_boundary_is_closer,
139 estimated_power, need_boundary_deltas,
140 &numerator, &denominator,
141 &delta_minus, &delta_plus);
142 // We now have v = (numerator / denominator) * 10^estimated_power.
143 FixupMultiply10(estimated_power, is_even, decimal_point,
144 &numerator, &denominator,
145 &delta_minus, &delta_plus);
146 // We now have v = (numerator / denominator) * 10^(decimal_point-1), and
147 // 1 <= (numerator + delta_plus) / denominator < 10
148 switch (mode) {
151 GenerateShortestDigits(&numerator, &denominator,
152 &delta_minus, &delta_plus,
154 break;
156 BignumToFixed(requested_digits, decimal_point,
157 &numerator, &denominator,
158 buffer, length);
159 break;
161 GenerateCountedDigits(requested_digits, decimal_point,
162 &numerator, &denominator,
163 buffer, length);
164 break;
165 default:
167 }
168 buffer[*length] = '\0';
169}
static int is_even(int x)
Definition: SkDashPath.cpp:31
int Exponent() const
Definition: ieee.h:313
uint32_t Significand() const
Definition: ieee.h:322
bool LowerBoundaryIsCloser() const
Definition: ieee.h:406
size_t length
static int EstimatePower(int exponent)
Definition: bignum-dtoa.cc:385
static void GenerateShortestDigits(Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus, bool is_even, Vector< char > buffer, int *length)
Definition: bignum-dtoa.cc:185
static void BignumToFixed(int requested_digits, int *decimal_point, Bignum *numerator, Bignum *denominator, Vector< char > buffer, int *length)
Definition: bignum-dtoa.cc:326
static void InitialScaledStartValues(uint64_t significand, int exponent, bool lower_boundary_is_closer, int estimated_power, bool need_boundary_deltas, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
Definition: bignum-dtoa.cc:568
static void FixupMultiply10(int estimated_power, bool is_even, int *decimal_point, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
Definition: bignum-dtoa.cc:612
static int NormalizedExponent(uint64_t significand, int exponent)
Definition: bignum-dtoa.cc:37
static void GenerateCountedDigits(int count, int *decimal_point, Bignum *numerator, Bignum *denominator, Vector< char > buffer, int *length)
Definition: bignum-dtoa.cc:283
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228

◆ BignumToFixed()

static void double_conversion::BignumToFixed ( int  requested_digits,
int decimal_point,
Bignum numerator,
Bignum denominator,
Vector< char >  buffer,
int length 
)
static

Definition at line 326 of file bignum-dtoa.cc.

328 {
329 // Note that we have to look at more than just the requested_digits, since
330 // a number could be rounded up. Example: v=0.5 with requested_digits=0.
331 // Even though the power of v equals 0 we can't just stop here.
332 if (-(*decimal_point) > requested_digits) {
333 // The number is definitively too small.
334 // Ex: 0.001 with requested_digits == 1.
335 // Set decimal-point to -requested_digits. This is what Gay does.
336 // Note that it should not have any effect anyways since the string is
337 // empty.
338 *decimal_point = -requested_digits;
339 *length = 0;
340 return;
341 } else if (-(*decimal_point) == requested_digits) {
342 // We only need to verify if the number rounds down or up.
343 // Ex: 0.04 and 0.06 with requested_digits == 1.
344 DOUBLE_CONVERSION_ASSERT(*decimal_point == -requested_digits);
345 // Initially the fraction lies in range (1, 10]. Multiply the denominator
346 // by 10 so that we can compare more easily.
347 denominator->Times10();
348 if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
349 // If the fraction is >= 0.5 then we have to include the rounded
350 // digit.
351 buffer[0] = '1';
352 *length = 1;
353 (*decimal_point)++;
354 } else {
355 // Note that we caught most of similar cases earlier.
356 *length = 0;
357 }
358 return;
359 } else {
360 // The requested digits correspond to the digits after the point.
361 // The variable 'needed_digits' includes the digits before the point.
362 int needed_digits = (*decimal_point) + requested_digits;
363 GenerateCountedDigits(needed_digits, decimal_point,
364 numerator, denominator,
365 buffer, length);
366 }
367}

◆ BitCast() [1/2]

template<class Dest , class Source >
Dest double_conversion::BitCast ( const Source &  source)

Definition at line 395 of file utils.h.

395 {
396 // Compile time assertion: sizeof(Dest) == sizeof(Source)
397 // A compile error here means your Dest and Source have different sizes.
398#if __cplusplus >= 201103L
399 static_assert(sizeof(Dest) == sizeof(Source),
400 "source and destination size mismatch");
401#else
403 typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
404#endif
405
406 Dest dest;
407 memmove(&dest, &source, sizeof(dest));
408 return dest;
409}
SkBitmap source
Definition: examples.cpp:28
dest
Definition: zip.py:79
#define DOUBLE_CONVERSION_UNUSED
Definition: utils.h:96

◆ BitCast() [2/2]

template<class Dest , class Source >
Dest double_conversion::BitCast ( Source *  source)

Definition at line 412 of file utils.h.

412 {
413 return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
414}

◆ BitSize()

template<typename S >
static int double_conversion::BitSize ( const S  value)
static

Definition at line 49 of file bignum.cc.

49 {
50 (void) value; // Mark variable as used.
51 return 8 * sizeof(value);
52}
uint8_t value

◆ CompareBufferWithDiyFp()

static int double_conversion::CompareBufferWithDiyFp ( Vector< const char >  buffer,
int  exponent,
DiyFp  diy_fp 
)
static

Definition at line 388 of file strtod.cc.

390 {
391 DOUBLE_CONVERSION_ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
392 DOUBLE_CONVERSION_ASSERT(buffer.length() + exponent > kMinDecimalPower);
394 // Make sure that the Bignum will be able to hold all our numbers.
395 // Our Bignum implementation has a separate field for exponents. Shifts will
396 // consume at most one bigit (< 64 bits).
397 // ln(10) == 3.3219...
398 DOUBLE_CONVERSION_ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
399 Bignum buffer_bignum;
400 Bignum diy_fp_bignum;
401 buffer_bignum.AssignDecimalString(buffer);
402 diy_fp_bignum.AssignUInt64(diy_fp.f());
403 if (exponent >= 0) {
404 buffer_bignum.MultiplyByPowerOfTen(exponent);
405 } else {
406 diy_fp_bignum.MultiplyByPowerOfTen(-exponent);
407 }
408 if (diy_fp.e() > 0) {
409 diy_fp_bignum.ShiftLeft(diy_fp.e());
410 } else {
411 buffer_bignum.ShiftLeft(-diy_fp.e());
412 }
413 return Bignum::Compare(buffer_bignum, diy_fp_bignum);
414}
void ShiftLeft(const int shift_amount)
Definition: bignum.cc:239
void AssignDecimalString(const Vector< const char > value)
Definition: bignum.cc:97
void MultiplyByPowerOfTen(const int exponent)
Definition: bignum.cc:311
void AssignUInt64(uint64_t value)
Definition: bignum.cc:65
int32_t e() const
Definition: diy-fp.h:123
uint64_t f() const
Definition: diy-fp.h:122
static const int kMinDecimalPower
Definition: strtod.cc:54
static const int kMaxSignificantDecimalDigits
Definition: strtod.cc:93
static const int kMaxDecimalPower
Definition: strtod.cc:53

◆ ComputeGuess()

static bool double_conversion::ComputeGuess ( Vector< const char >  trimmed,
int  exponent,
double *  guess 
)
static

Definition at line 419 of file strtod.cc.

420 {
421 if (trimmed.length() == 0) {
422 *guess = 0.0;
423 return true;
424 }
425 if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) {
426 *guess = Double::Infinity();
427 return true;
428 }
429 if (exponent + trimmed.length() <= kMinDecimalPower) {
430 *guess = 0.0;
431 return true;
432 }
433
434 if (DoubleStrtod(trimmed, exponent, guess) ||
435 DiyFpStrtod(trimmed, exponent, guess)) {
436 return true;
437 }
438 if (*guess == Double::Infinity()) {
439 return true;
440 }
441 return false;
442}
int length() const
Definition: utils.h:266
static bool DiyFpStrtod(Vector< const char > buffer, int exponent, double *result)
Definition: strtod.cc:270
static bool DoubleStrtod(Vector< const char > trimmed, int exponent, double *result)
Definition: strtod.cc:190

◆ CutToMaxSignificantDigits()

static void double_conversion::CutToMaxSignificantDigits ( Vector< const char >  buffer,
int  exponent,
char *  significant_buffer,
int significant_exponent 
)
static

Definition at line 104 of file strtod.cc.

107 {
108 for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) {
109 significant_buffer[i] = buffer[i];
110 }
111 // The input buffer has been trimmed. Therefore the last digit must be
112 // different from '0'.
113 DOUBLE_CONVERSION_ASSERT(buffer[buffer.length() - 1] != '0');
114 // Set the last digit to be non-zero. This is sufficient to guarantee
115 // correct rounding.
116 significant_buffer[kMaxSignificantDecimalDigits - 1] = '1';
117 *significant_exponent =
118 exponent + (buffer.length() - kMaxSignificantDecimalDigits);
119}

◆ DigitGen()

static bool double_conversion::DigitGen ( DiyFp  low,
DiyFp  w,
DiyFp  high,
Vector< char >  buffer,
int length,
int kappa 
)
static

Definition at line 300 of file fast-dtoa.cc.

305 {
306 DOUBLE_CONVERSION_ASSERT(low.e() == w.e() && w.e() == high.e());
307 DOUBLE_CONVERSION_ASSERT(low.f() + 1 <= high.f() - 1);
309 // low, w and high are imprecise, but by less than one ulp (unit in the last
310 // place).
311 // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that
312 // the new numbers are outside of the interval we want the final
313 // representation to lie in.
314 // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield
315 // numbers that are certain to lie in the interval. We will use this fact
316 // later on.
317 // We will now start by generating the digits within the uncertain
318 // interval. Later we will weed out representations that lie outside the safe
319 // interval and thus _might_ lie outside the correct interval.
320 uint64_t unit = 1;
321 DiyFp too_low = DiyFp(low.f() - unit, low.e());
322 DiyFp too_high = DiyFp(high.f() + unit, high.e());
323 // too_low and too_high are guaranteed to lie outside the interval we want the
324 // generated number in.
325 DiyFp unsafe_interval = DiyFp::Minus(too_high, too_low);
326 // We now cut the input number into two parts: the integral digits and the
327 // fractionals. We will not write any decimal separator though, but adapt
328 // kappa instead.
329 // Reminder: we are currently computing the digits (stored inside the buffer)
330 // such that: too_low < buffer * 10^kappa < too_high
331 // We use too_high for the digit_generation and stop as soon as possible.
332 // If we stop early we effectively round down.
333 DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
334 // Division by one is a shift.
335 uint32_t integrals = static_cast<uint32_t>(too_high.f() >> -one.e());
336 // Modulo by one is an and.
337 uint64_t fractionals = too_high.f() & (one.f() - 1);
338 uint32_t divisor;
339 int divisor_exponent_plus_one;
340 BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
341 &divisor, &divisor_exponent_plus_one);
342 *kappa = divisor_exponent_plus_one;
343 *length = 0;
344 // Loop invariant: buffer = too_high / 10^kappa (integer division)
345 // The invariant holds for the first iteration: kappa has been initialized
346 // with the divisor exponent + 1. And the divisor is the biggest power of ten
347 // that is smaller than integrals.
348 while (*kappa > 0) {
349 int digit = integrals / divisor;
350 DOUBLE_CONVERSION_ASSERT(digit <= 9);
351 buffer[*length] = static_cast<char>('0' + digit);
352 (*length)++;
353 integrals %= divisor;
354 (*kappa)--;
355 // Note that kappa now equals the exponent of the divisor and that the
356 // invariant thus holds again.
357 uint64_t rest =
358 (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
359 // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e())
360 // Reminder: unsafe_interval.e() == one.e()
361 if (rest < unsafe_interval.f()) {
362 // Rounding down (by not emitting the remaining digits) yields a number
363 // that lies within the unsafe interval.
364 return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f(),
365 unsafe_interval.f(), rest,
366 static_cast<uint64_t>(divisor) << -one.e(), unit);
367 }
368 divisor /= 10;
369 }
370
371 // The integrals have been generated. We are at the point of the decimal
372 // separator. In the following loop we simply multiply the remaining digits by
373 // 10 and divide by one. We just need to pay attention to multiply associated
374 // data (like the interval or 'unit'), too.
375 // Note that the multiplication by 10 does not overflow, because w.e >= -60
376 // and thus one.e >= -60.
377 DOUBLE_CONVERSION_ASSERT(one.e() >= -60);
378 DOUBLE_CONVERSION_ASSERT(fractionals < one.f());
379 DOUBLE_CONVERSION_ASSERT(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
380 for (;;) {
381 fractionals *= 10;
382 unit *= 10;
383 unsafe_interval.set_f(unsafe_interval.f() * 10);
384 // Integer division by one.
385 int digit = static_cast<int>(fractionals >> -one.e());
386 DOUBLE_CONVERSION_ASSERT(digit <= 9);
387 buffer[*length] = static_cast<char>('0' + digit);
388 (*length)++;
389 fractionals &= one.f() - 1; // Modulo by one.
390 (*kappa)--;
391 if (fractionals < unsafe_interval.f()) {
392 return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f() * unit,
393 unsafe_interval.f(), fractionals, one.f(), unit);
394 }
395 }
396}
void set_f(uint64_t new_value)
Definition: diy-fp.h:125
static const int kMinimalTargetExponent
Definition: fast-dtoa.cc:42
static bool RoundWeed(Vector< char > buffer, int length, uint64_t distance_too_high_w, uint64_t unsafe_interval, uint64_t rest, uint64_t ten_kappa, uint64_t unit)
Definition: fast-dtoa.cc:61
static void BiggestPowerTen(uint32_t number, int number_bits, uint32_t *power, int *exponent_plus_one)
Definition: fast-dtoa.cc:240
static const int kMaximalTargetExponent
Definition: fast-dtoa.cc:43
SkScalar w

◆ DigitGenCounted()

static bool double_conversion::DigitGenCounted ( DiyFp  w,
int  requested_digits,
Vector< char >  buffer,
int length,
int kappa 
)
static

Definition at line 428 of file fast-dtoa.cc.

432 {
436 // w is assumed to have an error less than 1 unit. Whenever w is scaled we
437 // also scale its error.
438 uint64_t w_error = 1;
439 // We cut the input number into two parts: the integral digits and the
440 // fractional digits. We don't emit any decimal separator, but adapt kappa
441 // instead. Example: instead of writing "1.2" we put "12" into the buffer and
442 // increase kappa by 1.
443 DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
444 // Division by one is a shift.
445 uint32_t integrals = static_cast<uint32_t>(w.f() >> -one.e());
446 // Modulo by one is an and.
447 uint64_t fractionals = w.f() & (one.f() - 1);
448 uint32_t divisor;
449 int divisor_exponent_plus_one;
450 BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
451 &divisor, &divisor_exponent_plus_one);
452 *kappa = divisor_exponent_plus_one;
453 *length = 0;
454
455 // Loop invariant: buffer = w / 10^kappa (integer division)
456 // The invariant holds for the first iteration: kappa has been initialized
457 // with the divisor exponent + 1. And the divisor is the biggest power of ten
458 // that is smaller than 'integrals'.
459 while (*kappa > 0) {
460 int digit = integrals / divisor;
461 DOUBLE_CONVERSION_ASSERT(digit <= 9);
462 buffer[*length] = static_cast<char>('0' + digit);
463 (*length)++;
464 requested_digits--;
465 integrals %= divisor;
466 (*kappa)--;
467 // Note that kappa now equals the exponent of the divisor and that the
468 // invariant thus holds again.
469 if (requested_digits == 0) break;
470 divisor /= 10;
471 }
472
473 if (requested_digits == 0) {
474 uint64_t rest =
475 (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
476 return RoundWeedCounted(buffer, *length, rest,
477 static_cast<uint64_t>(divisor) << -one.e(), w_error,
478 kappa);
479 }
480
481 // The integrals have been generated. We are at the point of the decimal
482 // separator. In the following loop we simply multiply the remaining digits by
483 // 10 and divide by one. We just need to pay attention to multiply associated
484 // data (the 'unit'), too.
485 // Note that the multiplication by 10 does not overflow, because w.e >= -60
486 // and thus one.e >= -60.
487 DOUBLE_CONVERSION_ASSERT(one.e() >= -60);
488 DOUBLE_CONVERSION_ASSERT(fractionals < one.f());
489 DOUBLE_CONVERSION_ASSERT(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
490 while (requested_digits > 0 && fractionals > w_error) {
491 fractionals *= 10;
492 w_error *= 10;
493 // Integer division by one.
494 int digit = static_cast<int>(fractionals >> -one.e());
495 DOUBLE_CONVERSION_ASSERT(digit <= 9);
496 buffer[*length] = static_cast<char>('0' + digit);
497 (*length)++;
498 requested_digits--;
499 fractionals &= one.f() - 1; // Modulo by one.
500 (*kappa)--;
501 }
502 if (requested_digits != 0) return false;
503 return RoundWeedCounted(buffer, *length, fractionals, one.f(), w_error,
504 kappa);
505}
static bool RoundWeedCounted(Vector< char > buffer, int length, uint64_t rest, uint64_t ten_kappa, uint64_t unit, int *kappa)
Definition: fast-dtoa.cc:181

◆ DiyFpStrtod()

static bool double_conversion::DiyFpStrtod ( Vector< const char >  buffer,
int  exponent,
double *  result 
)
static

Definition at line 270 of file strtod.cc.

272 {
273 DiyFp input;
274 int remaining_decimals;
275 ReadDiyFp(buffer, &input, &remaining_decimals);
276 // Since we may have dropped some digits the input is not accurate.
277 // If remaining_decimals is different than 0 than the error is at most
278 // .5 ulp (unit in the last place).
279 // We don't want to deal with fractions and therefore keep a common
280 // denominator.
281 const int kDenominatorLog = 3;
282 const int kDenominator = 1 << kDenominatorLog;
283 // Move the remaining decimals into the exponent.
284 exponent += remaining_decimals;
285 uint64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
286
287 int old_e = input.e();
288 input.Normalize();
289 error <<= old_e - input.e();
290
293 *result = 0.0;
294 return true;
295 }
296 DiyFp cached_power;
297 int cached_decimal_exponent;
299 &cached_power,
300 &cached_decimal_exponent);
301
302 if (cached_decimal_exponent != exponent) {
303 int adjustment_exponent = exponent - cached_decimal_exponent;
304 DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent);
305 input.Multiply(adjustment_power);
306 if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
307 // The product of input with the adjustment power fits into a 64 bit
308 // integer.
309 DOUBLE_CONVERSION_ASSERT(DiyFp::kSignificandSize == 64);
310 } else {
311 // The adjustment power is exact. There is hence only an error of 0.5.
312 error += kDenominator / 2;
313 }
314 }
315
316 input.Multiply(cached_power);
317 // The error introduced by a multiplication of a*b equals
318 // error_a + error_b + error_a*error_b/2^64 + 0.5
319 // Substituting a with 'input' and b with 'cached_power' we have
320 // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp),
321 // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64
322 int error_b = kDenominator / 2;
323 int error_ab = (error == 0 ? 0 : 1); // We round up to 1.
324 int fixed_error = kDenominator / 2;
325 error += error_b + error_ab + fixed_error;
326
327 old_e = input.e();
328 input.Normalize();
329 error <<= old_e - input.e();
330
331 // See if the double's significand changes if we add/subtract the error.
332 int order_of_magnitude = DiyFp::kSignificandSize + input.e();
333 int effective_significand_size =
334 Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude);
335 int precision_digits_count =
336 DiyFp::kSignificandSize - effective_significand_size;
337 if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) {
338 // This can only happen for very small denormals. In this case the
339 // half-way multiplied by the denominator exceeds the range of an uint64.
340 // Simply shift everything to the right.
341 int shift_amount = (precision_digits_count + kDenominatorLog) -
342 DiyFp::kSignificandSize + 1;
343 input.set_f(input.f() >> shift_amount);
344 input.set_e(input.e() + shift_amount);
345 // We add 1 for the lost precision of error, and kDenominator for
346 // the lost precision of input.f().
347 error = (error >> shift_amount) + 1 + kDenominator;
348 precision_digits_count -= shift_amount;
349 }
350 // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too.
351 DOUBLE_CONVERSION_ASSERT(DiyFp::kSignificandSize == 64);
352 DOUBLE_CONVERSION_ASSERT(precision_digits_count < 64);
353 uint64_t one64 = 1;
354 uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
355 uint64_t precision_bits = input.f() & precision_bits_mask;
356 uint64_t half_way = one64 << (precision_digits_count - 1);
357 precision_bits *= kDenominator;
358 half_way *= kDenominator;
359 DiyFp rounded_input(input.f() >> precision_digits_count,
360 input.e() + precision_digits_count);
361 if (precision_bits >= half_way + error) {
362 rounded_input.set_f(rounded_input.f() + 1);
363 }
364 // If the last_bits are too close to the half-way case than we are too
365 // inaccurate and round down. In this case we return false so that we can
366 // fall back to a more precise algorithm.
367
368 *result = Double(rounded_input).value();
369 if (half_way - error < precision_bits && precision_bits < half_way + error) {
370 // Too imprecise. The caller will have to fall back to a slower version.
371 // However the returned number is guaranteed to be either the correct
372 // double, or the next-lower double.
373 return false;
374 } else {
375 return true;
376 }
377}
void Multiply(const DiyFp &other)
Definition: diy-fp.h:68
void set_e(int32_t new_value)
Definition: diy-fp.h:126
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
void GetCachedPowerForDecimalExponent(int requested_exponent, DiyFp *power, int *found_exponent)
static DiyFp AdjustmentPowerOfTen(int exponent)
Definition: strtod.cc:247
static const int kMaxUint64DecimalDigits
Definition: strtod.cc:45
static void ReadDiyFp(Vector< const char > buffer, DiyFp *result, int *remaining_decimals)
Definition: strtod.cc:169

◆ double_to_uint64()

static uint64_t double_conversion::double_to_uint64 ( double  d)
static

Definition at line 36 of file ieee.h.

36{ return BitCast<uint64_t>(d); }
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19

◆ DoubleStrtod()

static bool double_conversion::DoubleStrtod ( Vector< const char >  trimmed,
int  exponent,
double *  result 
)
static

Definition at line 190 of file strtod.cc.

192 {
193#if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS)
194 // Avoid "unused parameter" warnings
195 (void) trimmed;
196 (void) exponent;
197 (void) result;
198 // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
199 // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
200 // result is not accurate.
201 // We know that Windows32 uses 64 bits and is therefore accurate.
202 return false;
203#else
204 if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
205 int read_digits;
206 // The trimmed input fits into a double.
207 // If the 10^exponent (resp. 10^-exponent) fits into a double too then we
208 // can compute the result-double simply by multiplying (resp. dividing) the
209 // two numbers.
210 // This is possible because IEEE guarantees that floating-point operations
211 // return the best possible approximation.
212 if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
213 // 10^-exponent fits into a double.
214 *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
215 DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length());
216 *result /= exact_powers_of_ten[-exponent];
217 return true;
218 }
219 if (0 <= exponent && exponent < kExactPowersOfTenSize) {
220 // 10^exponent fits into a double.
221 *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
222 DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length());
223 *result *= exact_powers_of_ten[exponent];
224 return true;
225 }
226 int remaining_digits =
227 kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
228 if ((0 <= exponent) &&
229 (exponent - remaining_digits < kExactPowersOfTenSize)) {
230 // The trimmed string was short and we can multiply it with
231 // 10^remaining_digits. As a result the remaining exponent now fits
232 // into a double too.
233 *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
234 DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length());
235 *result *= exact_powers_of_ten[remaining_digits];
236 *result *= exact_powers_of_ten[exponent - remaining_digits];
237 return true;
238 }
239 }
240 return false;
241#endif
242}
static uint64_t ReadUint64(Vector< const char > buffer, int *number_of_read_digits)
Definition: strtod.cc:151

◆ DtoaToBignumDtoaMode()

static BignumDtoaMode double_conversion::DtoaToBignumDtoaMode ( DoubleToStringConverter::DtoaMode  dtoa_mode)
static

Definition at line 372 of file double-to-string.cc.

373 {
374 switch (dtoa_mode) {
375 case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
376 case DoubleToStringConverter::SHORTEST_SINGLE:
378 case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
379 case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
380 default:
382 }
383}

◆ EstimatePower()

static int double_conversion::EstimatePower ( int  exponent)
static

Definition at line 385 of file bignum-dtoa.cc.

385 {
386 // This function estimates log10 of v where v = f*2^e (with e == exponent).
387 // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)).
388 // Note that f is bounded by its container size. Let p = 53 (the double's
389 // significand size). Then 2^(p-1) <= f < 2^p.
390 //
391 // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close
392 // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)).
393 // The computed number undershoots by less than 0.631 (when we compute log3
394 // and not log10).
395 //
396 // Optimization: since we only need an approximated result this computation
397 // can be performed on 64 bit integers. On x86/x64 architecture the speedup is
398 // not really measurable, though.
399 //
400 // Since we want to avoid overshooting we decrement by 1e10 so that
401 // floating-point imprecisions don't affect us.
402 //
403 // Explanation for v's boundary m+: the computation takes advantage of
404 // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement
405 // (even for denormals where the delta can be much more important).
406
407 const double k1Log10 = 0.30102999566398114; // 1/lg(10)
408
409 // For doubles len(f) == 53 (don't forget the hidden bit).
410 const int kSignificandSize = Double::kSignificandSize;
411 double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
412 return static_cast<int>(estimate);
413}
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition: SkVx.h:702

◆ FastDtoa()

bool double_conversion::FastDtoa ( double  v,
FastDtoaMode  mode,
int  requested_digits,
Vector< char >  buffer,
int length,
int decimal_point 
)

Definition at line 635 of file fast-dtoa.cc.

640 {
642 DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial());
643
644 bool result = false;
645 int decimal_exponent = 0;
646 switch (mode) {
649 result = Grisu3(v, mode, buffer, length, &decimal_exponent);
650 break;
652 result = Grisu3Counted(v, requested_digits,
653 buffer, length, &decimal_exponent);
654 break;
655 default:
657 }
658 if (result) {
659 *decimal_point = *length + decimal_exponent;
660 buffer[*length] = '\0';
661 }
662 return result;
663}
static bool Grisu3Counted(double v, int requested_digits, Vector< char > buffer, int *length, int *decimal_exponent)
Definition: fast-dtoa.cc:591
static bool Grisu3(double v, FastDtoaMode mode, Vector< char > buffer, int *length, int *decimal_exponent)
Definition: fast-dtoa.cc:519

◆ FastFixedDtoa()

bool double_conversion::FastFixedDtoa ( double  v,
int  fractional_count,
Vector< char >  buffer,
int length,
int decimal_point 
)

Definition at line 310 of file fixed-dtoa.cc.

314 {
315 const uint32_t kMaxUInt32 = 0xFFFFFFFF;
316 uint64_t significand = Double(v).Significand();
317 int exponent = Double(v).Exponent();
318 // v = significand * 2^exponent (with significand a 53bit integer).
319 // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we
320 // don't know how to compute the representation. 2^73 ~= 9.5*10^21.
321 // If necessary this limit could probably be increased, but we don't need
322 // more.
323 if (exponent > 20) return false;
324 if (fractional_count > 20) return false;
325 *length = 0;
326 // At most kDoubleSignificandSize bits of the significand are non-zero.
327 // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero
328 // bits: 0..11*..0xxx..53*..xx
329 if (exponent + kDoubleSignificandSize > 64) {
330 // The exponent must be > 11.
331 //
332 // We know that v = significand * 2^exponent.
333 // And the exponent > 11.
334 // We simplify the task by dividing v by 10^17.
335 // The quotient delivers the first digits, and the remainder fits into a 64
336 // bit number.
337 // Dividing by 10^17 is equivalent to dividing by 5^17*2^17.
338 const uint64_t kFive17 = DOUBLE_CONVERSION_UINT64_2PART_C(0xB1, A2BC2EC5); // 5^17
339 uint64_t divisor = kFive17;
340 int divisor_power = 17;
341 uint64_t dividend = significand;
342 uint32_t quotient;
343 uint64_t remainder;
344 // Let v = f * 2^e with f == significand and e == exponent.
345 // Then need q (quotient) and r (remainder) as follows:
346 // v = q * 10^17 + r
347 // f * 2^e = q * 10^17 + r
348 // f * 2^e = q * 5^17 * 2^17 + r
349 // If e > 17 then
350 // f * 2^(e-17) = q * 5^17 + r/2^17
351 // else
352 // f = q * 5^17 * 2^(17-e) + r/2^e
353 if (exponent > divisor_power) {
354 // We only allow exponents of up to 20 and therefore (17 - e) <= 3
355 dividend <<= exponent - divisor_power;
356 quotient = static_cast<uint32_t>(dividend / divisor);
357 remainder = (dividend % divisor) << divisor_power;
358 } else {
359 divisor <<= divisor_power - exponent;
360 quotient = static_cast<uint32_t>(dividend / divisor);
361 remainder = (dividend % divisor) << exponent;
362 }
363 FillDigits32(quotient, buffer, length);
365 *decimal_point = *length;
366 } else if (exponent >= 0) {
367 // 0 <= exponent <= 11
368 significand <<= exponent;
369 FillDigits64(significand, buffer, length);
370 *decimal_point = *length;
371 } else if (exponent > -kDoubleSignificandSize) {
372 // We have to cut the number.
373 uint64_t integrals = significand >> -exponent;
374 uint64_t fractionals = significand - (integrals << -exponent);
375 if (integrals > kMaxUInt32) {
376 FillDigits64(integrals, buffer, length);
377 } else {
378 FillDigits32(static_cast<uint32_t>(integrals), buffer, length);
379 }
380 *decimal_point = *length;
381 FillFractionals(fractionals, exponent, fractional_count,
382 buffer, length, decimal_point);
383 } else if (exponent < -128) {
384 // This configuration (with at most 20 digits) means that all digits must be
385 // 0.
386 DOUBLE_CONVERSION_ASSERT(fractional_count <= 20);
387 buffer[0] = '\0';
388 *length = 0;
389 *decimal_point = -fractional_count;
390 } else {
391 *decimal_point = 0;
392 FillFractionals(significand, exponent, fractional_count,
393 buffer, length, decimal_point);
394 }
395 TrimZeros(buffer, length, decimal_point);
396 buffer[*length] = '\0';
397 if ((*length) == 0) {
398 // The string is empty and the decimal_point thus has no importance. Mimic
399 // Gay's dtoa and set it to -fractional_count.
400 *decimal_point = -fractional_count;
401 }
402 return true;
403}
uint64_t Significand() const
Definition: ieee.h:123
int Exponent() const
Definition: ieee.h:114
static void FillDigits64FixedLength(uint64_t number, Vector< char > buffer, int *length)
Definition: fixed-dtoa.cc:153
static void FillFractionals(uint64_t fractionals, int exponent, int fractional_count, Vector< char > buffer, int *length, int *decimal_point)
Definition: fixed-dtoa.cc:230
static const int kDoubleSignificandSize
Definition: fixed-dtoa.cc:117
static void FillDigits32(uint32_t number, Vector< char > buffer, int *length)
Definition: fixed-dtoa.cc:130
static void TrimZeros(Vector< char > buffer, int *length, int *decimal_point)
Definition: fixed-dtoa.cc:292
static void FillDigits64(uint64_t number, Vector< char > buffer, int *length)
Definition: fixed-dtoa.cc:168

◆ FillDigits32()

static void double_conversion::FillDigits32 ( uint32_t  number,
Vector< char >  buffer,
int length 
)
static

Definition at line 130 of file fixed-dtoa.cc.

130 {
131 int number_length = 0;
132 // We fill the digits in reverse order and exchange them afterwards.
133 while (number != 0) {
134 int digit = number % 10;
135 number /= 10;
136 buffer[(*length) + number_length] = static_cast<char>('0' + digit);
137 number_length++;
138 }
139 // Exchange the digits.
140 int i = *length;
141 int j = *length + number_length - 1;
142 while (i < j) {
143 char tmp = buffer[i];
144 buffer[i] = buffer[j];
145 buffer[j] = tmp;
146 i++;
147 j--;
148 }
149 *length += number_length;
150}

◆ FillDigits32FixedLength()

static void double_conversion::FillDigits32FixedLength ( uint32_t  number,
int  requested_length,
Vector< char >  buffer,
int length 
)
static

Definition at line 120 of file fixed-dtoa.cc.

121 {
122 for (int i = requested_length - 1; i >= 0; --i) {
123 buffer[(*length) + i] = '0' + number % 10;
124 number /= 10;
125 }
126 *length += requested_length;
127}

◆ FillDigits64()

static void double_conversion::FillDigits64 ( uint64_t  number,
Vector< char >  buffer,
int length 
)
static

Definition at line 168 of file fixed-dtoa.cc.

168 {
169 const uint32_t kTen7 = 10000000;
170 // For efficiency cut the number into 3 uint32_t parts, and print those.
171 uint32_t part2 = static_cast<uint32_t>(number % kTen7);
172 number /= kTen7;
173 uint32_t part1 = static_cast<uint32_t>(number % kTen7);
174 uint32_t part0 = static_cast<uint32_t>(number / kTen7);
175
176 if (part0 != 0) {
177 FillDigits32(part0, buffer, length);
180 } else if (part1 != 0) {
181 FillDigits32(part1, buffer, length);
183 } else {
184 FillDigits32(part2, buffer, length);
185 }
186}
static void FillDigits32FixedLength(uint32_t number, int requested_length, Vector< char > buffer, int *length)
Definition: fixed-dtoa.cc:120

◆ FillDigits64FixedLength()

static void double_conversion::FillDigits64FixedLength ( uint64_t  number,
Vector< char >  buffer,
int length 
)
static

Definition at line 153 of file fixed-dtoa.cc.

154 {
155 const uint32_t kTen7 = 10000000;
156 // For efficiency cut the number into 3 uint32_t parts, and print those.
157 uint32_t part2 = static_cast<uint32_t>(number % kTen7);
158 number /= kTen7;
159 uint32_t part1 = static_cast<uint32_t>(number % kTen7);
160 uint32_t part0 = static_cast<uint32_t>(number / kTen7);
161
165}

◆ FillFractionals()

static void double_conversion::FillFractionals ( uint64_t  fractionals,
int  exponent,
int  fractional_count,
Vector< char >  buffer,
int length,
int decimal_point 
)
static

Definition at line 230 of file fixed-dtoa.cc.

232 {
233 DOUBLE_CONVERSION_ASSERT(-128 <= exponent && exponent <= 0);
234 // 'fractionals' is a fixed-point number, with binary point at bit
235 // (-exponent). Inside the function the non-converted remainder of fractionals
236 // is a fixed-point number, with binary point at bit 'point'.
237 if (-exponent <= 64) {
238 // One 64 bit number is sufficient.
239 DOUBLE_CONVERSION_ASSERT(fractionals >> 56 == 0);
240 int point = -exponent;
241 for (int i = 0; i < fractional_count; ++i) {
242 if (fractionals == 0) break;
243 // Instead of multiplying by 10 we multiply by 5 and adjust the point
244 // location. This way the fractionals variable will not overflow.
245 // Invariant at the beginning of the loop: fractionals < 2^point.
246 // Initially we have: point <= 64 and fractionals < 2^56
247 // After each iteration the point is decremented by one.
248 // Note that 5^3 = 125 < 128 = 2^7.
249 // Therefore three iterations of this loop will not overflow fractionals
250 // (even without the subtraction at the end of the loop body). At this
251 // time point will satisfy point <= 61 and therefore fractionals < 2^point
252 // and any further multiplication of fractionals by 5 will not overflow.
253 fractionals *= 5;
254 point--;
255 int digit = static_cast<int>(fractionals >> point);
256 DOUBLE_CONVERSION_ASSERT(digit <= 9);
257 buffer[*length] = static_cast<char>('0' + digit);
258 (*length)++;
259 fractionals -= static_cast<uint64_t>(digit) << point;
260 }
261 // If the first bit after the point is set we have to round up.
262 DOUBLE_CONVERSION_ASSERT(fractionals == 0 || point - 1 >= 0);
263 if ((fractionals != 0) && ((fractionals >> (point - 1)) & 1) == 1) {
264 RoundUp(buffer, length, decimal_point);
265 }
266 } else { // We need 128 bits.
267 DOUBLE_CONVERSION_ASSERT(64 < -exponent && -exponent <= 128);
268 UInt128 fractionals128 = UInt128(fractionals, 0);
269 fractionals128.Shift(-exponent - 64);
270 int point = 128;
271 for (int i = 0; i < fractional_count; ++i) {
272 if (fractionals128.IsZero()) break;
273 // As before: instead of multiplying by 10 we multiply by 5 and adjust the
274 // point location.
275 // This multiplication will not overflow for the same reasons as before.
276 fractionals128.Multiply(5);
277 point--;
278 int digit = fractionals128.DivModPowerOf2(point);
279 DOUBLE_CONVERSION_ASSERT(digit <= 9);
280 buffer[*length] = static_cast<char>('0' + digit);
281 (*length)++;
282 }
283 if (fractionals128.BitAt(point - 1) == 1) {
284 RoundUp(buffer, length, decimal_point);
285 }
286 }
287}
static void RoundUp(Vector< char > buffer, int *length, int *decimal_point)
Definition: fixed-dtoa.cc:189

◆ FixupMultiply10()

static void double_conversion::FixupMultiply10 ( int  estimated_power,
bool  is_even,
int decimal_point,
Bignum numerator,
Bignum denominator,
Bignum delta_minus,
Bignum delta_plus 
)
static

Definition at line 612 of file bignum-dtoa.cc.

615 {
616 bool in_range;
617 if (is_even) {
618 // For IEEE doubles half-way cases (in decimal system numbers ending with 5)
619 // are rounded to the closest floating-point number with even significand.
620 in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
621 } else {
622 in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
623 }
624 if (in_range) {
625 // Since numerator + delta_plus >= denominator we already have
626 // 1 <= numerator/denominator < 10. Simply update the estimated_power.
627 *decimal_point = estimated_power + 1;
628 } else {
629 *decimal_point = estimated_power;
630 numerator->Times10();
631 if (Bignum::Equal(*delta_minus, *delta_plus)) {
632 delta_minus->Times10();
633 delta_plus->AssignBignum(*delta_minus);
634 } else {
635 delta_minus->Times10();
636 delta_plus->Times10();
637 }
638 }
639}
void AssignBignum(const Bignum &other)
Definition: bignum.cc:75

◆ float_to_uint32()

static uint32_t double_conversion::float_to_uint32 ( float  f)
static

Definition at line 38 of file ieee.h.

38{ return BitCast<uint32_t>(f); }

◆ GenerateCountedDigits()

static void double_conversion::GenerateCountedDigits ( int  count,
int decimal_point,
Bignum numerator,
Bignum denominator,
Vector< char >  buffer,
int length 
)
static

Definition at line 283 of file bignum-dtoa.cc.

285 {
287 for (int i = 0; i < count - 1; ++i) {
288 uint16_t digit;
289 digit = numerator->DivideModuloIntBignum(*denominator);
290 DOUBLE_CONVERSION_ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
291 // digit = numerator / denominator (integer division).
292 // numerator = numerator % denominator.
293 buffer[i] = static_cast<char>(digit + '0');
294 // Prepare for next iteration.
295 numerator->Times10();
296 }
297 // Generate the last digit.
298 uint16_t digit;
299 digit = numerator->DivideModuloIntBignum(*denominator);
300 if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
301 digit++;
302 }
303 DOUBLE_CONVERSION_ASSERT(digit <= 10);
304 buffer[count - 1] = static_cast<char>(digit + '0');
305 // Correct bad digits (in case we had a sequence of '9's). Propagate the
306 // carry until we hat a non-'9' or til we reach the first digit.
307 for (int i = count - 1; i > 0; --i) {
308 if (buffer[i] != '0' + 10) break;
309 buffer[i] = '0';
310 buffer[i - 1]++;
311 }
312 if (buffer[0] == '0' + 10) {
313 // Propagate a carry past the top place.
314 buffer[0] = '1';
315 (*decimal_point)++;
316 }
317 *length = count;
318}
int count
Definition: FontMgrTest.cpp:50
uint16_t DivideModuloIntBignum(const Bignum &other)
Definition: bignum.cc:502

◆ GenerateShortestDigits()

static void double_conversion::GenerateShortestDigits ( Bignum numerator,
Bignum denominator,
Bignum delta_minus,
Bignum delta_plus,
bool  is_even,
Vector< char >  buffer,
int length 
)
static

Definition at line 185 of file bignum-dtoa.cc.

188 {
189 // Small optimization: if delta_minus and delta_plus are the same just reuse
190 // one of the two bignums.
191 if (Bignum::Equal(*delta_minus, *delta_plus)) {
192 delta_plus = delta_minus;
193 }
194 *length = 0;
195 for (;;) {
196 uint16_t digit;
197 digit = numerator->DivideModuloIntBignum(*denominator);
198 DOUBLE_CONVERSION_ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
199 // digit = numerator / denominator (integer division).
200 // numerator = numerator % denominator.
201 buffer[(*length)++] = static_cast<char>(digit + '0');
202
203 // Can we stop already?
204 // If the remainder of the division is less than the distance to the lower
205 // boundary we can stop. In this case we simply round down (discarding the
206 // remainder).
207 // Similarly we test if we can round up (using the upper boundary).
208 bool in_delta_room_minus;
209 bool in_delta_room_plus;
210 if (is_even) {
211 in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus);
212 } else {
213 in_delta_room_minus = Bignum::Less(*numerator, *delta_minus);
214 }
215 if (is_even) {
216 in_delta_room_plus =
217 Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
218 } else {
219 in_delta_room_plus =
220 Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
221 }
222 if (!in_delta_room_minus && !in_delta_room_plus) {
223 // Prepare for next iteration.
224 numerator->Times10();
225 delta_minus->Times10();
226 // We optimized delta_plus to be equal to delta_minus (if they share the
227 // same value). So don't multiply delta_plus if they point to the same
228 // object.
229 if (delta_minus != delta_plus) {
230 delta_plus->Times10();
231 }
232 } else if (in_delta_room_minus && in_delta_room_plus) {
233 // Let's see if 2*numerator < denominator.
234 // If yes, then the next digit would be < 5 and we can round down.
235 int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator);
236 if (compare < 0) {
237 // Remaining digits are less than .5. -> Round down (== do nothing).
238 } else if (compare > 0) {
239 // Remaining digits are more than .5 of denominator. -> Round up.
240 // Note that the last digit could not be a '9' as otherwise the whole
241 // loop would have stopped earlier.
242 // We still have an assert here in case the preconditions were not
243 // satisfied.
244 DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9');
245 buffer[(*length) - 1]++;
246 } else {
247 // Halfway case.
248 // TODO(floitsch): need a way to solve half-way cases.
249 // For now let's round towards even (since this is what Gay seems to
250 // do).
251
252 if ((buffer[(*length) - 1] - '0') % 2 == 0) {
253 // Round down => Do nothing.
254 } else {
255 DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9');
256 buffer[(*length) - 1]++;
257 }
258 }
259 return;
260 } else if (in_delta_room_minus) {
261 // Round down (== do nothing).
262 return;
263 } else { // in_delta_room_plus
264 // Round up.
265 // Note again that the last digit could not be '9' since this would have
266 // stopped the loop earlier.
267 // We still have an DOUBLE_CONVERSION_ASSERT here, in case the preconditions were not
268 // satisfied.
270 buffer[(*length) - 1]++;
271 return;
272 }
273 }
274}
int compare(const void *untyped_lhs, const void *untyped_rhs)
Definition: skdiff.h:161

◆ Grisu3()

static bool double_conversion::Grisu3 ( double  v,
FastDtoaMode  mode,
Vector< char >  buffer,
int length,
int decimal_exponent 
)
static

Definition at line 519 of file fast-dtoa.cc.

523 {
525 // boundary_minus and boundary_plus are the boundaries between v and its
526 // closest floating-point neighbors. Any number strictly between
527 // boundary_minus and boundary_plus will round to v when convert to a double.
528 // Grisu3 will never output representations that lie exactly on a boundary.
529 DiyFp boundary_minus, boundary_plus;
530 if (mode == FAST_DTOA_SHORTEST) {
531 Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
532 } else {
534 float single_v = static_cast<float>(v);
535 Single(single_v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
536 }
537 DOUBLE_CONVERSION_ASSERT(boundary_plus.e() == w.e());
538 DiyFp ten_mk; // Cached power of ten: 10^-k
539 int mk; // -k
540 int ten_mk_minimal_binary_exponent =
541 kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
542 int ten_mk_maximal_binary_exponent =
543 kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
545 ten_mk_minimal_binary_exponent,
546 ten_mk_maximal_binary_exponent,
547 &ten_mk, &mk);
549 DiyFp::kSignificandSize) &&
550 (kMaximalTargetExponent >= w.e() + ten_mk.e() +
551 DiyFp::kSignificandSize));
552 // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
553 // 64 bit significand and ten_mk is thus only precise up to 64 bits.
554
555 // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
556 // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
557 // off by a small amount.
558 // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
559 // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
560 // (f-1) * 2^e < w*10^k < (f+1) * 2^e
561 DiyFp scaled_w = DiyFp::Times(w, ten_mk);
562 DOUBLE_CONVERSION_ASSERT(scaled_w.e() ==
563 boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize);
564 // In theory it would be possible to avoid some recomputations by computing
565 // the difference between w and boundary_minus/plus (a power of 2) and to
566 // compute scaled_boundary_minus/plus by subtracting/adding from
567 // scaled_w. However the code becomes much less readable and the speed
568 // enhancements are not terrific.
569 DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk);
570 DiyFp scaled_boundary_plus = DiyFp::Times(boundary_plus, ten_mk);
571
572 // DigitGen will generate the digits of scaled_w. Therefore we have
573 // v == (double) (scaled_w * 10^-mk).
574 // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
575 // integer than it will be updated. For instance if scaled_w == 1.23 then
576 // the buffer will be filled with "123" and the decimal_exponent will be
577 // decreased by 2.
578 int kappa;
579 bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
580 buffer, length, &kappa);
581 *decimal_exponent = -mk + kappa;
582 return result;
583}
void NormalizedBoundaries(DiyFp *out_m_minus, DiyFp *out_m_plus) const
Definition: ieee.h:191
DiyFp AsNormalizedDiyFp() const
Definition: ieee.h:69
void GetCachedPowerForBinaryExponentRange(int min_exponent, int max_exponent, DiyFp *power, int *decimal_exponent)
static bool DigitGen(DiyFp low, DiyFp w, DiyFp high, Vector< char > buffer, int *length, int *kappa)
Definition: fast-dtoa.cc:300

◆ Grisu3Counted()

static bool double_conversion::Grisu3Counted ( double  v,
int  requested_digits,
Vector< char >  buffer,
int length,
int decimal_exponent 
)
static

Definition at line 591 of file fast-dtoa.cc.

595 {
597 DiyFp ten_mk; // Cached power of ten: 10^-k
598 int mk; // -k
599 int ten_mk_minimal_binary_exponent =
600 kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
601 int ten_mk_maximal_binary_exponent =
602 kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
604 ten_mk_minimal_binary_exponent,
605 ten_mk_maximal_binary_exponent,
606 &ten_mk, &mk);
608 DiyFp::kSignificandSize) &&
609 (kMaximalTargetExponent >= w.e() + ten_mk.e() +
610 DiyFp::kSignificandSize));
611 // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
612 // 64 bit significand and ten_mk is thus only precise up to 64 bits.
613
614 // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
615 // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
616 // off by a small amount.
617 // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
618 // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
619 // (f-1) * 2^e < w*10^k < (f+1) * 2^e
620 DiyFp scaled_w = DiyFp::Times(w, ten_mk);
621
622 // We now have (double) (scaled_w * 10^-mk).
623 // DigitGen will generate the first requested_digits digits of scaled_w and
624 // return together with a kappa such that scaled_w ~= buffer * 10^kappa. (It
625 // will not always be exactly the same since DigitGenCounted only produces a
626 // limited number of digits.)
627 int kappa;
628 bool result = DigitGenCounted(scaled_w, requested_digits,
629 buffer, length, &kappa);
630 *decimal_exponent = -mk + kappa;
631 return result;
632}
static bool DigitGenCounted(DiyFp w, int requested_digits, Vector< char > buffer, int *length, int *kappa)
Definition: fast-dtoa.cc:428

◆ HexCharOfValue()

static char double_conversion::HexCharOfValue ( const int  value)
static

Definition at line 580 of file bignum.cc.

580 {
581 DOUBLE_CONVERSION_ASSERT(0 <= value && value <= 16);
582 if (value < 10) {
583 return static_cast<char>(value + '0');
584 }
585 return static_cast<char>(value - 10 + 'A');
586}

◆ HexCharValue()

static uint64_t double_conversion::HexCharValue ( const int  c)
static

Definition at line 118 of file bignum.cc.

118 {
119 if ('0' <= c && c <= '9') {
120 return c - '0';
121 }
122 if ('a' <= c && c <= 'f') {
123 return 10 + c - 'a';
124 }
125 DOUBLE_CONVERSION_ASSERT('A' <= c && c <= 'F');
126 return 10 + c - 'A';
127}

◆ InitialScaledStartValues()

static void double_conversion::InitialScaledStartValues ( uint64_t  significand,
int  exponent,
bool  lower_boundary_is_closer,
int  estimated_power,
bool  need_boundary_deltas,
Bignum numerator,
Bignum denominator,
Bignum delta_minus,
Bignum delta_plus 
)
static

Definition at line 568 of file bignum-dtoa.cc.

576 {
577 if (exponent >= 0) {
579 significand, exponent, estimated_power, need_boundary_deltas,
580 numerator, denominator, delta_minus, delta_plus);
581 } else if (estimated_power >= 0) {
583 significand, exponent, estimated_power, need_boundary_deltas,
584 numerator, denominator, delta_minus, delta_plus);
585 } else {
587 significand, exponent, estimated_power, need_boundary_deltas,
588 numerator, denominator, delta_minus, delta_plus);
589 }
590
591 if (need_boundary_deltas && lower_boundary_is_closer) {
592 // The lower boundary is closer at half the distance of "normal" numbers.
593 // Increase the common denominator and adapt all but the delta_minus.
594 denominator->ShiftLeft(1); // *2
595 numerator->ShiftLeft(1); // *2
596 delta_plus->ShiftLeft(1); // *2
597 }
598}
static void InitialScaledStartValuesNegativeExponentPositivePower(uint64_t significand, int exponent, int estimated_power, bool need_boundary_deltas, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
Definition: bignum-dtoa.cc:450
static void InitialScaledStartValuesPositiveExponent(uint64_t significand, int exponent, int estimated_power, bool need_boundary_deltas, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
Definition: bignum-dtoa.cc:417
static void InitialScaledStartValuesNegativeExponentNegativePower(uint64_t significand, int exponent, int estimated_power, bool need_boundary_deltas, Bignum *numerator, Bignum *denominator, Bignum *delta_minus, Bignum *delta_plus)
Definition: bignum-dtoa.cc:484

◆ InitialScaledStartValuesNegativeExponentNegativePower()

static void double_conversion::InitialScaledStartValuesNegativeExponentNegativePower ( uint64_t  significand,
int  exponent,
int  estimated_power,
bool  need_boundary_deltas,
Bignum numerator,
Bignum denominator,
Bignum delta_minus,
Bignum delta_plus 
)
static

Definition at line 484 of file bignum-dtoa.cc.

488 {
489 // Instead of multiplying the denominator with 10^estimated_power we
490 // multiply all values (numerator and deltas) by 10^-estimated_power.
491
492 // Use numerator as temporary container for power_ten.
493 Bignum* power_ten = numerator;
494 power_ten->AssignPowerUInt16(10, -estimated_power);
495
496 if (need_boundary_deltas) {
497 // Since power_ten == numerator we must make a copy of 10^estimated_power
498 // before we complete the computation of the numerator.
499 // delta_plus = delta_minus = 10^estimated_power
500 delta_plus->AssignBignum(*power_ten);
501 delta_minus->AssignBignum(*power_ten);
502 }
503
504 // numerator = significand * 2 * 10^-estimated_power
505 // since v = significand * 2^exponent this is equivalent to
506 // numerator = v * 10^-estimated_power * 2 * 2^-exponent.
507 // Remember: numerator has been abused as power_ten. So no need to assign it
508 // to itself.
509 DOUBLE_CONVERSION_ASSERT(numerator == power_ten);
510 numerator->MultiplyByUInt64(significand);
511
512 // denominator = 2 * 2^-exponent with exponent < 0.
513 denominator->AssignUInt16(1);
514 denominator->ShiftLeft(-exponent);
515
516 if (need_boundary_deltas) {
517 // Introduce a common denominator so that the deltas to the boundaries are
518 // integers.
519 numerator->ShiftLeft(1);
520 denominator->ShiftLeft(1);
521 // With this shift the boundaries have their correct value, since
522 // delta_plus = 10^-estimated_power, and
523 // delta_minus = 10^-estimated_power.
524 // These assignments have been done earlier.
525 // The adjustments if f == 2^p-1 (lower boundary is closer) are done later.
526 }
527}
void AssignPowerUInt16(uint16_t base, const int exponent)
Definition: bignum.cc:427
void AssignUInt16(const uint16_t value)
Definition: bignum.cc:55
void MultiplyByUInt64(const uint64_t factor)
Definition: bignum.cc:279

◆ InitialScaledStartValuesNegativeExponentPositivePower()

static void double_conversion::InitialScaledStartValuesNegativeExponentPositivePower ( uint64_t  significand,
int  exponent,
int  estimated_power,
bool  need_boundary_deltas,
Bignum numerator,
Bignum denominator,
Bignum delta_minus,
Bignum delta_plus 
)
static

Definition at line 450 of file bignum-dtoa.cc.

454 {
455 // v = f * 2^e with e < 0, and with estimated_power >= 0.
456 // This means that e is close to 0 (have a look at how estimated_power is
457 // computed).
458
459 // numerator = significand
460 // since v = significand * 2^exponent this is equivalent to
461 // numerator = v * / 2^-exponent
462 numerator->AssignUInt64(significand);
463 // denominator = 10^estimated_power * 2^-exponent (with exponent < 0)
464 denominator->AssignPowerUInt16(10, estimated_power);
465 denominator->ShiftLeft(-exponent);
466
467 if (need_boundary_deltas) {
468 // Introduce a common denominator so that the deltas to the boundaries are
469 // integers.
470 denominator->ShiftLeft(1);
471 numerator->ShiftLeft(1);
472 // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
473 // denominator (of 2) delta_plus equals 2^e.
474 // Given that the denominator already includes v's exponent the distance
475 // to the boundaries is simply 1.
476 delta_plus->AssignUInt16(1);
477 // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
478 delta_minus->AssignUInt16(1);
479 }
480}

◆ InitialScaledStartValuesPositiveExponent()

static void double_conversion::InitialScaledStartValuesPositiveExponent ( uint64_t  significand,
int  exponent,
int  estimated_power,
bool  need_boundary_deltas,
Bignum numerator,
Bignum denominator,
Bignum delta_minus,
Bignum delta_plus 
)
static

Definition at line 417 of file bignum-dtoa.cc.

421 {
422 // A positive exponent implies a positive power.
423 DOUBLE_CONVERSION_ASSERT(estimated_power >= 0);
424 // Since the estimated_power is positive we simply multiply the denominator
425 // by 10^estimated_power.
426
427 // numerator = v.
428 numerator->AssignUInt64(significand);
429 numerator->ShiftLeft(exponent);
430 // denominator = 10^estimated_power.
431 denominator->AssignPowerUInt16(10, estimated_power);
432
433 if (need_boundary_deltas) {
434 // Introduce a common denominator so that the deltas to the boundaries are
435 // integers.
436 denominator->ShiftLeft(1);
437 numerator->ShiftLeft(1);
438 // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
439 // denominator (of 2) delta_plus equals 2^e.
440 delta_plus->AssignUInt16(1);
441 delta_plus->ShiftLeft(exponent);
442 // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
443 delta_minus->AssignUInt16(1);
444 delta_minus->ShiftLeft(exponent);
445 }
446}

◆ IsCharacterDigitForRadix()

static bool double_conversion::IsCharacterDigitForRadix ( int  c,
int  radix,
char  a_character 
)
static

Definition at line 184 of file string-to-double.cc.

184 {
185 return radix > 10 && c >= a_character && c < a_character + radix - 10;
186}

◆ IsDecimalDigitForRadix()

static bool double_conversion::IsDecimalDigitForRadix ( int  c,
int  radix 
)
inlinestatic

Definition at line 173 of file string-to-double.cc.

173 {
174 return '0' <= c && c <= '9' && (c - '0') < radix;
175}

◆ IsDigit()

static bool double_conversion::IsDigit ( const char  d)
static

Definition at line 444 of file strtod.cc.

444 {
445 return ('0' <= d) && (d <= '9');
446}

◆ isDigit()

static bool double_conversion::isDigit ( int  x,
int  radix 
)
static

Definition at line 148 of file string-to-double.cc.

148 {
149 return (x >= '0' && x <= '9' && x < '0' + radix)
150 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
151 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
152}
double x

◆ IsHexFloatString()

template<class Iterator >
static bool double_conversion::IsHexFloatString ( Iterator  start,
Iterator  end,
uc16  separator,
bool  allow_trailing_junk 
)
static

Definition at line 216 of file string-to-double.cc.

219 {
221
222 Iterator current = start;
223
224 bool saw_digit = false;
225 while (isDigit(*current, 16)) {
226 saw_digit = true;
227 if (Advance(&current, separator, 16, end)) return false;
228 }
229 if (*current == '.') {
230 if (Advance(&current, separator, 16, end)) return false;
231 while (isDigit(*current, 16)) {
232 saw_digit = true;
233 if (Advance(&current, separator, 16, end)) return false;
234 }
235 }
236 if (!saw_digit) return false;
237 if (*current != 'p' && *current != 'P') return false;
238 if (Advance(&current, separator, 16, end)) return false;
239 if (*current == '+' || *current == '-') {
240 if (Advance(&current, separator, 16, end)) return false;
241 }
242 if (!isDigit(*current, 10)) return false;
243 if (Advance(&current, separator, 16, end)) return true;
244 while (isDigit(*current, 10)) {
245 if (Advance(&current, separator, 16, end)) return true;
246 }
247 return allow_trailing_junk || !AdvanceToNonspace(&current, end);
248}
static bool Advance(Iterator *it, uc16 separator, int base, Iterator &end)
static bool AdvanceToNonspace(Iterator *current, Iterator end)

◆ IsNonZeroDigit()

static bool double_conversion::IsNonZeroDigit ( const char  d)
static

Definition at line 448 of file strtod.cc.

448 {
449 return ('1' <= d) && (d <= '9');
450}

◆ isWhitespace()

static bool double_conversion::isWhitespace ( int  x)
static

Definition at line 123 of file string-to-double.cc.

123 {
124 if (x < 128) {
125 for (int i = 0; i < kWhitespaceTable7Length; i++) {
126 if (kWhitespaceTable7[i] == x) return true;
127 }
128 } else {
129 for (int i = 0; i < kWhitespaceTable16Length; i++) {
130 if (kWhitespaceTable16[i] == x) return true;
131 }
132 }
133 return false;
134}
static const int kWhitespaceTable7Length
static const int kWhitespaceTable16Length
static const uc16 kWhitespaceTable16[]
static const char kWhitespaceTable7[]

◆ NormalizedExponent()

static int double_conversion::NormalizedExponent ( uint64_t  significand,
int  exponent 
)
static

Definition at line 37 of file bignum-dtoa.cc.

37 {
38 DOUBLE_CONVERSION_ASSERT(significand != 0);
39 while ((significand & Double::kHiddenBit) == 0) {
40 significand = significand << 1;
41 exponent = exponent - 1;
42 }
43 return exponent;
44}

◆ RadixStringToIeee()

template<int radix_log_2, class Iterator >
static double double_conversion::RadixStringToIeee ( Iterator *  current,
Iterator  end,
bool  sign,
uc16  separator,
bool  parse_as_hex_float,
bool  allow_trailing_junk,
double  junk_string_value,
bool  read_as_double,
bool *  result_is_junk 
)
static

Definition at line 256 of file string-to-double.cc.

264 {
265 DOUBLE_CONVERSION_ASSERT(*current != end);
266 DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float ||
267 IsHexFloatString(*current, end, separator, allow_trailing_junk));
268
269 const int kDoubleSize = Double::kSignificandSize;
270 const int kSingleSize = Single::kSignificandSize;
271 const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
272
273 *result_is_junk = true;
274
275 int64_t number = 0;
276 int exponent = 0;
277 const int radix = (1 << radix_log_2);
278 // Whether we have encountered a '.' and are parsing the decimal digits.
279 // Only relevant if parse_as_hex_float is true.
280 bool post_decimal = false;
281
282 // Skip leading 0s.
283 while (**current == '0') {
284 if (Advance(current, separator, radix, end)) {
285 *result_is_junk = false;
286 return SignedZero(sign);
287 }
288 }
289
290 while (true) {
291 int digit;
292 if (IsDecimalDigitForRadix(**current, radix)) {
293 digit = static_cast<char>(**current) - '0';
294 if (post_decimal) exponent -= radix_log_2;
295 } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
296 digit = static_cast<char>(**current) - 'a' + 10;
297 if (post_decimal) exponent -= radix_log_2;
298 } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
299 digit = static_cast<char>(**current) - 'A' + 10;
300 if (post_decimal) exponent -= radix_log_2;
301 } else if (parse_as_hex_float && **current == '.') {
302 post_decimal = true;
303 Advance(current, separator, radix, end);
304 DOUBLE_CONVERSION_ASSERT(*current != end);
305 continue;
306 } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
307 break;
308 } else {
309 if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
310 break;
311 } else {
312 return junk_string_value;
313 }
314 }
315
316 number = number * radix + digit;
317 int overflow = static_cast<int>(number >> kSignificandSize);
318 if (overflow != 0) {
319 // Overflow occurred. Need to determine which direction to round the
320 // result.
321 int overflow_bits_count = 1;
322 while (overflow > 1) {
323 overflow_bits_count++;
324 overflow >>= 1;
325 }
326
327 int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
328 int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
329 number >>= overflow_bits_count;
330 exponent += overflow_bits_count;
331
332 bool zero_tail = true;
333 for (;;) {
334 if (Advance(current, separator, radix, end)) break;
335 if (parse_as_hex_float && **current == '.') {
336 // Just run over the '.'. We are just trying to see whether there is
337 // a non-zero digit somewhere.
338 Advance(current, separator, radix, end);
339 DOUBLE_CONVERSION_ASSERT(*current != end);
340 post_decimal = true;
341 }
342 if (!isDigit(**current, radix)) break;
343 zero_tail = zero_tail && **current == '0';
344 if (!post_decimal) exponent += radix_log_2;
345 }
346
347 if (!parse_as_hex_float &&
348 !allow_trailing_junk &&
349 AdvanceToNonspace(current, end)) {
350 return junk_string_value;
351 }
352
353 int middle_value = (1 << (overflow_bits_count - 1));
354 if (dropped_bits > middle_value) {
355 number++; // Rounding up.
356 } else if (dropped_bits == middle_value) {
357 // Rounding to even to consistency with decimals: half-way case rounds
358 // up if significant part is odd and down otherwise.
359 if ((number & 1) != 0 || !zero_tail) {
360 number++; // Rounding up.
361 }
362 }
363
364 // Rounding up may cause overflow.
365 if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
366 exponent++;
367 number >>= 1;
368 }
369 break;
370 }
371 if (Advance(current, separator, radix, end)) break;
372 }
373
374 DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize));
375 DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
376
377 *result_is_junk = false;
378
379 if (parse_as_hex_float) {
380 DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P');
381 Advance(current, separator, radix, end);
382 DOUBLE_CONVERSION_ASSERT(*current != end);
383 bool is_negative = false;
384 if (**current == '+') {
385 Advance(current, separator, radix, end);
386 DOUBLE_CONVERSION_ASSERT(*current != end);
387 } else if (**current == '-') {
388 is_negative = true;
389 Advance(current, separator, radix, end);
390 DOUBLE_CONVERSION_ASSERT(*current != end);
391 }
392 int written_exponent = 0;
393 while (IsDecimalDigitForRadix(**current, 10)) {
394 // No need to read exponents if they are too big. That could potentially overflow
395 // the `written_exponent` variable.
396 if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
397 written_exponent = 10 * written_exponent + **current - '0';
398 }
399 if (Advance(current, separator, radix, end)) break;
400 }
401 if (is_negative) written_exponent = -written_exponent;
402 exponent += written_exponent;
403 }
404
405 if (exponent == 0 || number == 0) {
406 if (sign) {
407 if (number == 0) return -0.0;
408 number = -number;
409 }
410 return static_cast<double>(number);
411 }
412
413 DOUBLE_CONVERSION_ASSERT(number != 0);
414 double result = Double(DiyFp(number, exponent)).value();
415 return sign ? -result : result;
416}
static int sign(SkScalar x)
Definition: SkPath.cpp:2205
constexpr intptr_t kDoubleSize
Definition: globals.h:456
static bool IsHexFloatString(Iterator start, Iterator end, uc16 separator, bool allow_trailing_junk)
static bool IsDecimalDigitForRadix(int c, int radix)
static bool IsCharacterDigitForRadix(int c, int radix, char a_character)
static double SignedZero(bool sign)
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707

◆ ReadDiyFp()

static void double_conversion::ReadDiyFp ( Vector< const char >  buffer,
DiyFp result,
int remaining_decimals 
)
static

Definition at line 169 of file strtod.cc.

171 {
172 int read_digits;
173 uint64_t significand = ReadUint64(buffer, &read_digits);
174 if (buffer.length() == read_digits) {
175 *result = DiyFp(significand, 0);
176 *remaining_decimals = 0;
177 } else {
178 // Round the significand.
179 if (buffer[read_digits] >= '5') {
180 significand++;
181 }
182 // Compute the binary exponent.
183 int exponent = 0;
184 *result = DiyFp(significand, exponent);
185 *remaining_decimals = buffer.length() - read_digits;
186 }
187}

◆ ReadUInt64()

static uint64_t double_conversion::ReadUInt64 ( const Vector< const char >  buffer,
const int  from,
const int  digits_to_read 
)
static

Definition at line 84 of file bignum.cc.

86 {
87 uint64_t result = 0;
88 for (int i = from; i < from + digits_to_read; ++i) {
89 const int digit = buffer[i] - '0';
90 DOUBLE_CONVERSION_ASSERT(0 <= digit && digit <= 9);
91 result = result * 10 + digit;
92 }
93 return result;
94}

◆ ReadUint64()

static uint64_t double_conversion::ReadUint64 ( Vector< const char >  buffer,
int number_of_read_digits 
)
static

Definition at line 151 of file strtod.cc.

152 {
153 uint64_t result = 0;
154 int i = 0;
155 while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
156 int digit = buffer[i++] - '0';
157 DOUBLE_CONVERSION_ASSERT(0 <= digit && digit <= 9);
158 result = 10 * result + digit;
159 }
160 *number_of_read_digits = i;
161 return result;
162}
static const uint64_t kMaxUint64
Definition: strtod.cc:57

◆ RoundUp()

static void double_conversion::RoundUp ( Vector< char >  buffer,
int length,
int decimal_point 
)
static

Definition at line 189 of file fixed-dtoa.cc.

189 {
190 // An empty buffer represents 0.
191 if (*length == 0) {
192 buffer[0] = '1';
193 *decimal_point = 1;
194 *length = 1;
195 return;
196 }
197 // Round the last digit until we either have a digit that was not '9' or until
198 // we reached the first digit.
199 buffer[(*length) - 1]++;
200 for (int i = (*length) - 1; i > 0; --i) {
201 if (buffer[i] != '0' + 10) {
202 return;
203 }
204 buffer[i] = '0';
205 buffer[i - 1]++;
206 }
207 // If the first digit is now '0' + 10, we would need to set it to '0' and add
208 // a '1' in front. However we reach the first digit only if all following
209 // digits had been '9' before rounding up. Now all trailing digits are '0' and
210 // we simply switch the first digit to '1' and update the decimal-point
211 // (indicating that the point is now one digit to the right).
212 if (buffer[0] == '0' + 10) {
213 buffer[0] = '1';
214 (*decimal_point)++;
215 }
216}

◆ RoundWeed()

static bool double_conversion::RoundWeed ( Vector< char >  buffer,
int  length,
uint64_t  distance_too_high_w,
uint64_t  unsafe_interval,
uint64_t  rest,
uint64_t  ten_kappa,
uint64_t  unit 
)
static

Definition at line 61 of file fast-dtoa.cc.

67 {
68 uint64_t small_distance = distance_too_high_w - unit;
69 uint64_t big_distance = distance_too_high_w + unit;
70 // Let w_low = too_high - big_distance, and
71 // w_high = too_high - small_distance.
72 // Note: w_low < w < w_high
73 //
74 // The real w (* unit) must lie somewhere inside the interval
75 // ]w_low; w_high[ (often written as "(w_low; w_high)")
76
77 // Basically the buffer currently contains a number in the unsafe interval
78 // ]too_low; too_high[ with too_low < w < too_high
79 //
80 // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81 // ^v 1 unit ^ ^ ^ ^
82 // boundary_high --------------------- . . . .
83 // ^v 1 unit . . . .
84 // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . .
85 // . . ^ . .
86 // . big_distance . . .
87 // . . . . rest
88 // small_distance . . . .
89 // v . . . .
90 // w_high - - - - - - - - - - - - - - - - - - . . . .
91 // ^v 1 unit . . . .
92 // w ---------------------------------------- . . . .
93 // ^v 1 unit v . . .
94 // w_low - - - - - - - - - - - - - - - - - - - - - . . .
95 // . . v
96 // buffer --------------------------------------------------+-------+--------
97 // . .
98 // safe_interval .
99 // v .
100 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
101 // ^v 1 unit .
102 // boundary_low ------------------------- unsafe_interval
103 // ^v 1 unit v
104 // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
105 //
106 //
107 // Note that the value of buffer could lie anywhere inside the range too_low
108 // to too_high.
109 //
110 // boundary_low, boundary_high and w are approximations of the real boundaries
111 // and v (the input number). They are guaranteed to be precise up to one unit.
112 // In fact the error is guaranteed to be strictly less than one unit.
113 //
114 // Anything that lies outside the unsafe interval is guaranteed not to round
115 // to v when read again.
116 // Anything that lies inside the safe interval is guaranteed to round to v
117 // when read again.
118 // If the number inside the buffer lies inside the unsafe interval but not
119 // inside the safe interval then we simply do not know and bail out (returning
120 // false).
121 //
122 // Similarly we have to take into account the imprecision of 'w' when finding
123 // the closest representation of 'w'. If we have two potential
124 // representations, and one is closer to both w_low and w_high, then we know
125 // it is closer to the actual value v.
126 //
127 // By generating the digits of too_high we got the largest (closest to
128 // too_high) buffer that is still in the unsafe interval. In the case where
129 // w_high < buffer < too_high we try to decrement the buffer.
130 // This way the buffer approaches (rounds towards) w.
131 // There are 3 conditions that stop the decrementation process:
132 // 1) the buffer is already below w_high
133 // 2) decrementing the buffer would make it leave the unsafe interval
134 // 3) decrementing the buffer would yield a number below w_high and farther
135 // away than the current number. In other words:
136 // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high
137 // Instead of using the buffer directly we use its distance to too_high.
138 // Conceptually rest ~= too_high - buffer
139 // We need to do the following tests in this order to avoid over- and
140 // underflows.
141 DOUBLE_CONVERSION_ASSERT(rest <= unsafe_interval);
142 while (rest < small_distance && // Negated condition 1
143 unsafe_interval - rest >= ten_kappa && // Negated condition 2
144 (rest + ten_kappa < small_distance || // buffer{-1} > w_high
145 small_distance - rest >= rest + ten_kappa - small_distance)) {
146 buffer[length - 1]--;
147 rest += ten_kappa;
148 }
149
150 // We have approached w+ as much as possible. We now test if approaching w-
151 // would require changing the buffer. If yes, then we have two possible
152 // representations close to w, but we cannot decide which one is closer.
153 if (rest < big_distance &&
154 unsafe_interval - rest >= ten_kappa &&
155 (rest + ten_kappa < big_distance ||
156 big_distance - rest > rest + ten_kappa - big_distance)) {
157 return false;
158 }
159
160 // Weeding test.
161 // The safe interval is [too_low + 2 ulp; too_high - 2 ulp]
162 // Since too_low = too_high - unsafe_interval this is equivalent to
163 // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp]
164 // Conceptually we have: rest ~= too_high - buffer
165 return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit);
166}

◆ RoundWeedCounted()

static bool double_conversion::RoundWeedCounted ( Vector< char >  buffer,
int  length,
uint64_t  rest,
uint64_t  ten_kappa,
uint64_t  unit,
int kappa 
)
static

Definition at line 181 of file fast-dtoa.cc.

186 {
187 DOUBLE_CONVERSION_ASSERT(rest < ten_kappa);
188 // The following tests are done in a specific order to avoid overflows. They
189 // will work correctly with any uint64 values of rest < ten_kappa and unit.
190 //
191 // If the unit is too big, then we don't know which way to round. For example
192 // a unit of 50 means that the real number lies within rest +/- 50. If
193 // 10^kappa == 40 then there is no way to tell which way to round.
194 if (unit >= ten_kappa) return false;
195 // Even if unit is just half the size of 10^kappa we are already completely
196 // lost. (And after the previous test we know that the expression will not
197 // over/underflow.)
198 if (ten_kappa - unit <= unit) return false;
199 // If 2 * (rest + unit) <= 10^kappa we can safely round down.
200 if ((ten_kappa - rest > rest) && (ten_kappa - 2 * rest >= 2 * unit)) {
201 return true;
202 }
203 // If 2 * (rest - unit) >= 10^kappa, then we can safely round up.
204 if ((rest > unit) && (ten_kappa - (rest - unit) <= (rest - unit))) {
205 // Increment the last digit recursively until we find a non '9' digit.
206 buffer[length - 1]++;
207 for (int i = length - 1; i > 0; --i) {
208 if (buffer[i] != '0' + 10) break;
209 buffer[i] = '0';
210 buffer[i - 1]++;
211 }
212 // If the first digit is now '0'+ 10 we had a buffer with all '9's. With the
213 // exception of the first digit all digits are now '0'. Simply switch the
214 // first digit to '1' and adjust the kappa. Example: "99" becomes "10" and
215 // the power (the kappa) is increased.
216 if (buffer[0] == '0' + 10) {
217 buffer[0] = '1';
218 (*kappa) += 1;
219 }
220 return true;
221 }
222 return false;
223}

◆ SanitizedDoubletof()

static float double_conversion::SanitizedDoubletof ( double  d)
static

Definition at line 497 of file strtod.cc.

497 {
499 // ASAN has a sanitize check that disallows casting doubles to floats if
500 // they are too big.
501 // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#available-checks
502 // The behavior should be covered by IEEE 754, but some projects use this
503 // flag, so work around it.
504 float max_finite = 3.4028234663852885981170418348451692544e+38;
505 // The half-way point between the max-finite and infinity value.
506 // Since infinity has an even significand everything equal or greater than
507 // this value should become infinity.
508 double half_max_finite_infinity =
509 3.40282356779733661637539395458142568448e+38;
510 if (d >= max_finite) {
511 if (d >= half_max_finite_infinity) {
512 return Single::Infinity();
513 } else {
514 return max_finite;
515 }
516 } else {
517 return static_cast<float>(d);
518 }
519}

◆ SignedZero()

static double double_conversion::SignedZero ( bool  sign)
static

Definition at line 155 of file string-to-double.cc.

155 {
156 return sign ? -0.0 : 0.0;
157}

◆ SizeInHexChars()

template<typename S >
static int double_conversion::SizeInHexChars ( number)
static

Definition at line 569 of file bignum.cc.

569 {
570 DOUBLE_CONVERSION_ASSERT(number > 0);
571 int result = 0;
572 while (number != 0) {
573 number >>= 4;
574 result++;
575 }
576 return result;
577}

◆ StrLength()

int double_conversion::StrLength ( const char *  string)
inline

Definition at line 241 of file utils.h.

241 {
242 size_t length = strlen(string);
243 DOUBLE_CONVERSION_ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
244 return static_cast<int>(length);
245}

◆ Strtod()

double double_conversion::Strtod ( Vector< const char >  buffer,
int  exponent 
)

Definition at line 488 of file strtod.cc.

488 {
489 char copy_buffer[kMaxSignificantDecimalDigits];
490 Vector<const char> trimmed;
491 int updated_exponent;
492 TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
493 &trimmed, &updated_exponent);
494 return StrtodTrimmed(trimmed, updated_exponent);
495}
double StrtodTrimmed(Vector< const char > trimmed, int exponent)
Definition: strtod.cc:466
static void TrimAndCut(Vector< const char > buffer, int exponent, char *buffer_copy_space, int space_size, Vector< const char > *trimmed, int *updated_exponent)
Definition: strtod.cc:126

◆ StrtodTrimmed()

double double_conversion::StrtodTrimmed ( Vector< const char >  trimmed,
int  exponent 
)

Definition at line 466 of file strtod.cc.

466 {
469 double guess;
470 const bool is_correct = ComputeGuess(trimmed, exponent, &guess);
471 if (is_correct) {
472 return guess;
473 }
474 DiyFp upper_boundary = Double(guess).UpperBoundary();
475 int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
476 if (comparison < 0) {
477 return guess;
478 } else if (comparison > 0) {
479 return Double(guess).NextDouble();
480 } else if ((Double(guess).Significand() & 1) == 0) {
481 // Round towards even.
482 return guess;
483 } else {
484 return Double(guess).NextDouble();
485 }
486}
static bool ComputeGuess(Vector< const char > trimmed, int exponent, double *guess)
Definition: strtod.cc:419
static int CompareBufferWithDiyFp(Vector< const char > buffer, int exponent, DiyFp diy_fp)
Definition: strtod.cc:388
static bool AssertTrimmedDigits(const Vector< const char > &buffer)
Definition: strtod.cc:457

◆ Strtof()

float double_conversion::Strtof ( Vector< const char >  buffer,
int  exponent 
)

Definition at line 521 of file strtod.cc.

521 {
522 char copy_buffer[kMaxSignificantDecimalDigits];
523 Vector<const char> trimmed;
524 int updated_exponent;
525 TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
526 &trimmed, &updated_exponent);
527 exponent = updated_exponent;
528 return StrtofTrimmed(trimmed, exponent);
529}
float StrtofTrimmed(Vector< const char > trimmed, int exponent)
Definition: strtod.cc:531

◆ StrtofTrimmed()

float double_conversion::StrtofTrimmed ( Vector< const char >  trimmed,
int  exponent 
)

Definition at line 531 of file strtod.cc.

531 {
534
535 double double_guess;
536 bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
537
538 float float_guess = SanitizedDoubletof(double_guess);
539 if (float_guess == double_guess) {
540 // This shortcut triggers for integer values.
541 return float_guess;
542 }
543
544 // We must catch double-rounding. Say the double has been rounded up, and is
545 // now a boundary of a float, and rounds up again. This is why we have to
546 // look at previous too.
547 // Example (in decimal numbers):
548 // input: 12349
549 // high-precision (4 digits): 1235
550 // low-precision (3 digits):
551 // when read from input: 123
552 // when rounded from high precision: 124.
553 // To do this we simply look at the neighbors of the correct result and see
554 // if they would round to the same float. If the guess is not correct we have
555 // to look at four values (since two different doubles could be the correct
556 // double).
557
558 double double_next = Double(double_guess).NextDouble();
559 double double_previous = Double(double_guess).PreviousDouble();
560
561 float f1 = SanitizedDoubletof(double_previous);
562 float f2 = float_guess;
563 float f3 = SanitizedDoubletof(double_next);
564 float f4;
565 if (is_correct) {
566 f4 = f3;
567 } else {
568 double double_next2 = Double(double_next).NextDouble();
569 f4 = SanitizedDoubletof(double_next2);
570 }
571 (void) f2; // Mark variable as used.
572 DOUBLE_CONVERSION_ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
573
574 // If the guess doesn't lie near a single-precision boundary we can simply
575 // return its float-value.
576 if (f1 == f4) {
577 return float_guess;
578 }
579
580 DOUBLE_CONVERSION_ASSERT((f1 != f2 && f2 == f3 && f3 == f4) ||
581 (f1 == f2 && f2 != f3 && f3 == f4) ||
582 (f1 == f2 && f2 == f3 && f3 != f4));
583
584 // guess and next are the two possible candidates (in the same way that
585 // double_guess was the lower candidate for a double-precision guess).
586 float guess = f1;
587 float next = f4;
588 DiyFp upper_boundary;
589 if (guess == 0.0f) {
590 float min_float = 1e-45f;
591 upper_boundary = Double(static_cast<double>(min_float) / 2).AsDiyFp();
592 } else {
593 upper_boundary = Single(guess).UpperBoundary();
594 }
595 int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
596 if (comparison < 0) {
597 return guess;
598 } else if (comparison > 0) {
599 return next;
600 } else if ((Single(guess).Significand() & 1) == 0) {
601 // Round towards even.
602 return guess;
603 } else {
604 return next;
605 }
606}
static float next(float f)
static float SanitizedDoubletof(double d)
Definition: strtod.cc:497

◆ TrimAndCut()

static void double_conversion::TrimAndCut ( Vector< const char >  buffer,
int  exponent,
char *  buffer_copy_space,
int  space_size,
Vector< const char > *  trimmed,
int updated_exponent 
)
static

Definition at line 126 of file strtod.cc.

128 {
130 Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
131 exponent += left_trimmed.length() - right_trimmed.length();
132 if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
133 (void) space_size; // Mark variable as used.
135 CutToMaxSignificantDigits(right_trimmed, exponent,
136 buffer_copy_space, updated_exponent);
137 *trimmed = Vector<const char>(buffer_copy_space,
139 } else {
140 *trimmed = right_trimmed;
141 *updated_exponent = exponent;
142 }
143}
static void CutToMaxSignificantDigits(Vector< const char > buffer, int exponent, char *significant_buffer, int *significant_exponent)
Definition: strtod.cc:104
static Vector< const char > TrimLeadingZeros(Vector< const char > buffer)
Definition: strtod.cc:95
Vector< const char > TrimTrailingZeros(Vector< const char > buffer)
Definition: strtod.h:53

◆ TrimLeadingZeros()

static Vector< const char > double_conversion::TrimLeadingZeros ( Vector< const char >  buffer)
static

Definition at line 95 of file strtod.cc.

95 {
96 for (int i = 0; i < buffer.length(); i++) {
97 if (buffer[i] != '0') {
98 return buffer.SubVector(i, buffer.length());
99 }
100 }
101 return Vector<const char>(buffer.start(), 0);
102}

◆ TrimTrailingZeros()

Vector< const char > double_conversion::TrimTrailingZeros ( Vector< const char >  buffer)
inline

Definition at line 53 of file strtod.h.

53 {
54 for (int i = buffer.length() - 1; i >= 0; --i) {
55 if (buffer[i] != '0') {
56 return buffer.SubVector(0, i + 1);
57 }
58 }
59 return Vector<const char>(buffer.start(), 0);
60}

◆ TrimZeros()

static void double_conversion::TrimZeros ( Vector< char >  buffer,
int length,
int decimal_point 
)
static

Definition at line 292 of file fixed-dtoa.cc.

292 {
293 while (*length > 0 && buffer[(*length) - 1] == '0') {
294 (*length)--;
295 }
296 int first_non_zero = 0;
297 while (first_non_zero < *length && buffer[first_non_zero] == '0') {
298 first_non_zero++;
299 }
300 if (first_non_zero != 0) {
301 for (int i = first_non_zero; i < *length; ++i) {
302 buffer[i - first_non_zero] = buffer[i];
303 }
304 *length -= first_non_zero;
305 *decimal_point -= first_non_zero;
306 }
307}

◆ uint32_to_float()

static float double_conversion::uint32_to_float ( uint32_t  d32)
static

Definition at line 39 of file ieee.h.

39{ return BitCast<float>(d32); }

◆ uint64_to_double()

static double double_conversion::uint64_to_double ( uint64_t  d64)
static

Definition at line 37 of file ieee.h.

37{ return BitCast<double>(d64); }

Variable Documentation

◆ kDoubleSignificandSize

const int double_conversion::kDoubleSignificandSize = 53
static

Definition at line 117 of file fixed-dtoa.cc.

◆ kFastDtoaMaximalLength

const int double_conversion::kFastDtoaMaximalLength = 17
static

Definition at line 49 of file fast-dtoa.h.

◆ kFastDtoaMaximalSingleLength

const int double_conversion::kFastDtoaMaximalSingleLength = 9
static

Definition at line 51 of file fast-dtoa.h.

◆ kMaxDecimalPower

const int double_conversion::kMaxDecimalPower = 309
static

Definition at line 53 of file strtod.cc.

◆ kMaximalTargetExponent

const int double_conversion::kMaximalTargetExponent = -32
static

Definition at line 43 of file fast-dtoa.cc.

◆ kMaxSignificantDecimalDigits

const int double_conversion::kMaxSignificantDecimalDigits = 780
static

Definition at line 93 of file strtod.cc.

◆ kMaxSignificantDigits

const int double_conversion::kMaxSignificantDigits = 772

Definition at line 109 of file string-to-double.cc.

◆ kMaxUint64

const uint64_t double_conversion::kMaxUint64 = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF)
static

Definition at line 57 of file strtod.cc.

◆ kMaxUint64DecimalDigits

const int double_conversion::kMaxUint64DecimalDigits = 19
static

Definition at line 45 of file strtod.cc.

◆ kMinDecimalPower

const int double_conversion::kMinDecimalPower = -324
static

Definition at line 54 of file strtod.cc.

◆ kMinimalTargetExponent

const int double_conversion::kMinimalTargetExponent = -60
static

Definition at line 42 of file fast-dtoa.cc.

◆ kSmallPowersOfTen

unsigned int const double_conversion::kSmallPowersOfTen[]
static
Initial value:
=
{0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
1000000000}

Definition at line 236 of file fast-dtoa.cc.

◆ kWhitespaceTable16

const uc16 double_conversion::kWhitespaceTable16[]
static
Initial value:
= {
160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
}

Definition at line 116 of file string-to-double.cc.

◆ kWhitespaceTable16Length

const int double_conversion::kWhitespaceTable16Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable16)
static

Definition at line 120 of file string-to-double.cc.

◆ kWhitespaceTable7

const char double_conversion::kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 }
static

Definition at line 112 of file string-to-double.cc.

◆ kWhitespaceTable7Length

const int double_conversion::kWhitespaceTable7Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable7)
static

Definition at line 113 of file string-to-double.cc.