9 #include "src/base/logging.h" 10 #include "src/utils.h" 12 #include "src/double.h" 13 #include "src/fixed-dtoa.h" 22 UInt128() : high_bits_(0), low_bits_(0) { }
23 UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { }
25 void Multiply(
uint32_t multiplicand) {
28 accumulator = (low_bits_ & kMask32) * multiplicand;
31 accumulator = accumulator + (low_bits_ >> 32) * multiplicand;
32 low_bits_ = (accumulator << 32) + part;
34 accumulator = accumulator + (high_bits_ & kMask32) * multiplicand;
35 part =
static_cast<uint32_t>(accumulator & kMask32);
37 accumulator = accumulator + (high_bits_ >> 32) * multiplicand;
38 high_bits_ = (accumulator << 32) + part;
39 DCHECK_EQ(accumulator >> 32, 0);
42 void Shift(
int shift_amount) {
43 DCHECK(-64 <= shift_amount && shift_amount <= 64);
44 if (shift_amount == 0) {
46 }
else if (shift_amount == -64) {
47 high_bits_ = low_bits_;
49 }
else if (shift_amount == 64) {
50 low_bits_ = high_bits_;
52 }
else if (shift_amount <= 0) {
53 high_bits_ <<= -shift_amount;
54 high_bits_ += low_bits_ >> (64 + shift_amount);
55 low_bits_ <<= -shift_amount;
57 low_bits_ >>= shift_amount;
58 low_bits_ += high_bits_ << (64 - shift_amount);
59 high_bits_ >>= shift_amount;
65 int DivModPowerOf2(
int power) {
67 int result =
static_cast<int>(high_bits_ >> (power - 64));
68 high_bits_ -=
static_cast<uint64_t
>(result) << (power - 64);
71 uint64_t part_low = low_bits_ >> power;
72 uint64_t part_high = high_bits_ << (64 - power);
73 int result =
static_cast<int>(part_low + part_high);
75 low_bits_ -= part_low << power;
81 return high_bits_ == 0 && low_bits_ == 0;
84 int BitAt(
int position) {
86 return static_cast<int>(high_bits_ >> (position - 64)) & 1;
88 return static_cast<int>(low_bits_ >> position) & 1;
93 static const uint64_t kMask32 = 0xFFFFFFFF;
100 static const int kDoubleSignificandSize = 53;
103 static void FillDigits32FixedLength(
uint32_t number,
int requested_length,
105 for (
int i = requested_length - 1;
i >= 0; --
i) {
106 buffer[(*length) +
i] =
'0' + number % 10;
109 *length += requested_length;
113 static void FillDigits32(
uint32_t number, Vector<char> buffer,
int* length) {
114 int number_length = 0;
116 while (number != 0) {
117 int digit = number % 10;
119 buffer[(*length) + number_length] =
'0' + digit;
124 int j = *length + number_length - 1;
126 char tmp = buffer[
i];
127 buffer[
i] = buffer[j];
132 *length += number_length;
136 static void FillDigits64FixedLength(uint64_t number,
int requested_length,
137 Vector<char> buffer,
int* length) {
145 FillDigits32FixedLength(part0, 3, buffer, length);
146 FillDigits32FixedLength(part1, 7, buffer, length);
147 FillDigits32FixedLength(part2, 7, buffer, length);
151 static void FillDigits64(uint64_t number, Vector<char> buffer,
int* length) {
160 FillDigits32(part0, buffer, length);
161 FillDigits32FixedLength(part1, 7, buffer, length);
162 FillDigits32FixedLength(part2, 7, buffer, length);
163 }
else if (part1 != 0) {
164 FillDigits32(part1, buffer, length);
165 FillDigits32FixedLength(part2, 7, buffer, length);
167 FillDigits32(part2, buffer, length);
171 static void DtoaRoundUp(Vector<char> buffer,
int* length,
int* decimal_point) {
181 buffer[(*length) - 1]++;
182 for (
int i = (*length) - 1;
i > 0; --
i) {
183 if (buffer[
i] !=
'0' + 10) {
194 if (buffer[0] ==
'0' + 10) {
212 static void FillFractionals(uint64_t fractionals,
int exponent,
213 int fractional_count, Vector<char> buffer,
214 int* length,
int* decimal_point) {
215 DCHECK(-128 <= exponent && exponent <= 0);
219 if (-exponent <= 64) {
221 DCHECK_EQ(fractionals >> 56, 0);
222 int point = -exponent;
223 for (
int i = 0;
i < fractional_count; ++
i) {
224 if (fractionals == 0)
break;
237 int digit =
static_cast<int>(fractionals >> point);
238 buffer[*length] =
'0' + digit;
240 fractionals -=
static_cast<uint64_t
>(digit) << point;
243 if (((fractionals >> (point - 1)) & 1) == 1) {
244 DtoaRoundUp(buffer, length, decimal_point);
247 DCHECK(64 < -exponent && -exponent <= 128);
248 UInt128 fractionals128 = UInt128(fractionals, 0);
249 fractionals128.Shift(-exponent - 64);
251 for (
int i = 0;
i < fractional_count; ++
i) {
252 if (fractionals128.IsZero())
break;
256 fractionals128.Multiply(5);
258 int digit = fractionals128.DivModPowerOf2(point);
259 buffer[*length] =
'0' + digit;
262 if (fractionals128.BitAt(point - 1) == 1) {
263 DtoaRoundUp(buffer, length, decimal_point);
271 static void TrimZeros(Vector<char> buffer,
int* length,
int* decimal_point) {
272 while (*length > 0 && buffer[(*length) - 1] ==
'0') {
275 int first_non_zero = 0;
276 while (first_non_zero < *length && buffer[first_non_zero] ==
'0') {
279 if (first_non_zero != 0) {
280 for (
int i = first_non_zero;
i < *length; ++
i) {
281 buffer[
i - first_non_zero] = buffer[
i];
283 *length -= first_non_zero;
284 *decimal_point -= first_non_zero;
289 bool FastFixedDtoa(
double v,
290 int fractional_count,
293 int* decimal_point) {
294 const uint32_t kMaxUInt32 = 0xFFFFFFFF;
295 uint64_t significand = Double(v).Significand();
296 int exponent = Double(v).Exponent();
302 if (exponent > 20)
return false;
303 if (fractional_count > 20)
return false;
308 if (exponent + kDoubleSignificandSize > 64) {
317 const uint64_t kFive17 = V8_2PART_UINT64_C(0xB1, A2BC2EC5);
318 uint64_t divisor = kFive17;
319 int divisor_power = 17;
320 uint64_t dividend = significand;
332 if (exponent > divisor_power) {
334 dividend <<= exponent - divisor_power;
335 quotient =
static_cast<uint32_t>(dividend / divisor);
336 remainder = (dividend % divisor) << divisor_power;
338 divisor <<= divisor_power - exponent;
339 quotient =
static_cast<uint32_t>(dividend / divisor);
340 remainder = (dividend % divisor) << exponent;
342 FillDigits32(quotient, buffer, length);
343 FillDigits64FixedLength(remainder, divisor_power, buffer, length);
344 *decimal_point = *length;
345 }
else if (exponent >= 0) {
347 significand <<= exponent;
348 FillDigits64(significand, buffer, length);
349 *decimal_point = *length;
350 }
else if (exponent > -kDoubleSignificandSize) {
352 uint64_t integrals = significand >> -exponent;
353 uint64_t fractionals = significand - (integrals << -exponent);
354 if (integrals > kMaxUInt32) {
355 FillDigits64(integrals, buffer, length);
357 FillDigits32(static_cast<uint32_t>(integrals), buffer, length);
359 *decimal_point = *length;
360 FillFractionals(fractionals, exponent, fractional_count,
361 buffer, length, decimal_point);
362 }
else if (exponent < -128) {
365 DCHECK_LE(fractional_count, 20);
368 *decimal_point = -fractional_count;
371 FillFractionals(significand, exponent, fractional_count,
372 buffer, length, decimal_point);
374 TrimZeros(buffer, length, decimal_point);
375 buffer[*length] =
'\0';
376 if ((*length) == 0) {
379 *decimal_point = -fractional_count;