| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "include/v8stdint.h" | 5 #include "include/v8stdint.h" |
| 6 #include "src/base/logging.h" | 6 #include "src/base/logging.h" |
| 7 #include "src/utils.h" | 7 #include "src/utils.h" |
| 8 | 8 |
| 9 #include "src/fast-dtoa.h" | 9 #include "src/fast-dtoa.h" |
| 10 | 10 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 // There are 3 conditions that stop the decrementation process: | 113 // There are 3 conditions that stop the decrementation process: |
| 114 // 1) the buffer is already below w_high | 114 // 1) the buffer is already below w_high |
| 115 // 2) decrementing the buffer would make it leave the unsafe interval | 115 // 2) decrementing the buffer would make it leave the unsafe interval |
| 116 // 3) decrementing the buffer would yield a number below w_high and farther | 116 // 3) decrementing the buffer would yield a number below w_high and farther |
| 117 // away than the current number. In other words: | 117 // away than the current number. In other words: |
| 118 // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high | 118 // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high |
| 119 // Instead of using the buffer directly we use its distance to too_high. | 119 // Instead of using the buffer directly we use its distance to too_high. |
| 120 // Conceptually rest ~= too_high - buffer | 120 // Conceptually rest ~= too_high - buffer |
| 121 // We need to do the following tests in this order to avoid over- and | 121 // We need to do the following tests in this order to avoid over- and |
| 122 // underflows. | 122 // underflows. |
| 123 ASSERT(rest <= unsafe_interval); | 123 DCHECK(rest <= unsafe_interval); |
| 124 while (rest < small_distance && // Negated condition 1 | 124 while (rest < small_distance && // Negated condition 1 |
| 125 unsafe_interval - rest >= ten_kappa && // Negated condition 2 | 125 unsafe_interval - rest >= ten_kappa && // Negated condition 2 |
| 126 (rest + ten_kappa < small_distance || // buffer{-1} > w_high | 126 (rest + ten_kappa < small_distance || // buffer{-1} > w_high |
| 127 small_distance - rest >= rest + ten_kappa - small_distance)) { | 127 small_distance - rest >= rest + ten_kappa - small_distance)) { |
| 128 buffer[length - 1]--; | 128 buffer[length - 1]--; |
| 129 rest += ten_kappa; | 129 rest += ten_kappa; |
| 130 } | 130 } |
| 131 | 131 |
| 132 // We have approached w+ as much as possible. We now test if approaching w- | 132 // We have approached w+ as much as possible. We now test if approaching w- |
| 133 // would require changing the buffer. If yes, then we have two possible | 133 // would require changing the buffer. If yes, then we have two possible |
| (...skipping 25 matching lines...) Expand all Loading... |
| 159 // imprecision and returns false, if the rounding direction cannot be | 159 // imprecision and returns false, if the rounding direction cannot be |
| 160 // unambiguously determined. | 160 // unambiguously determined. |
| 161 // | 161 // |
| 162 // Precondition: rest < ten_kappa. | 162 // Precondition: rest < ten_kappa. |
| 163 static bool RoundWeedCounted(Vector<char> buffer, | 163 static bool RoundWeedCounted(Vector<char> buffer, |
| 164 int length, | 164 int length, |
| 165 uint64_t rest, | 165 uint64_t rest, |
| 166 uint64_t ten_kappa, | 166 uint64_t ten_kappa, |
| 167 uint64_t unit, | 167 uint64_t unit, |
| 168 int* kappa) { | 168 int* kappa) { |
| 169 ASSERT(rest < ten_kappa); | 169 DCHECK(rest < ten_kappa); |
| 170 // The following tests are done in a specific order to avoid overflows. They | 170 // The following tests are done in a specific order to avoid overflows. They |
| 171 // will work correctly with any uint64 values of rest < ten_kappa and unit. | 171 // will work correctly with any uint64 values of rest < ten_kappa and unit. |
| 172 // | 172 // |
| 173 // If the unit is too big, then we don't know which way to round. For example | 173 // If the unit is too big, then we don't know which way to round. For example |
| 174 // a unit of 50 means that the real number lies within rest +/- 50. If | 174 // a unit of 50 means that the real number lies within rest +/- 50. If |
| 175 // 10^kappa == 40 then there is no way to tell which way to round. | 175 // 10^kappa == 40 then there is no way to tell which way to round. |
| 176 if (unit >= ten_kappa) return false; | 176 if (unit >= ten_kappa) return false; |
| 177 // Even if unit is just half the size of 10^kappa we are already completely | 177 // Even if unit is just half the size of 10^kappa we are already completely |
| 178 // lost. (And after the previous test we know that the expression will not | 178 // lost. (And after the previous test we know that the expression will not |
| 179 // over/underflow.) | 179 // over/underflow.) |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 // once we have enough digits. That is, once the digits inside the buffer | 358 // once we have enough digits. That is, once the digits inside the buffer |
| 359 // represent 'w' we can stop. Everything inside the interval low - high | 359 // represent 'w' we can stop. Everything inside the interval low - high |
| 360 // represents w. However we have to pay attention to low, high and w's | 360 // represents w. However we have to pay attention to low, high and w's |
| 361 // imprecision. | 361 // imprecision. |
| 362 static bool DigitGen(DiyFp low, | 362 static bool DigitGen(DiyFp low, |
| 363 DiyFp w, | 363 DiyFp w, |
| 364 DiyFp high, | 364 DiyFp high, |
| 365 Vector<char> buffer, | 365 Vector<char> buffer, |
| 366 int* length, | 366 int* length, |
| 367 int* kappa) { | 367 int* kappa) { |
| 368 ASSERT(low.e() == w.e() && w.e() == high.e()); | 368 DCHECK(low.e() == w.e() && w.e() == high.e()); |
| 369 ASSERT(low.f() + 1 <= high.f() - 1); | 369 DCHECK(low.f() + 1 <= high.f() - 1); |
| 370 ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent); | 370 DCHECK(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent); |
| 371 // low, w and high are imprecise, but by less than one ulp (unit in the last | 371 // low, w and high are imprecise, but by less than one ulp (unit in the last |
| 372 // place). | 372 // place). |
| 373 // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that | 373 // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that |
| 374 // the new numbers are outside of the interval we want the final | 374 // the new numbers are outside of the interval we want the final |
| 375 // representation to lie in. | 375 // representation to lie in. |
| 376 // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield | 376 // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield |
| 377 // numbers that are certain to lie in the interval. We will use this fact | 377 // numbers that are certain to lie in the interval. We will use this fact |
| 378 // later on. | 378 // later on. |
| 379 // We will now start by generating the digits within the uncertain | 379 // We will now start by generating the digits within the uncertain |
| 380 // interval. Later we will weed out representations that lie outside the safe | 380 // interval. Later we will weed out representations that lie outside the safe |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 } | 428 } |
| 429 divisor /= 10; | 429 divisor /= 10; |
| 430 } | 430 } |
| 431 | 431 |
| 432 // The integrals have been generated. We are at the point of the decimal | 432 // The integrals have been generated. We are at the point of the decimal |
| 433 // separator. In the following loop we simply multiply the remaining digits by | 433 // separator. In the following loop we simply multiply the remaining digits by |
| 434 // 10 and divide by one. We just need to pay attention to multiply associated | 434 // 10 and divide by one. We just need to pay attention to multiply associated |
| 435 // data (like the interval or 'unit'), too. | 435 // data (like the interval or 'unit'), too. |
| 436 // Note that the multiplication by 10 does not overflow, because w.e >= -60 | 436 // Note that the multiplication by 10 does not overflow, because w.e >= -60 |
| 437 // and thus one.e >= -60. | 437 // and thus one.e >= -60. |
| 438 ASSERT(one.e() >= -60); | 438 DCHECK(one.e() >= -60); |
| 439 ASSERT(fractionals < one.f()); | 439 DCHECK(fractionals < one.f()); |
| 440 ASSERT(V8_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); | 440 DCHECK(V8_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); |
| 441 while (true) { | 441 while (true) { |
| 442 fractionals *= 10; | 442 fractionals *= 10; |
| 443 unit *= 10; | 443 unit *= 10; |
| 444 unsafe_interval.set_f(unsafe_interval.f() * 10); | 444 unsafe_interval.set_f(unsafe_interval.f() * 10); |
| 445 // Integer division by one. | 445 // Integer division by one. |
| 446 int digit = static_cast<int>(fractionals >> -one.e()); | 446 int digit = static_cast<int>(fractionals >> -one.e()); |
| 447 buffer[*length] = '0' + digit; | 447 buffer[*length] = '0' + digit; |
| 448 (*length)++; | 448 (*length)++; |
| 449 fractionals &= one.f() - 1; // Modulo by one. | 449 fractionals &= one.f() - 1; // Modulo by one. |
| 450 (*kappa)--; | 450 (*kappa)--; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 // | 483 // |
| 484 // Remark: This procedure takes into account the imprecision of its input | 484 // Remark: This procedure takes into account the imprecision of its input |
| 485 // numbers. If the precision is not enough to guarantee all the postconditions | 485 // numbers. If the precision is not enough to guarantee all the postconditions |
| 486 // then false is returned. This usually happens rarely, but the failure-rate | 486 // then false is returned. This usually happens rarely, but the failure-rate |
| 487 // increases with higher requested_digits. | 487 // increases with higher requested_digits. |
| 488 static bool DigitGenCounted(DiyFp w, | 488 static bool DigitGenCounted(DiyFp w, |
| 489 int requested_digits, | 489 int requested_digits, |
| 490 Vector<char> buffer, | 490 Vector<char> buffer, |
| 491 int* length, | 491 int* length, |
| 492 int* kappa) { | 492 int* kappa) { |
| 493 ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent); | 493 DCHECK(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent); |
| 494 ASSERT(kMinimalTargetExponent >= -60); | 494 DCHECK(kMinimalTargetExponent >= -60); |
| 495 ASSERT(kMaximalTargetExponent <= -32); | 495 DCHECK(kMaximalTargetExponent <= -32); |
| 496 // w is assumed to have an error less than 1 unit. Whenever w is scaled we | 496 // w is assumed to have an error less than 1 unit. Whenever w is scaled we |
| 497 // also scale its error. | 497 // also scale its error. |
| 498 uint64_t w_error = 1; | 498 uint64_t w_error = 1; |
| 499 // We cut the input number into two parts: the integral digits and the | 499 // We cut the input number into two parts: the integral digits and the |
| 500 // fractional digits. We don't emit any decimal separator, but adapt kappa | 500 // fractional digits. We don't emit any decimal separator, but adapt kappa |
| 501 // instead. Example: instead of writing "1.2" we put "12" into the buffer and | 501 // instead. Example: instead of writing "1.2" we put "12" into the buffer and |
| 502 // increase kappa by 1. | 502 // increase kappa by 1. |
| 503 DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e()); | 503 DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e()); |
| 504 // Division by one is a shift. | 504 // Division by one is a shift. |
| 505 uint32_t integrals = static_cast<uint32_t>(w.f() >> -one.e()); | 505 uint32_t integrals = static_cast<uint32_t>(w.f() >> -one.e()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 536 static_cast<uint64_t>(divisor) << -one.e(), w_error, | 536 static_cast<uint64_t>(divisor) << -one.e(), w_error, |
| 537 kappa); | 537 kappa); |
| 538 } | 538 } |
| 539 | 539 |
| 540 // The integrals have been generated. We are at the point of the decimal | 540 // The integrals have been generated. We are at the point of the decimal |
| 541 // separator. In the following loop we simply multiply the remaining digits by | 541 // separator. In the following loop we simply multiply the remaining digits by |
| 542 // 10 and divide by one. We just need to pay attention to multiply associated | 542 // 10 and divide by one. We just need to pay attention to multiply associated |
| 543 // data (the 'unit'), too. | 543 // data (the 'unit'), too. |
| 544 // Note that the multiplication by 10 does not overflow, because w.e >= -60 | 544 // Note that the multiplication by 10 does not overflow, because w.e >= -60 |
| 545 // and thus one.e >= -60. | 545 // and thus one.e >= -60. |
| 546 ASSERT(one.e() >= -60); | 546 DCHECK(one.e() >= -60); |
| 547 ASSERT(fractionals < one.f()); | 547 DCHECK(fractionals < one.f()); |
| 548 ASSERT(V8_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); | 548 DCHECK(V8_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); |
| 549 while (requested_digits > 0 && fractionals > w_error) { | 549 while (requested_digits > 0 && fractionals > w_error) { |
| 550 fractionals *= 10; | 550 fractionals *= 10; |
| 551 w_error *= 10; | 551 w_error *= 10; |
| 552 // Integer division by one. | 552 // Integer division by one. |
| 553 int digit = static_cast<int>(fractionals >> -one.e()); | 553 int digit = static_cast<int>(fractionals >> -one.e()); |
| 554 buffer[*length] = '0' + digit; | 554 buffer[*length] = '0' + digit; |
| 555 (*length)++; | 555 (*length)++; |
| 556 requested_digits--; | 556 requested_digits--; |
| 557 fractionals &= one.f() - 1; // Modulo by one. | 557 fractionals &= one.f() - 1; // Modulo by one. |
| 558 (*kappa)--; | 558 (*kappa)--; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 578 Vector<char> buffer, | 578 Vector<char> buffer, |
| 579 int* length, | 579 int* length, |
| 580 int* decimal_exponent) { | 580 int* decimal_exponent) { |
| 581 DiyFp w = Double(v).AsNormalizedDiyFp(); | 581 DiyFp w = Double(v).AsNormalizedDiyFp(); |
| 582 // boundary_minus and boundary_plus are the boundaries between v and its | 582 // boundary_minus and boundary_plus are the boundaries between v and its |
| 583 // closest floating-point neighbors. Any number strictly between | 583 // closest floating-point neighbors. Any number strictly between |
| 584 // boundary_minus and boundary_plus will round to v when convert to a double. | 584 // boundary_minus and boundary_plus will round to v when convert to a double. |
| 585 // Grisu3 will never output representations that lie exactly on a boundary. | 585 // Grisu3 will never output representations that lie exactly on a boundary. |
| 586 DiyFp boundary_minus, boundary_plus; | 586 DiyFp boundary_minus, boundary_plus; |
| 587 Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus); | 587 Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus); |
| 588 ASSERT(boundary_plus.e() == w.e()); | 588 DCHECK(boundary_plus.e() == w.e()); |
| 589 DiyFp ten_mk; // Cached power of ten: 10^-k | 589 DiyFp ten_mk; // Cached power of ten: 10^-k |
| 590 int mk; // -k | 590 int mk; // -k |
| 591 int ten_mk_minimal_binary_exponent = | 591 int ten_mk_minimal_binary_exponent = |
| 592 kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize); | 592 kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize); |
| 593 int ten_mk_maximal_binary_exponent = | 593 int ten_mk_maximal_binary_exponent = |
| 594 kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize); | 594 kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize); |
| 595 PowersOfTenCache::GetCachedPowerForBinaryExponentRange( | 595 PowersOfTenCache::GetCachedPowerForBinaryExponentRange( |
| 596 ten_mk_minimal_binary_exponent, | 596 ten_mk_minimal_binary_exponent, |
| 597 ten_mk_maximal_binary_exponent, | 597 ten_mk_maximal_binary_exponent, |
| 598 &ten_mk, &mk); | 598 &ten_mk, &mk); |
| 599 ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() + | 599 DCHECK((kMinimalTargetExponent <= w.e() + ten_mk.e() + |
| 600 DiyFp::kSignificandSize) && | 600 DiyFp::kSignificandSize) && |
| 601 (kMaximalTargetExponent >= w.e() + ten_mk.e() + | 601 (kMaximalTargetExponent >= w.e() + ten_mk.e() + |
| 602 DiyFp::kSignificandSize)); | 602 DiyFp::kSignificandSize)); |
| 603 // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a | 603 // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a |
| 604 // 64 bit significand and ten_mk is thus only precise up to 64 bits. | 604 // 64 bit significand and ten_mk is thus only precise up to 64 bits. |
| 605 | 605 |
| 606 // The DiyFp::Times procedure rounds its result, and ten_mk is approximated | 606 // The DiyFp::Times procedure rounds its result, and ten_mk is approximated |
| 607 // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now | 607 // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now |
| 608 // off by a small amount. | 608 // off by a small amount. |
| 609 // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. | 609 // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. |
| 610 // In other words: let f = scaled_w.f() and e = scaled_w.e(), then | 610 // In other words: let f = scaled_w.f() and e = scaled_w.e(), then |
| 611 // (f-1) * 2^e < w*10^k < (f+1) * 2^e | 611 // (f-1) * 2^e < w*10^k < (f+1) * 2^e |
| 612 DiyFp scaled_w = DiyFp::Times(w, ten_mk); | 612 DiyFp scaled_w = DiyFp::Times(w, ten_mk); |
| 613 ASSERT(scaled_w.e() == | 613 DCHECK(scaled_w.e() == |
| 614 boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize); | 614 boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize); |
| 615 // In theory it would be possible to avoid some recomputations by computing | 615 // In theory it would be possible to avoid some recomputations by computing |
| 616 // the difference between w and boundary_minus/plus (a power of 2) and to | 616 // the difference between w and boundary_minus/plus (a power of 2) and to |
| 617 // compute scaled_boundary_minus/plus by subtracting/adding from | 617 // compute scaled_boundary_minus/plus by subtracting/adding from |
| 618 // scaled_w. However the code becomes much less readable and the speed | 618 // scaled_w. However the code becomes much less readable and the speed |
| 619 // enhancements are not terriffic. | 619 // enhancements are not terriffic. |
| 620 DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk); | 620 DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk); |
| 621 DiyFp scaled_boundary_plus = DiyFp::Times(boundary_plus, ten_mk); | 621 DiyFp scaled_boundary_plus = DiyFp::Times(boundary_plus, ten_mk); |
| 622 | 622 |
| 623 // DigitGen will generate the digits of scaled_w. Therefore we have | 623 // DigitGen will generate the digits of scaled_w. Therefore we have |
| (...skipping 24 matching lines...) Expand all Loading... |
| 648 DiyFp ten_mk; // Cached power of ten: 10^-k | 648 DiyFp ten_mk; // Cached power of ten: 10^-k |
| 649 int mk; // -k | 649 int mk; // -k |
| 650 int ten_mk_minimal_binary_exponent = | 650 int ten_mk_minimal_binary_exponent = |
| 651 kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize); | 651 kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize); |
| 652 int ten_mk_maximal_binary_exponent = | 652 int ten_mk_maximal_binary_exponent = |
| 653 kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize); | 653 kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize); |
| 654 PowersOfTenCache::GetCachedPowerForBinaryExponentRange( | 654 PowersOfTenCache::GetCachedPowerForBinaryExponentRange( |
| 655 ten_mk_minimal_binary_exponent, | 655 ten_mk_minimal_binary_exponent, |
| 656 ten_mk_maximal_binary_exponent, | 656 ten_mk_maximal_binary_exponent, |
| 657 &ten_mk, &mk); | 657 &ten_mk, &mk); |
| 658 ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() + | 658 DCHECK((kMinimalTargetExponent <= w.e() + ten_mk.e() + |
| 659 DiyFp::kSignificandSize) && | 659 DiyFp::kSignificandSize) && |
| 660 (kMaximalTargetExponent >= w.e() + ten_mk.e() + | 660 (kMaximalTargetExponent >= w.e() + ten_mk.e() + |
| 661 DiyFp::kSignificandSize)); | 661 DiyFp::kSignificandSize)); |
| 662 // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a | 662 // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a |
| 663 // 64 bit significand and ten_mk is thus only precise up to 64 bits. | 663 // 64 bit significand and ten_mk is thus only precise up to 64 bits. |
| 664 | 664 |
| 665 // The DiyFp::Times procedure rounds its result, and ten_mk is approximated | 665 // The DiyFp::Times procedure rounds its result, and ten_mk is approximated |
| 666 // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now | 666 // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now |
| 667 // off by a small amount. | 667 // off by a small amount. |
| 668 // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. | 668 // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 682 return result; | 682 return result; |
| 683 } | 683 } |
| 684 | 684 |
| 685 | 685 |
| 686 bool FastDtoa(double v, | 686 bool FastDtoa(double v, |
| 687 FastDtoaMode mode, | 687 FastDtoaMode mode, |
| 688 int requested_digits, | 688 int requested_digits, |
| 689 Vector<char> buffer, | 689 Vector<char> buffer, |
| 690 int* length, | 690 int* length, |
| 691 int* decimal_point) { | 691 int* decimal_point) { |
| 692 ASSERT(v > 0); | 692 DCHECK(v > 0); |
| 693 ASSERT(!Double(v).IsSpecial()); | 693 DCHECK(!Double(v).IsSpecial()); |
| 694 | 694 |
| 695 bool result = false; | 695 bool result = false; |
| 696 int decimal_exponent = 0; | 696 int decimal_exponent = 0; |
| 697 switch (mode) { | 697 switch (mode) { |
| 698 case FAST_DTOA_SHORTEST: | 698 case FAST_DTOA_SHORTEST: |
| 699 result = Grisu3(v, buffer, length, &decimal_exponent); | 699 result = Grisu3(v, buffer, length, &decimal_exponent); |
| 700 break; | 700 break; |
| 701 case FAST_DTOA_PRECISION: | 701 case FAST_DTOA_PRECISION: |
| 702 result = Grisu3Counted(v, requested_digits, | 702 result = Grisu3Counted(v, requested_digits, |
| 703 buffer, length, &decimal_exponent); | 703 buffer, length, &decimal_exponent); |
| 704 break; | 704 break; |
| 705 default: | 705 default: |
| 706 UNREACHABLE(); | 706 UNREACHABLE(); |
| 707 } | 707 } |
| 708 if (result) { | 708 if (result) { |
| 709 *decimal_point = *length + decimal_exponent; | 709 *decimal_point = *length + decimal_exponent; |
| 710 buffer[*length] = '\0'; | 710 buffer[*length] = '\0'; |
| 711 } | 711 } |
| 712 return result; | 712 return result; |
| 713 } | 713 } |
| 714 | 714 |
| 715 } } // namespace v8::internal | 715 } } // namespace v8::internal |
| OLD | NEW |