30 #include "../include/v8stdint.h"
42 static int NormalizedExponent(uint64_t significand,
int exponent) {
45 significand = significand << 1;
46 exponent = exponent - 1;
54 static int EstimatePower(
int exponent);
57 static void InitialScaledStartValues(
double v,
59 bool need_boundary_deltas,
69 static void FixupMultiply10(
int estimated_power,
bool is_even,
71 Bignum* numerator, Bignum* denominator,
72 Bignum* delta_minus, Bignum* delta_plus);
75 static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
76 Bignum* delta_minus, Bignum* delta_plus,
78 Vector<char> buffer,
int* length);
80 static void BignumToFixed(
int requested_digits,
int* decimal_point,
81 Bignum* numerator, Bignum* denominator,
82 Vector<char>(buffer),
int* length);
87 static void GenerateCountedDigits(
int count,
int* decimal_point,
88 Bignum* numerator, Bignum* denominator,
89 Vector<char>(buffer),
int* length);
97 bool is_even = (significand & 1) == 0;
99 int normalized_exponent = NormalizedExponent(significand, exponent);
101 int estimated_power = EstimatePower(normalized_exponent);
113 *decimal_point = -requested_digits;
127 InitialScaledStartValues(v, estimated_power, need_boundary_deltas,
128 &numerator, &denominator,
129 &delta_minus, &delta_plus);
131 FixupMultiply10(estimated_power, is_even, decimal_point,
132 &numerator, &denominator,
133 &delta_minus, &delta_plus);
138 GenerateShortestDigits(&numerator, &denominator,
139 &delta_minus, &delta_plus,
140 is_even, buffer, length);
143 BignumToFixed(requested_digits, decimal_point,
144 &numerator, &denominator,
148 GenerateCountedDigits(requested_digits, decimal_point,
149 &numerator, &denominator,
155 buffer[*length] =
'\0';
172 static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
173 Bignum* delta_minus, Bignum* delta_plus,
175 Vector<char> buffer,
int* length) {
179 delta_plus = delta_minus;
184 digit = numerator->DivideModuloIntBignum(*denominator);
188 buffer[(*length)++] = digit +
'0';
195 bool in_delta_room_minus;
196 bool in_delta_room_plus;
200 in_delta_room_minus =
Bignum::Less(*numerator, *delta_minus);
209 if (!in_delta_room_minus && !in_delta_room_plus) {
211 numerator->Times10();
212 delta_minus->Times10();
216 if (delta_minus != delta_plus) {
217 delta_plus->Times10();
219 }
else if (in_delta_room_minus && in_delta_room_plus) {
225 }
else if (compare > 0) {
231 ASSERT(buffer[(*length) - 1] !=
'9');
232 buffer[(*length) - 1]++;
239 if ((buffer[(*length) - 1] -
'0') % 2 == 0) {
242 ASSERT(buffer[(*length) - 1] !=
'9');
243 buffer[(*length) - 1]++;
247 }
else if (in_delta_room_minus) {
256 ASSERT(buffer[(*length) -1] !=
'9');
257 buffer[(*length) - 1]++;
270 static void GenerateCountedDigits(
int count,
int* decimal_point,
271 Bignum* numerator, Bignum* denominator,
272 Vector<char>(buffer),
int* length) {
274 for (
int i = 0; i < count - 1; ++i) {
276 digit = numerator->DivideModuloIntBignum(*denominator);
280 buffer[i] = digit +
'0';
282 numerator->Times10();
286 digit = numerator->DivideModuloIntBignum(*denominator);
290 buffer[count - 1] = digit +
'0';
293 for (
int i = count - 1; i > 0; --i) {
294 if (buffer[i] !=
'0' + 10)
break;
298 if (buffer[0] ==
'0' + 10) {
312 static void BignumToFixed(
int requested_digits,
int* decimal_point,
313 Bignum* numerator, Bignum* denominator,
314 Vector<char>(buffer),
int* length) {
318 if (-(*decimal_point) > requested_digits) {
324 *decimal_point = -requested_digits;
327 }
else if (-(*decimal_point) == requested_digits) {
330 ASSERT(*decimal_point == -requested_digits);
333 denominator->Times10();
348 int needed_digits = (*decimal_point) + requested_digits;
349 GenerateCountedDigits(needed_digits, decimal_point,
350 numerator, denominator,
371 static int EstimatePower(
int exponent) {
393 const double k1Log10 = 0.30102999566398114;
396 const int kSignificandSize = 53;
397 double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
398 return static_cast<int>(estimate);
403 static void InitialScaledStartValuesPositiveExponent(
404 double v,
int estimated_power,
bool need_boundary_deltas,
405 Bignum* numerator, Bignum* denominator,
406 Bignum* delta_minus, Bignum* delta_plus) {
408 ASSERT(estimated_power >= 0);
413 numerator->AssignUInt64(Double(v).Significand());
414 numerator->ShiftLeft(Double(v).Exponent());
416 denominator->AssignPowerUInt16(10, estimated_power);
418 if (need_boundary_deltas) {
421 denominator->ShiftLeft(1);
422 numerator->ShiftLeft(1);
425 delta_plus->AssignUInt16(1);
426 delta_plus->ShiftLeft(Double(v).Exponent());
428 delta_minus->AssignUInt16(1);
429 delta_minus->ShiftLeft(Double(v).Exponent());
436 uint64_t v_bits = Double(v).AsUint64();
440 denominator->ShiftLeft(1);
441 numerator->ShiftLeft(1);
442 delta_plus->ShiftLeft(1);
449 static void InitialScaledStartValuesNegativeExponentPositivePower(
450 double v,
int estimated_power,
bool need_boundary_deltas,
451 Bignum* numerator, Bignum* denominator,
452 Bignum* delta_minus, Bignum* delta_plus) {
453 uint64_t significand = Double(v).Significand();
454 int exponent = Double(v).Exponent();
462 numerator->AssignUInt64(significand);
464 denominator->AssignPowerUInt16(10, estimated_power);
465 denominator->ShiftLeft(-exponent);
467 if (need_boundary_deltas) {
470 denominator->ShiftLeft(1);
471 numerator->ShiftLeft(1);
476 delta_plus->AssignUInt16(1);
478 delta_minus->AssignUInt16(1);
486 uint64_t v_bits = Double(v).AsUint64();
487 if ((v_bits & Double::kSignificandMask) == 0) {
490 denominator->ShiftLeft(1);
491 numerator->ShiftLeft(1);
492 delta_plus->ShiftLeft(1);
499 static void InitialScaledStartValuesNegativeExponentNegativePower(
500 double v,
int estimated_power,
bool need_boundary_deltas,
501 Bignum* numerator, Bignum* denominator,
502 Bignum* delta_minus, Bignum* delta_plus) {
503 const uint64_t kMinimalNormalizedExponent =
505 uint64_t significand = Double(v).Significand();
506 int exponent = Double(v).Exponent();
511 Bignum* power_ten = numerator;
512 power_ten->AssignPowerUInt16(10, -estimated_power);
514 if (need_boundary_deltas) {
518 delta_plus->AssignBignum(*power_ten);
519 delta_minus->AssignBignum(*power_ten);
527 ASSERT(numerator == power_ten);
528 numerator->MultiplyByUInt64(significand);
531 denominator->AssignUInt16(1);
532 denominator->ShiftLeft(-exponent);
534 if (need_boundary_deltas) {
537 numerator->ShiftLeft(1);
538 denominator->ShiftLeft(1);
546 uint64_t v_bits = Double(v).AsUint64();
547 if ((v_bits & Double::kSignificandMask) == 0 &&
551 numerator->ShiftLeft(1);
552 denominator->ShiftLeft(1);
553 delta_plus->ShiftLeft(1);
595 static void InitialScaledStartValues(
double v,
597 bool need_boundary_deltas,
601 Bignum* delta_plus) {
602 if (Double(v).Exponent() >= 0) {
603 InitialScaledStartValuesPositiveExponent(
604 v, estimated_power, need_boundary_deltas,
605 numerator, denominator, delta_minus, delta_plus);
606 }
else if (estimated_power >= 0) {
607 InitialScaledStartValuesNegativeExponentPositivePower(
608 v, estimated_power, need_boundary_deltas,
609 numerator, denominator, delta_minus, delta_plus);
611 InitialScaledStartValuesNegativeExponentNegativePower(
612 v, estimated_power, need_boundary_deltas,
613 numerator, denominator, delta_minus, delta_plus);
629 static void FixupMultiply10(
int estimated_power,
bool is_even,
631 Bignum* numerator, Bignum* denominator,
632 Bignum* delta_minus, Bignum* delta_plus) {
644 *decimal_point = estimated_power + 1;
646 *decimal_point = estimated_power;
647 numerator->Times10();
649 delta_minus->Times10();
650 delta_plus->AssignBignum(*delta_minus);
652 delta_minus->Times10();
653 delta_plus->Times10();
uint64_t Significand() const
static const uint64_t kExponentMask
static const uint64_t kHiddenBit
#define ASSERT(condition)
static int PlusCompare(const Bignum &a, const Bignum &b, const Bignum &c)
static bool Equal(const Bignum &a, const Bignum &b)
void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, Vector< char > buffer, int *length, int *decimal_point)
static bool Less(const Bignum &a, const Bignum &b)
#define V8_2PART_UINT64_C(a, b)
static const uint64_t kSignificandMask
static bool LessEqual(const Bignum &a, const Bignum &b)
static const int kMaxSignificantBits