28 #include "../include/v8stdint.h"
47 static const int kMinimalTargetExponent = -60;
48 static const int kMaximalTargetExponent = -32;
66 static bool RoundWeed(Vector<char> buffer,
68 uint64_t distance_too_high_w,
69 uint64_t unsafe_interval,
73 uint64_t small_distance = distance_too_high_w - unit;
74 uint64_t big_distance = distance_too_high_w + unit;
146 ASSERT(rest <= unsafe_interval);
147 while (rest < small_distance &&
148 unsafe_interval - rest >= ten_kappa &&
149 (rest + ten_kappa < small_distance ||
150 small_distance - rest >= rest + ten_kappa - small_distance)) {
151 buffer[length - 1]--;
158 if (rest < big_distance &&
159 unsafe_interval - rest >= ten_kappa &&
160 (rest + ten_kappa < big_distance ||
161 big_distance - rest > rest + ten_kappa - big_distance)) {
170 return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit);
186 static bool RoundWeedCounted(Vector<char> buffer,
199 if (unit >= ten_kappa)
return false;
203 if (ten_kappa - unit <= unit)
return false;
205 if ((ten_kappa - rest > rest) && (ten_kappa - 2 * rest >= 2 * unit)) {
209 if ((rest > unit) && (ten_kappa - (rest - unit) <= (rest - unit))) {
211 buffer[length - 1]++;
212 for (
int i = length - 1; i > 0; --i) {
213 if (buffer[i] !=
'0' + 10)
break;
221 if (buffer[0] ==
'0' + 10) {
231 static const uint32_t kTen4 = 10000;
232 static const uint32_t kTen5 = 100000;
233 static const uint32_t kTen6 = 1000000;
234 static const uint32_t kTen7 = 10000000;
235 static const uint32_t kTen8 = 100000000;
236 static const uint32_t kTen9 = 1000000000;
243 static void BiggestPowerTen(uint32_t number,
247 switch (number_bits) {
251 if (kTen9 <= number) {
259 if (kTen8 <= number) {
267 if (kTen7 <= number) {
276 if (kTen6 <= number) {
284 if (kTen5 <= number) {
292 if (kTen4 <= number) {
301 if (1000 <= number) {
385 static bool DigitGen(DiyFp low,
391 ASSERT(low.e() == w.e() && w.e() == high.e());
392 ASSERT(low.f() + 1 <= high.f() - 1);
393 ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
406 DiyFp too_low = DiyFp(low.f() - unit, low.e());
407 DiyFp too_high = DiyFp(high.f() + unit, high.e());
410 DiyFp unsafe_interval =
DiyFp::Minus(too_high, too_low);
418 DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
420 uint32_t integrals =
static_cast<uint32_t
>(too_high.f() >> -one.e());
422 uint64_t fractionals = too_high.f() & (one.f() - 1);
424 int divisor_exponent;
426 &divisor, &divisor_exponent);
427 *kappa = divisor_exponent + 1;
434 int digit = integrals / divisor;
435 buffer[*length] =
'0' + digit;
437 integrals %= divisor;
442 (
static_cast<uint64_t
>(integrals) << -one.e()) + fractionals;
445 if (rest < unsafe_interval.f()) {
448 return RoundWeed(buffer, *length,
DiyFp::Minus(too_high, w).f(),
449 unsafe_interval.
f(), rest,
450 static_cast<uint64_t
>(divisor) << -one.e(), unit);
462 ASSERT(fractionals < one.f());
467 unsafe_interval.set_f(unsafe_interval.f() * 10);
469 int digit =
static_cast<int>(fractionals >> -one.e());
470 buffer[*length] =
'0' + digit;
472 fractionals &= one.f() - 1;
474 if (fractionals < unsafe_interval.f()) {
475 return RoundWeed(buffer, *length,
DiyFp::Minus(too_high, w).f() * unit,
476 unsafe_interval.
f(), fractionals, one.f(), unit);
511 static bool DigitGenCounted(DiyFp w,
512 int requested_digits,
516 ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
517 ASSERT(kMinimalTargetExponent >= -60);
518 ASSERT(kMaximalTargetExponent <= -32);
521 uint64_t w_error = 1;
526 DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
528 uint32_t integrals =
static_cast<uint32_t
>(w.f() >> -one.e());
530 uint64_t fractionals = w.f() & (one.f() - 1);
532 int divisor_exponent;
534 &divisor, &divisor_exponent);
535 *kappa = divisor_exponent + 1;
543 int digit = integrals / divisor;
544 buffer[*length] =
'0' + digit;
547 integrals %= divisor;
551 if (requested_digits == 0)
break;
555 if (requested_digits == 0) {
557 (
static_cast<uint64_t
>(integrals) << -one.e()) + fractionals;
558 return RoundWeedCounted(buffer, *length, rest,
559 static_cast<uint64_t>(divisor) << -one.e(), w_error,
570 ASSERT(fractionals < one.f());
572 while (requested_digits > 0 && fractionals > w_error) {
576 int digit =
static_cast<int>(fractionals >> -one.e());
577 buffer[*length] =
'0' + digit;
580 fractionals &= one.f() - 1;
583 if (requested_digits != 0)
return false;
584 return RoundWeedCounted(buffer, *length, fractionals, one.f(), w_error,
600 static bool Grisu3(
double v,
603 int* decimal_exponent) {
604 DiyFp w = Double(v).AsNormalizedDiyFp();
609 DiyFp boundary_minus, boundary_plus;
610 Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
611 ASSERT(boundary_plus.e() == w.e());
614 int ten_mk_minimal_binary_exponent =
616 int ten_mk_maximal_binary_exponent =
619 ten_mk_minimal_binary_exponent,
620 ten_mk_maximal_binary_exponent,
622 ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
624 (kMaximalTargetExponent >= w.e() + ten_mk.e() +
643 DiyFp scaled_boundary_minus =
DiyFp::Times(boundary_minus, ten_mk);
644 DiyFp scaled_boundary_plus =
DiyFp::Times(boundary_plus, ten_mk);
653 bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
654 buffer, length, &kappa);
655 *decimal_exponent = -mk + kappa;
665 static bool Grisu3Counted(
double v,
666 int requested_digits,
669 int* decimal_exponent) {
670 DiyFp w = Double(v).AsNormalizedDiyFp();
673 int ten_mk_minimal_binary_exponent =
675 int ten_mk_maximal_binary_exponent =
678 ten_mk_minimal_binary_exponent,
679 ten_mk_maximal_binary_exponent,
681 ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
683 (kMaximalTargetExponent >= w.e() + ten_mk.e() +
702 bool result = DigitGenCounted(scaled_w, requested_digits,
703 buffer, length, &kappa);
704 *decimal_exponent = -mk + kappa;
711 int requested_digits,
714 int* decimal_point) {
719 int decimal_exponent = 0;
722 result = Grisu3(v, buffer, length, &decimal_exponent);
725 result = Grisu3Counted(v, requested_digits,
726 buffer, length, &decimal_exponent);
732 *decimal_point = *length + decimal_exponent;
733 buffer[*length] =
'\0';
static DiyFp Minus(const DiyFp &a, const DiyFp &b)
static const int kSignificandSize
#define ASSERT(condition)
bool FastDtoa(double v, FastDtoaMode mode, int requested_digits, Vector< char > buffer, int *length, int *decimal_point)
#define V8_2PART_UINT64_C(a, b)
static DiyFp Times(const DiyFp &a, const DiyFp &b)
static void GetCachedPowerForBinaryExponentRange(int min_exponent, int max_exponent, DiyFp *power, int *decimal_exponent)