Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

.

  • Loading branch information...
commit 9c7300bdd2c329a4fc1e166cf7aed1c36bcb06bb 2 parents ed472c9 + 62e41bb
@floitschG floitschG authored
Showing with 308,932 additions and 511 deletions.
  1. +7 −0 Makefile
  2. +11 −0 SConstruct
  3. +12 −0 src/SConscript
  4. +3 −5 src/bignum-dtoa.cc
  5. +7 −6 src/bignum-dtoa.h
  6. +3 −6 src/bignum.cc
  7. +8 −7 src/bignum.h
  8. +92 −92 src/cached-powers.cc
  9. +5 −6 src/cached-powers.h
  10. +4 −5 src/diy-fp.cc
  11. +9 −8 src/diy-fp.h
  12. +467 −298 src/double-conversion.cc
  13. +498 −0 src/double-conversion.h
  14. +23 −16 src/double.h
  15. +9 −10 src/fast-dtoa.cc
  16. +7 −6 src/fast-dtoa.h
  17. +4 −7 src/fixed-dtoa.cc
  18. +7 −6 src/fixed-dtoa.h
  19. +18 −17 src/strtod.cc
  20. +7 −6 src/strtod.h
  21. +69 −10 src/utils.h
  22. +16 −0 test/cctest/SConscript
  23. +122 −0 test/cctest/cctest.cc
  24. +141 −0 test/cctest/cctest.h
  25. +314 −0 test/cctest/checks.h
  26. +100,048 −0 test/cctest/gay-fixed.cc
  27. +46 −0 test/cctest/gay-fixed.h
  28. +100,049 −0 test/cctest/gay-precision.cc
  29. +46 −0 test/cctest/gay-precision.h
  30. +100,049 −0 test/cctest/gay-shortest.cc
  31. +43 −0 test/cctest/gay-shortest.h
  32. +313 −0 test/cctest/test-bignum-dtoa.cc
  33. +1,502 −0 test/cctest/test-bignum.cc
  34. +3,039 −0 test/cctest/test-conversions.cc
  35. +65 −0 test/cctest/test-diy-fp.cc
  36. +218 −0 test/cctest/test-double.cc
  37. +422 −0 test/cctest/test-dtoa.cc
  38. +266 −0 test/cctest/test-fast-dtoa.cc
  39. +511 −0 test/cctest/test-fixed-dtoa.cc
  40. +452 −0 test/cctest/test-strtod.cc
View
7 Makefile
@@ -0,0 +1,7 @@
+all:
+ scons debug=1
+
+test:
+ ./run_tests --list | tr -d '<' | xargs ./run_tests
+
+.PHONY: test all
View
11 SConstruct
@@ -0,0 +1,11 @@
+double_conversion_sources = ['src/' + x for x in SConscript('src/SConscript')]
+double_conversion_test_sources = ['test/cctest/' + x for x in SConscript('test/cctest/SConscript')]
+test = double_conversion_sources + double_conversion_test_sources
+print(test)
+env = Environment(CPPPATH='#/src')
+debug = ARGUMENTS.get('debug', 0)
+if int(debug):
+ env.Append(CCFLAGS = '-g')
+print double_conversion_sources
+print double_conversion_test_sources
+env.Program('run_tests', double_conversion_sources + double_conversion_test_sources)
View
12 src/SConscript
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+double_conversion_sources = [
+ 'bignum.cc',
+ 'bignum-dtoa.cc',
+ 'cached-powers.cc',
+ 'diy-fp.cc',
+ 'double-conversion.cc',
+ 'fast-dtoa.cc',
+ 'fixed-dtoa.cc',
+ 'strtod.cc'
+ ]
+Return('double_conversion_sources')
View
8 src/bignum-dtoa.cc
@@ -27,14 +27,12 @@
#include <math.h>
-#include "v8.h"
#include "bignum-dtoa.h"
#include "bignum.h"
#include "double.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
static int NormalizedExponent(uint64_t significand, int exponent) {
ASSERT(significand != 0);
@@ -498,7 +496,7 @@ static void InitialScaledStartValuesNegativeExponentNegativePower(
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
const uint64_t kMinimalNormalizedExponent =
- V8_2PART_UINT64_C(0x00100000, 00000000);
+ UINT64_2PART_C(0x00100000, 00000000);
uint64_t significand = Double(v).Significand();
int exponent = Double(v).Exponent();
// Instead of multiplying the denominator with 10^estimated_power we
@@ -652,4 +650,4 @@ static void FixupMultiply10(int estimated_power, bool is_even,
}
}
-} } // namespace v8::internal
+} // namespace double_conversion
View
13 src/bignum-dtoa.h
@@ -25,11 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef V8_BIGNUM_DTOA_H_
-#define V8_BIGNUM_DTOA_H_
+#ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_
+#define DOUBLE_CONVERSION_BIGNUM_DTOA_H_
-namespace v8 {
-namespace internal {
+#include "utils.h"
+
+namespace double_conversion {
enum BignumDtoaMode {
// Return the shortest correct representation.
@@ -76,6 +77,6 @@ enum BignumDtoaMode {
void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
Vector<char> buffer, int* length, int* point);
-} } // namespace v8::internal
+} // namespace double_conversion
-#endif // V8_BIGNUM_DTOA_H_
+#endif // DOUBLE_CONVERSION_BIGNUM_DTOA_H_
View
9 src/bignum.cc
@@ -25,13 +25,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "v8.h"
-
#include "bignum.h"
#include "utils.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
Bignum::Bignum()
: bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
@@ -301,7 +298,7 @@ void Bignum::MultiplyByUInt64(uint64_t factor) {
void Bignum::MultiplyByPowerOfTen(int exponent) {
- const uint64_t kFive27 = V8_2PART_UINT64_C(0x6765c793, fa10079d);
+ const uint64_t kFive27 = UINT64_2PART_C(0x6765c793, fa10079d);
const uint16_t kFive1 = 5;
const uint16_t kFive2 = kFive1 * 5;
const uint16_t kFive3 = kFive2 * 5;
@@ -764,4 +761,4 @@ void Bignum::SubtractTimes(const Bignum& other, int factor) {
}
-} } // namespace v8::internal
+} // namespace double_conversion
View
15 src/bignum.h
@@ -25,11 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef V8_BIGNUM_H_
-#define V8_BIGNUM_H_
+#ifndef DOUBLE_CONVERSION_BIGNUM_H_
+#define DOUBLE_CONVERSION_BIGNUM_H_
-namespace v8 {
-namespace internal {
+#include "utils.h"
+
+namespace double_conversion {
class Bignum {
public:
@@ -117,7 +118,7 @@ class Bignum {
void Zero();
// Requires this to have enough capacity (no tests done).
// Updates used_digits_ if necessary.
- // by must be < kBigitSize.
+ // shift_amount must be < kBigitSize.
void BigitsShiftLeft(int shift_amount);
// BigitLength includes the "hidden" digits encoded in the exponent.
int BigitLength() const { return used_digits_ + exponent_; }
@@ -135,6 +136,6 @@ class Bignum {
DISALLOW_COPY_AND_ASSIGN(Bignum);
};
-} } // namespace v8::internal
+} // namespace double_conversion
-#endif // V8_BIGNUM_H_
+#endif // DOUBLE_CONVERSION_BIGNUM_H_
View
184 src/cached-powers.cc
@@ -27,13 +27,13 @@
#include <stdarg.h>
#include <limits.h>
+#include <math.h>
-#include "v8.h"
+#include "utils.h"
#include "cached-powers.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
struct CachedPower {
uint64_t significand;
@@ -42,93 +42,93 @@ struct CachedPower {
};
static const CachedPower kCachedPowers[] = {
- {V8_2PART_UINT64_C(0xfa8fd5a0, 081c0288), -1220, -348},
- {V8_2PART_UINT64_C(0xbaaee17f, a23ebf76), -1193, -340},
- {V8_2PART_UINT64_C(0x8b16fb20, 3055ac76), -1166, -332},
- {V8_2PART_UINT64_C(0xcf42894a, 5dce35ea), -1140, -324},
- {V8_2PART_UINT64_C(0x9a6bb0aa, 55653b2d), -1113, -316},
- {V8_2PART_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
- {V8_2PART_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
- {V8_2PART_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
- {V8_2PART_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
- {V8_2PART_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
- {V8_2PART_UINT64_C(0xd3515c28, 31559a83), -954, -268},
- {V8_2PART_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
- {V8_2PART_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
- {V8_2PART_UINT64_C(0xaecc4991, 4078536d), -874, -244},
- {V8_2PART_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
- {V8_2PART_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
- {V8_2PART_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
- {V8_2PART_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
- {V8_2PART_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
- {V8_2PART_UINT64_C(0xef340a98, 172aace5), -715, -196},
- {V8_2PART_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
- {V8_2PART_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
- {V8_2PART_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
- {V8_2PART_UINT64_C(0x936b9fce, bb25c996), -608, -164},
- {V8_2PART_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
- {V8_2PART_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
- {V8_2PART_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
- {V8_2PART_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
- {V8_2PART_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
- {V8_2PART_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
- {V8_2PART_UINT64_C(0x964e858c, 91ba2655), -422, -108},
- {V8_2PART_UINT64_C(0xdff97724, 70297ebd), -396, -100},
- {V8_2PART_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
- {V8_2PART_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
- {V8_2PART_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
- {V8_2PART_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
- {V8_2PART_UINT64_C(0xcdb02555, 653131b6), -263, -60},
- {V8_2PART_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
- {V8_2PART_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
- {V8_2PART_UINT64_C(0xaa242499, 697392d3), -183, -36},
- {V8_2PART_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
- {V8_2PART_UINT64_C(0xbce50864, 92111aeb), -130, -20},
- {V8_2PART_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
- {V8_2PART_UINT64_C(0xd1b71758, e219652c), -77, -4},
- {V8_2PART_UINT64_C(0x9c400000, 00000000), -50, 4},
- {V8_2PART_UINT64_C(0xe8d4a510, 00000000), -24, 12},
- {V8_2PART_UINT64_C(0xad78ebc5, ac620000), 3, 20},
- {V8_2PART_UINT64_C(0x813f3978, f8940984), 30, 28},
- {V8_2PART_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
- {V8_2PART_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
- {V8_2PART_UINT64_C(0xd5d238a4, abe98068), 109, 52},
- {V8_2PART_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
- {V8_2PART_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
- {V8_2PART_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
- {V8_2PART_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
- {V8_2PART_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
- {V8_2PART_UINT64_C(0x924d692c, a61be758), 269, 100},
- {V8_2PART_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
- {V8_2PART_UINT64_C(0xa26da399, 9aef774a), 322, 116},
- {V8_2PART_UINT64_C(0xf209787b, b47d6b85), 348, 124},
- {V8_2PART_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
- {V8_2PART_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
- {V8_2PART_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
- {V8_2PART_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
- {V8_2PART_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
- {V8_2PART_UINT64_C(0xa59bc234, db398c25), 508, 172},
- {V8_2PART_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
- {V8_2PART_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
- {V8_2PART_UINT64_C(0x88fcf317, f22241e2), 588, 196},
- {V8_2PART_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
- {V8_2PART_UINT64_C(0x98165af3, 7b2153df), 641, 212},
- {V8_2PART_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
- {V8_2PART_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
- {V8_2PART_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
- {V8_2PART_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
- {V8_2PART_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
- {V8_2PART_UINT64_C(0xd01fef10, a657842c), 800, 260},
- {V8_2PART_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
- {V8_2PART_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
- {V8_2PART_UINT64_C(0xac2820d9, 623bf429), 880, 284},
- {V8_2PART_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
- {V8_2PART_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
- {V8_2PART_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
- {V8_2PART_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
- {V8_2PART_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
- {V8_2PART_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
- {V8_2PART_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+ {UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348},
+ {UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340},
+ {UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332},
+ {UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324},
+ {UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316},
+ {UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308},
+ {UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300},
+ {UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292},
+ {UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284},
+ {UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276},
+ {UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268},
+ {UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260},
+ {UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252},
+ {UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244},
+ {UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236},
+ {UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228},
+ {UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220},
+ {UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212},
+ {UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204},
+ {UINT64_2PART_C(0xef340a98, 172aace5), -715, -196},
+ {UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188},
+ {UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180},
+ {UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172},
+ {UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164},
+ {UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156},
+ {UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+ {UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140},
+ {UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132},
+ {UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124},
+ {UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116},
+ {UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108},
+ {UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100},
+ {UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+ {UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84},
+ {UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76},
+ {UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68},
+ {UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60},
+ {UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52},
+ {UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44},
+ {UINT64_2PART_C(0xaa242499, 697392d3), -183, -36},
+ {UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28},
+ {UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20},
+ {UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12},
+ {UINT64_2PART_C(0xd1b71758, e219652c), -77, -4},
+ {UINT64_2PART_C(0x9c400000, 00000000), -50, 4},
+ {UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12},
+ {UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20},
+ {UINT64_2PART_C(0x813f3978, f8940984), 30, 28},
+ {UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36},
+ {UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44},
+ {UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52},
+ {UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60},
+ {UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68},
+ {UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76},
+ {UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84},
+ {UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92},
+ {UINT64_2PART_C(0x924d692c, a61be758), 269, 100},
+ {UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108},
+ {UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116},
+ {UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124},
+ {UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132},
+ {UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140},
+ {UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148},
+ {UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156},
+ {UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164},
+ {UINT64_2PART_C(0xa59bc234, db398c25), 508, 172},
+ {UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180},
+ {UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188},
+ {UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196},
+ {UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204},
+ {UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212},
+ {UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220},
+ {UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228},
+ {UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236},
+ {UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244},
+ {UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252},
+ {UINT64_2PART_C(0xd01fef10, a657842c), 800, 260},
+ {UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268},
+ {UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276},
+ {UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284},
+ {UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292},
+ {UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300},
+ {UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308},
+ {UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316},
+ {UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324},
+ {UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332},
+ {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340},
};
static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers);
@@ -147,7 +147,7 @@ void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
DiyFp* power,
int* decimal_exponent) {
int kQ = DiyFp::kSignificandSize;
- double k = ceiling((min_exponent + kQ - 1) * kD_1_LOG2_10);
+ double k = ceil((min_exponent + kQ - 1) * kD_1_LOG2_10);
int foo = kCachedPowersOffset;
int index =
(foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1;
@@ -174,4 +174,4 @@ void PowersOfTenCache::GetCachedPowerForDecimalExponent(int requested_exponent,
ASSERT(requested_exponent < *found_exponent + kDecimalExponentDistance);
}
-} } // namespace v8::internal
+} // namespace double_conversion
View
11 src/cached-powers.h
@@ -25,13 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef V8_CACHED_POWERS_H_
-#define V8_CACHED_POWERS_H_
+#ifndef DOUBLE_CONVERSION_CACHED_POWERS_H_
+#define DOUBLE_CONVERSION_CACHED_POWERS_H_
#include "diy-fp.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
class PowersOfTenCache {
public:
@@ -60,6 +59,6 @@ class PowersOfTenCache {
int* found_exponent);
};
-} } // namespace v8::internal
+} // namespace double_conversion
-#endif // V8_CACHED_POWERS_H_
+#endif // DOUBLE_CONVERSION_CACHED_POWERS_H_
View
9 src/diy-fp.cc
@@ -25,19 +25,18 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "v8.h"
#include "diy-fp.h"
+#include "utils.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
void DiyFp::Multiply(const DiyFp& other) {
// Simply "emulates" a 128 bit multiplication.
// However: the resulting number only contains 64 bits. The least
// significant 64 bits are only used for rounding the most significant 64
// bits.
- const uint64_t kM32 = 0xFFFFFFFFu;
+ const uint64_t kM32 = 0xFFFFFFFFU;
uint64_t a = f_ >> 32;
uint64_t b = f_ & kM32;
uint64_t c = other.f_ >> 32;
@@ -55,4 +54,4 @@ void DiyFp::Multiply(const DiyFp& other) {
f_ = result_f;
}
-} } // namespace v8::internal
+} // namespace double_conversion
View
17 src/diy-fp.h
@@ -25,11 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef V8_DIY_FP_H_
-#define V8_DIY_FP_H_
+#ifndef DOUBLE_CONVERSION_DIY_FP_H_
+#define DOUBLE_CONVERSION_DIY_FP_H_
-namespace v8 {
-namespace internal {
+#include "utils.h"
+
+namespace double_conversion {
// This "Do It Yourself Floating Point" class implements a floating-point number
// with a uint64 significand and an int exponent. Normalized DiyFp numbers will
@@ -80,7 +81,7 @@ class DiyFp {
// This method is mainly called for normalizing boundaries. In general
// boundaries need to be shifted by 10 bits. We thus optimize for this case.
- const uint64_t k10MSBits = V8_2PART_UINT64_C(0xFFC00000, 00000000);
+ const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
while ((f & k10MSBits) == 0) {
f <<= 10;
e -= 10;
@@ -106,12 +107,12 @@ class DiyFp {
void set_e(int new_value) { e_ = new_value; }
private:
- static const uint64_t kUint64MSB = V8_2PART_UINT64_C(0x80000000, 00000000);
+ static const uint64_t kUint64MSB = UINT64_2PART_C(0x80000000, 00000000);
uint64_t f_;
int e_;
};
-} } // namespace v8::internal
+} // namespace double_conversion
-#endif // V8_DIY_FP_H_
+#endif // DOUBLE_CONVERSION_DIY_FP_H_
View
765 src/double-conversion.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -25,307 +25,401 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include <stdarg.h>
#include <limits.h>
+#include <math.h>
-#include "v8.h"
+#include "double-conversion.h"
-#include "conversions-inl.h"
-#include "dtoa.h"
-#include "factory.h"
-#include "scanner-base.h"
+#include "bignum-dtoa.h"
+#include "double.h"
+#include "fast-dtoa.h"
+#include "fixed-dtoa.h"
#include "strtod.h"
+#include "utils.h"
+
+namespace double_conversion {
+
+const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
+ int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
+ static DoubleToStringConverter converter(flags,
+ "Infinity",
+ "NaN",
+ 'e',
+ -6, 21,
+ 6, 0);
+ return converter;
+}
+
-namespace v8 {
-namespace internal {
+bool DoubleToStringConverter::HandleSpecialValues(
+ double value,
+ StringBuilder* result_builder) const {
+ Double double_inspect(value);
+ if (double_inspect.IsInfinite()) {
+ if (infinity_symbol_ == NULL) return false;
+ if (value < 0) {
+ result_builder->AddCharacter('-');
+ }
+ result_builder->AddString(infinity_symbol_);
+ return true;
+ }
+ if (double_inspect.IsNan()) {
+ if (nan_symbol_ == NULL) return false;
+ result_builder->AddString(nan_symbol_);
+ return true;
+ }
+ return false;
+}
-namespace {
-static char* CreateExponentialRepresentation(char* decimal_rep,
- int exponent,
- bool negative,
- int significant_digits) {
- bool negative_exponent = false;
+void DoubleToStringConverter::CreateExponentialRepresentation(
+ const char* decimal_digits,
+ int length,
+ int exponent,
+ StringBuilder* result_builder) const {
+ ASSERT(length != 0);
+ result_builder->AddCharacter(decimal_digits[0]);
+ if (length != 1) {
+ result_builder->AddCharacter('.');
+ result_builder->AddSubstring(&decimal_digits[1], length-1);
+ }
+ result_builder->AddCharacter(exponent_character_);
if (exponent < 0) {
- negative_exponent = true;
+ result_builder->AddCharacter('-');
exponent = -exponent;
+ } else {
+ if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
+ result_builder->AddCharacter('+');
+ }
}
-
- // Leave room in the result for appending a minus, for a period, the
- // letter 'e', a minus or a plus depending on the exponent, and a
- // three digit exponent.
- unsigned result_size = significant_digits + 7;
- StringBuilder builder(result_size + 1);
-
- if (negative) builder.AddCharacter('-');
- builder.AddCharacter(decimal_rep[0]);
- if (significant_digits != 1) {
- builder.AddCharacter('.');
- builder.AddString(decimal_rep + 1);
- int rep_length = StrLength(decimal_rep);
- builder.AddPadding('0', significant_digits - rep_length);
+ if (exponent == 0) {
+ result_builder->AddCharacter('0');
+ return;
}
-
- builder.AddCharacter('e');
- builder.AddCharacter(negative_exponent ? '-' : '+');
- builder.AddFormatted("%d", exponent);
- return builder.Finalize();
+ ASSERT(exponent < 1e4);
+ const int kMaxExponentLength = 5;
+ char buffer[kMaxExponentLength];
+ int first_char_pos = kMaxExponentLength;
+ while (exponent > 0) {
+ buffer[--first_char_pos] = '0' + (exponent % 10);
+ exponent /= 10;
+ }
+ result_builder->AddSubstring(&buffer[first_char_pos],
+ kMaxExponentLength - first_char_pos);
}
-const char* DoubleToCString(double v, Vector<char> buffer) {
- StringBuilder builder(buffer.start(), buffer.length());
-
- switch (fpclassify(v)) {
- case FP_NAN:
- builder.AddString("NaN");
- break;
-
- case FP_INFINITE:
- if (v < 0.0) {
- builder.AddString("-Infinity");
- } else {
- builder.AddString("Infinity");
- }
- break;
-
- case FP_ZERO:
- builder.AddCharacter('0');
- break;
- default: {
- int decimal_point;
- int sign;
- const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
- char decimal_rep[kV8DtoaBufferCapacity];
- int length;
+void DoubleToStringConverter::CreateDecimalRepresentation(
+ const char* decimal_digits,
+ int length,
+ int decimal_point,
+ int digits_after_point,
+ StringBuilder* result_builder) const {
+ // Create a representation that is padded with zeros if needed.
+ if (decimal_point <= 0) {
+ // "0.00000decimal_rep".
+ result_builder->AddCharacter('0');
+ if (digits_after_point > 0) {
+ result_builder->AddCharacter('.');
+ result_builder->AddPadding('0', -decimal_point);
+ ASSERT(length <= digits_after_point - (-decimal_point));
+ result_builder->AddSubstring(decimal_digits, length);
+ int remaining_digits = digits_after_point - (-decimal_point) - length;
+ result_builder->AddPadding('0', remaining_digits);
+ }
+ } else if (decimal_point >= length) {
+ // "decimal_rep0000.00000" or "decimal_rep.0000"
+ result_builder->AddSubstring(decimal_digits, length);
+ result_builder->AddPadding('0', decimal_point - length);
+ if (digits_after_point > 0) {
+ result_builder->AddCharacter('.');
+ result_builder->AddPadding('0', digits_after_point);
+ }
+ } else {
+ // "decima.l_rep000"
+ ASSERT(digits_after_point > 0);
+ result_builder->AddSubstring(decimal_digits, decimal_point);
+ result_builder->AddCharacter('.');
+ ASSERT(length - decimal_point <= digits_after_point);
+ result_builder->AddSubstring(&decimal_digits[decimal_point],
+ length - decimal_point);
+ int remaining_digits = digits_after_point - (length - decimal_point);
+ result_builder->AddPadding('0', remaining_digits);
+ }
+ if (digits_after_point == 0) {
+ if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
+ result_builder->AddCharacter('.');
+ }
+ if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
+ result_builder->AddCharacter('0');
+ }
+ }
+}
- DoubleToAscii(v, DTOA_SHORTEST, 0,
- Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
- &sign, &length, &decimal_point);
- if (sign) builder.AddCharacter('-');
+bool DoubleToStringConverter::ToShortest(double value,
+ StringBuilder* result_builder) const {
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
- if (length <= decimal_point && decimal_point <= 21) {
- // ECMA-262 section 9.8.1 step 6.
- builder.AddString(decimal_rep);
- builder.AddPadding('0', decimal_point - length);
+ int decimal_point;
+ bool sign;
+ const int kDecimalRepCapacity = kBase10MaximalLength + 1;
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
- } else if (0 < decimal_point && decimal_point <= 21) {
- // ECMA-262 section 9.8.1 step 7.
- builder.AddSubstring(decimal_rep, decimal_point);
- builder.AddCharacter('.');
- builder.AddString(decimal_rep + decimal_point);
+ DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
- } else if (decimal_point <= 0 && decimal_point > -6) {
- // ECMA-262 section 9.8.1 step 8.
- builder.AddString("0.");
- builder.AddPadding('0', -decimal_point);
- builder.AddString(decimal_rep);
+ bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
- } else {
- // ECMA-262 section 9.8.1 step 9 and 10 combined.
- builder.AddCharacter(decimal_rep[0]);
- if (length != 1) {
- builder.AddCharacter('.');
- builder.AddString(decimal_rep + 1);
- }
- builder.AddCharacter('e');
- builder.AddCharacter((decimal_point >= 0) ? '+' : '-');
- int exponent = decimal_point - 1;
- if (exponent < 0) exponent = -exponent;
- builder.AddFormatted("%d", exponent);
- }
- }
+ int exponent = decimal_point - 1;
+ if ((decimal_in_shortest_low_ <= exponent) &&
+ (exponent < decimal_in_shortest_high_)) {
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
+ decimal_point,
+ Max(0, decimal_rep_length - decimal_point),
+ result_builder);
+ } else {
+ CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
+ result_builder);
}
- return builder.Finalize();
+ return true;
}
-char* DoubleToFixedCString(double value, int f) {
- const int kMaxDigitsBeforePoint = 21;
- const double kFirstNonFixed = 1e21;
- const int kMaxDigitsAfterPoint = 20;
- ASSERT(f >= 0);
- ASSERT(f <= kMaxDigitsAfterPoint);
+bool DoubleToStringConverter::ToFixed(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const {
+ ASSERT(kMaxFixedDigitsBeforePoint == 60);
+ const double kFirstNonFixed = 1e60;
- bool negative = false;
- double abs_value = value;
- if (value < 0) {
- abs_value = -value;
- negative = true;
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
}
- // If abs_value has more than kMaxDigitsBeforePoint digits before the point
- // use the non-fixed conversion routine.
- if (abs_value >= kFirstNonFixed) {
- char arr[100];
- Vector<char> buffer(arr, ARRAY_SIZE(arr));
- return StrDup(DoubleToCString(value, buffer));
- }
+ if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
+ if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
// Find a sufficiently precise decimal representation of n.
int decimal_point;
- int sign;
+ bool sign;
// Add space for the '\0' byte.
const int kDecimalRepCapacity =
- kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1;
+ kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
char decimal_rep[kDecimalRepCapacity];
int decimal_rep_length;
- DoubleToAscii(value, DTOA_FIXED, f,
- Vector<char>(decimal_rep, kDecimalRepCapacity),
+ DoubleToAscii(value, FIXED, requested_digits,
+ decimal_rep, kDecimalRepCapacity,
&sign, &decimal_rep_length, &decimal_point);
- // Create a representation that is padded with zeros if needed.
- int zero_prefix_length = 0;
- int zero_postfix_length = 0;
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
- if (decimal_point <= 0) {
- zero_prefix_length = -decimal_point + 1;
- decimal_point = 1;
- }
-
- if (zero_prefix_length + decimal_rep_length < decimal_point + f) {
- zero_postfix_length = decimal_point + f - decimal_rep_length -
- zero_prefix_length;
- }
-
- unsigned rep_length =
- zero_prefix_length + decimal_rep_length + zero_postfix_length;
- StringBuilder rep_builder(rep_length + 1);
- rep_builder.AddPadding('0', zero_prefix_length);
- rep_builder.AddString(decimal_rep);
- rep_builder.AddPadding('0', zero_postfix_length);
- char* rep = rep_builder.Finalize();
-
- // Create the result string by appending a minus and putting in a
- // decimal point if needed.
- unsigned result_size = decimal_point + f + 2;
- StringBuilder builder(result_size + 1);
- if (negative) builder.AddCharacter('-');
- builder.AddSubstring(rep, decimal_point);
- if (f > 0) {
- builder.AddCharacter('.');
- builder.AddSubstring(rep + decimal_point, f);
- }
- DeleteArray(rep);
- return builder.Finalize();
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
+ requested_digits, result_builder);
+ return true;
}
-char* DoubleToExponentialCString(double value, int f) {
- const int kMaxDigitsAfterPoint = 20;
- // f might be -1 to signal that f was undefined in JavaScript.
- ASSERT(f >= -1 && f <= kMaxDigitsAfterPoint);
-
- bool negative = false;
- if (value < 0) {
- value = -value;
- negative = true;
+bool DoubleToStringConverter::ToExponential(
+ double value,
+ int requested_digits,
+ StringBuilder* result_builder) const {
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
}
- // Find a sufficiently precise decimal representation of n.
+ if (requested_digits < -1) return false;
+ if (requested_digits > kMaxExponentialDigits) return false;
+
int decimal_point;
- int sign;
- // f corresponds to the digits after the point. There is always one digit
- // before the point. The number of requested_digits equals hence f + 1.
- // And we have to add one character for the null-terminator.
- const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1;
- // Make sure that the buffer is big enough, even if we fall back to the
- // shortest representation (which happens when f equals -1).
- ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1);
- char decimal_rep[kV8DtoaBufferCapacity];
+ bool sign;
+ // Add space for digit before the decimal point and the '\0' character.
+ const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
+ ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
+ char decimal_rep[kDecimalRepCapacity];
int decimal_rep_length;
- if (f == -1) {
- DoubleToAscii(value, DTOA_SHORTEST, 0,
- Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
+ if (requested_digits == -1) {
+ DoubleToAscii(value, SHORTEST, 0,
+ decimal_rep, kDecimalRepCapacity,
&sign, &decimal_rep_length, &decimal_point);
- f = decimal_rep_length - 1;
} else {
- DoubleToAscii(value, DTOA_PRECISION, f + 1,
- Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
+ DoubleToAscii(value, PRECISION, requested_digits + 1,
+ decimal_rep, kDecimalRepCapacity,
&sign, &decimal_rep_length, &decimal_point);
+ ASSERT(decimal_rep_length <= requested_digits + 1);
+
+ for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
+ decimal_rep[i] = '0';
+ }
+ decimal_rep_length = requested_digits + 1;
}
- ASSERT(decimal_rep_length > 0);
- ASSERT(decimal_rep_length <= f + 1);
- int exponent = decimal_point - 1;
- char* result =
- CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1);
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
- return result;
+ int exponent = decimal_point - 1;
+ CreateExponentialRepresentation(decimal_rep,
+ decimal_rep_length,
+ exponent,
+ result_builder);
+ return true;
}
-char* DoubleToPrecisionCString(double value, int p) {
- const int kMinimalDigits = 1;
- const int kMaximalDigits = 21;
- ASSERT(p >= kMinimalDigits && p <= kMaximalDigits);
- USE(kMinimalDigits);
+bool DoubleToStringConverter::ToPrecision(double value,
+ int precision,
+ StringBuilder* result_builder) const {
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
- bool negative = false;
- if (value < 0) {
- value = -value;
- negative = true;
+ if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
+ return false;
}
// Find a sufficiently precise decimal representation of n.
int decimal_point;
- int sign;
+ bool sign;
// Add one for the terminating null character.
- const int kV8DtoaBufferCapacity = kMaximalDigits + 1;
- char decimal_rep[kV8DtoaBufferCapacity];
+ const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
+ char decimal_rep[kDecimalRepCapacity];
int decimal_rep_length;
- DoubleToAscii(value, DTOA_PRECISION, p,
- Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
+ DoubleToAscii(value, PRECISION, precision,
+ decimal_rep, kDecimalRepCapacity,
&sign, &decimal_rep_length, &decimal_point);
- ASSERT(decimal_rep_length <= p);
+ ASSERT(decimal_rep_length <= precision);
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ // The exponent if we print the number as x.xxeyyy. That is with the
+ // decimal point after the first digit.
int exponent = decimal_point - 1;
- char* result = NULL;
+ int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
+ if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
+ (decimal_point - precision + extra_zero >
+ max_trailing_padding_zeroes_in_precision_mode_)) {
+ // Fill buffer to contain 'precision' digits.
+ // Usually the buffer is already at the correct length, but 'DoubleToAscii'
+ // is allowed to return less characters.
+ for (int i = decimal_rep_length; i < precision; ++i) {
+ decimal_rep[i] = '0';
+ }
- if (exponent < -6 || exponent >= p) {
- result =
- CreateExponentialRepresentation(decimal_rep, exponent, negative, p);
+ CreateExponentialRepresentation(decimal_rep,
+ precision,
+ exponent,
+ result_builder);
} else {
- // Use fixed notation.
- //
- // Leave room in the result for appending a minus, a period and in
- // the case where decimal_point is not positive for a zero in
- // front of the period.
- unsigned result_size = (decimal_point <= 0)
- ? -decimal_point + p + 3
- : p + 2;
- StringBuilder builder(result_size + 1);
- if (negative) builder.AddCharacter('-');
- if (decimal_point <= 0) {
- builder.AddString("0.");
- builder.AddPadding('0', -decimal_point);
- builder.AddString(decimal_rep);
- builder.AddPadding('0', p - decimal_rep_length);
- } else {
- const int m = Min(decimal_rep_length, decimal_point);
- builder.AddSubstring(decimal_rep, m);
- builder.AddPadding('0', decimal_point - decimal_rep_length);
- if (decimal_point < p) {
- builder.AddCharacter('.');
- const int extra = negative ? 2 : 1;
- if (decimal_rep_length > decimal_point) {
- const int len = StrLength(decimal_rep + decimal_point);
- const int n = Min(len, p - (builder.position() - extra));
- builder.AddSubstring(decimal_rep + decimal_point, n);
- }
- builder.AddPadding('0', extra + (p - builder.position()));
- }
- }
- result = builder.Finalize();
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
+ Max(0, precision - decimal_point),
+ result_builder);
}
+ return true;
+}
+
- return result;
+static BignumDtoaMode DtoaToBignumDtoaMode(
+ DoubleToStringConverter::DtoaMode dtoa_mode) {
+ switch (dtoa_mode) {
+ case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
+ case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
+ case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
+ default:
+ UNREACHABLE();
+ return BIGNUM_DTOA_SHORTEST; // To silence compiler.
+ }
}
+
+void DoubleToStringConverter::DoubleToAscii(double v,
+ DtoaMode mode,
+ int requested_digits,
+ char* buffer,
+ int buffer_length,
+ bool* sign,
+ int* length,
+ int* point) {
+ Vector<char> vector(buffer, buffer_length);
+ ASSERT(!Double(v).IsSpecial());
+ ASSERT(mode == SHORTEST || requested_digits >= 0);
+
+ if (Double(v).Sign() < 0) {
+ *sign = true;
+ v = -v;
+ } else {
+ *sign = false;
+ }
+
+ if (mode == PRECISION && requested_digits == 0) {
+ vector[0] = '\0';
+ *length = 0;
+ return;
+ }
+
+ if (v == 0) {
+ vector[0] = '0';
+ vector[1] = '\0';
+ *length = 1;
+ *point = 1;
+ return;
+ }
+
+ bool fast_worked;
+ switch (mode) {
+ case SHORTEST:
+ fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
+ break;
+ case FIXED:
+ fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
+ break;
+ case PRECISION:
+ fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
+ vector, length, point);
+ break;
+ default:
+ UNREACHABLE();
+ fast_worked = false;
+ }
+ if (fast_worked) return;
+
+ // If the fast dtoa didn't succeed use the slower bignum version.
+ BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
+ BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
+ vector[*length] = '\0';
+}
+
+
+// Consumes the given substring from the iterator.
+// Returns false, if the substring does not match.
+static bool ConsumeSubString(const char** current,
+ const char* end,
+ const char* substring) {
+ ASSERT(**current == *substring);
+ for (substring++; *substring != '\0'; substring++) {
+ ++*current;
+ if (*current == end || **current != *substring) return false;
+ }
+ ++*current;
+ return true;
+}
+
+
// Maximum number of significant digits in decimal representation.
// The longest possible double in decimal representation is
// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
@@ -337,10 +431,9 @@ const int kMaxSignificantDigits = 772;
// Returns true if a nonspace found and false if the end has reached.
-template <class Iterator, class EndMark>
-static inline bool AdvanceToNonspace(Iterator* current, EndMark end) {
+static inline bool AdvanceToNonspace(const char** current, const char* end) {
while (*current != end) {
- if (!ScannerConstants::kIsWhiteSpace.get(**current)) return true;
+ if (**current != ' ') return true;
++*current;
}
return false;
@@ -360,17 +453,22 @@ static double SignedZero(bool sign) {
// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
-template <int radix_log_2, class Iterator, class EndMark>
-static double InternalStringToIntDouble(Iterator current,
- EndMark end,
- bool sign,
- bool allow_trailing_junk) {
+template <int radix_log_2>
+static double RadixStringToDouble(const char* current,
+ const char* end,
+ bool sign,
+ bool allow_trailing_junk,
+ double junk_string_value,
+ const char** trailing_pointer) {
ASSERT(current != end);
// Skip leading 0s.
while (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) {
+ *trailing_pointer = end;
+ return SignedZero(sign);
+ }
}
int64_t number = 0;
@@ -389,7 +487,7 @@ static double InternalStringToIntDouble(Iterator current,
if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) {
break;
} else {
- return JUNK_STRING_VALUE;
+ return junk_string_value;
}
}
@@ -418,7 +516,7 @@ static double InternalStringToIntDouble(Iterator current,
}
if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
+ return junk_string_value;
}
int middle_value = (1 << (overflow_bits_count - 1));
@@ -445,6 +543,8 @@ static double InternalStringToIntDouble(Iterator current,
ASSERT(number < ((int64_t)1 << 53));
ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
+ *trailing_pointer = current;
+
if (exponent == 0) {
if (sign) {
if (number == 0) return -0.0;
@@ -454,35 +554,46 @@ static double InternalStringToIntDouble(Iterator current,
}
ASSERT(number != 0);
- // The double could be constructed faster from number (mantissa), exponent
- // and sign. Assuming it's a rare case more simple code is used.
- return static_cast<double>(sign ? -number : number) * pow(2.0, exponent);
+ return Double(DiyFp(number, exponent)).value();
}
-// Converts a string to a double value. Assumes the Iterator supports
-// the following operations:
-// 1. current == end (other ops are not allowed), current != end.
-// 2. *current - gets the current character in the sequence.
-// 3. ++current (advances the position).
-template <class Iterator, class EndMark>
-static double InternalStringToDouble(Iterator current,
- EndMark end,
- int flags,
- double empty_string_val) {
+double StringToDoubleConverter::StringToDouble(
+ const char* input,
+ int length,
+ int* processed_characters_count) {
+ const char* current = input;
+ const char* end = input + length;
+
+ *processed_characters_count = 0;
+
+ const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
+ const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
+ const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
+ const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
+
// To make sure that iterator dereferencing is valid the following
// convention is used:
// 1. Each '++current' statement is followed by check for equality to 'end'.
// 2. If AdvanceToNonspace returned false then current == end.
- // 3. If 'current' becomes be equal to 'end' the function returns or goes to
+ // 3. If 'current' becomes equal to 'end' the function returns or goes to
// 'parsing_done'.
// 4. 'current' is not dereferenced after the 'parsing_done' label.
// 5. Code before 'parsing_done' may rely on 'current != end'.
- if (!AdvanceToNonspace(&current, end)) return empty_string_val;
+ if (current == end) return empty_string_value_;
- const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
+ if (allow_leading_spaces || allow_trailing_spaces) {
+ if (!AdvanceToNonspace(&current, end)) {
+ *processed_characters_count = current - input;
+ return empty_string_value_;
+ }
+ if (!allow_leading_spaces && (input != current)) {
+ // No leading spaces allowed, but AdvanceToNonspace moved forward.
+ return junk_string_value_;
+ }
+ }
- // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
+ // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
const int kBufferSize = kMaxSignificantDigits + 10;
char buffer[kBufferSize]; // NOLINT: size is known at compile time.
int buffer_pos = 0;
@@ -497,58 +608,98 @@ static double InternalStringToDouble(Iterator current,
bool sign = false;
- if (*current == '+') {
- // Ignore leading sign; skip following spaces.
+ if (*current == '+' || *current == '-') {
+ sign = (*current == '-');
++current;
- if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
- } else if (*current == '-') {
- ++current;
- if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
- sign = true;
+ const char* next_non_space = current;
+ // Skip following spaces (if allowed).
+ if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
+ if (!allow_spaces_after_sign && (current != next_non_space)) {
+ return junk_string_value_;
+ }
+ current = next_non_space;
}
- static const char kInfinitySymbol[] = "Infinity";
- if (*current == kInfinitySymbol[0]) {
- if (!SubStringEquals(&current, end, kInfinitySymbol)) {
- return JUNK_STRING_VALUE;
- }
+ if (infinity_symbol_ != NULL) {
+ if (*current == infinity_symbol_[0]) {
+ if (!ConsumeSubString(&current, end, infinity_symbol_)) {
+ return junk_string_value_;
+ }
+
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+ return junk_string_value_;
+ }
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ return junk_string_value_;
+ }
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
+ ASSERT(buffer_pos == 0);
+ *processed_characters_count = current - input;
+ return sign ? -Double::Infinity() : Double::Infinity();
}
+ }
- ASSERT(buffer_pos == 0);
- return sign ? -V8_INFINITY : V8_INFINITY;
+ if (nan_symbol_ != NULL) {
+ if (*current == nan_symbol_[0]) {
+ if (!ConsumeSubString(&current, end, nan_symbol_)) {
+ return junk_string_value_;
+ }
+
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+ return junk_string_value_;
+ }
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ return junk_string_value_;
+ }
+
+ ASSERT(buffer_pos == 0);
+ *processed_characters_count = current - input;
+ return sign ? -Double::NaN() : Double::NaN();
+ }
}
bool leading_zero = false;
if (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) {
+ *processed_characters_count = current - input;
+ return SignedZero(sign);
+ }
leading_zero = true;
// It could be hexadecimal value.
- if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
+ if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
++current;
if (current == end || !isDigit(*current, 16)) {
- return JUNK_STRING_VALUE; // "0x".
+ return junk_string_value_; // "0x".
}
- return InternalStringToIntDouble<4>(current,
- end,
- sign,
- allow_trailing_junk);
+ const char* tail_pointer = NULL;
+ double result = RadixStringToDouble<4>(current,
+ end,
+ sign,
+ allow_trailing_junk,
+ junk_string_value_,
+ &tail_pointer);
+ if (tail_pointer != NULL) {
+ if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
+ *processed_characters_count = tail_pointer - input;
+ }
+ return result;
}
// Ignore leading zeros in the integer part.
while (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) {
+ *processed_characters_count = current - input;
+ return SignedZero(sign);
+ }
}
}
- bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0;
+ bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
// Copy significant digits of the integer part (if any) to the buffer.
while (*current >= '0' && *current <= '9') {
@@ -571,13 +722,13 @@ static double InternalStringToDouble(Iterator current,
}
if (*current == '.') {
- if (octal && !allow_trailing_junk) return JUNK_STRING_VALUE;
+ if (octal && !allow_trailing_junk) return junk_string_value_;
if (octal) goto parsing_done;
++current;
if (current == end) {
if (significant_digits == 0 && !leading_zero) {
- return JUNK_STRING_VALUE;
+ return junk_string_value_;
} else {
goto parsing_done;
}
@@ -589,7 +740,10 @@ static double InternalStringToDouble(Iterator current,
// leading zeros (if any).
while (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) {
+ *processed_characters_count = current - input;
+ return SignedZero(sign);
+ }
exponent--; // Move this 0 into the exponent.
}
}
@@ -618,18 +772,19 @@ static double InternalStringToDouble(Iterator current,
// If exponent < 0 then string was [+-]\.0*...
// If significant_digits != 0 the string is not equal to 0.
// Otherwise there are no digits in the string.
- return JUNK_STRING_VALUE;
+ return junk_string_value_;
}
// Parse exponential part.
if (*current == 'e' || *current == 'E') {
- if (octal) return JUNK_STRING_VALUE;
+ if (octal && !allow_trailing_junk) return junk_string_value_;
+ if (octal) goto parsing_done;
++current;
if (current == end) {
if (allow_trailing_junk) {
goto parsing_done;
} else {
- return JUNK_STRING_VALUE;
+ return junk_string_value_;
}
}
char sign = '+';
@@ -640,7 +795,7 @@ static double InternalStringToDouble(Iterator current,
if (allow_trailing_junk) {
goto parsing_done;
} else {
- return JUNK_STRING_VALUE;
+ return junk_string_value_;
}
}
}
@@ -649,7 +804,7 @@ static double InternalStringToDouble(Iterator current,
if (allow_trailing_junk) {
goto parsing_done;
} else {
- return JUNK_STRING_VALUE;
+ return junk_string_value_;
}
}
@@ -671,18 +826,31 @@ static double InternalStringToDouble(Iterator current,
exponent += (sign == '-' ? -num : num);
}
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+ return junk_string_value_;
+ }
if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
+ return junk_string_value_;
+ }
+ if (allow_trailing_spaces) {
+ AdvanceToNonspace(&current, end);
}
parsing_done:
exponent += insignificant_digits;
if (octal) {
- return InternalStringToIntDouble<3>(buffer,
- buffer + buffer_pos,
- sign,
- allow_trailing_junk);
+ double result;
+ const char* tail_pointer = NULL;
+ result = RadixStringToDouble<3>(buffer,
+ buffer + buffer_pos,
+ sign,
+ allow_trailing_junk,
+ junk_string_value_,
+ &tail_pointer);
+ ASSERT(tail_pointer != NULL);
+ *processed_characters_count = current - input;
+ return result;
}
if (nonzero_digit_dropped) {
@@ -694,7 +862,8 @@ static double InternalStringToDouble(Iterator current,
buffer[buffer_pos] = '\0';
double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
- return sign ? -converted : converted;
+ *processed_characters_count = current - input;
+ return sign? -converted: converted;
}
-} } // namespace v8::internal
+} // namespace double_conversion
View
498 src/double-conversion.h
@@ -0,0 +1,498 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
+#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+class DoubleToStringConverter {
+ public:
+ // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint
+ // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the
+ // function returns false.
+ static const int kMaxFixedDigitsBeforePoint = 60;
+ static const int kMaxFixedDigitsAfterPoint = 60;
+
+ // When calling ToExponential with a requested_digits
+ // parameter > kMaxExponentialDigits then the function returns false.
+ static const int kMaxExponentialDigits = 120;
+
+ // When calling ToPrecision with a requested_digits
+ // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits
+ // then the function returns false.
+ static const int kMinPrecisionDigits = 1;
+ static const int kMaxPrecisionDigits = 120;
+
+ enum Flags {
+ NO_FLAGS = 0,
+ EMIT_POSITIVE_EXPONENT_SIGN = 1,
+ EMIT_TRAILING_DECIMAL_POINT = 2,
+ EMIT_TRAILING_ZERO_AFTER_POINT = 4,
+ UNIQUE_ZERO = 8
+ };
+
+ // Flags should be a bit-or combination of the possible Flags-enum.
+ // - NO_FLAGS: no special flags.
+ // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent
+ // form, emits a '+' for positive exponents. Example: 1.2e+2.
+ // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is
+ // converted into decimal format then a trailing decimal point is appended.
+ // Example: 2345.0 is converted to "2345.".
+ // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point
+ // emits a trailing '0'-character. This flag requires the
+ // EXMIT_TRAILING_DECIMAL_POINT flag.
+ // Example: 2345.0 is converted to "2345.0".
+ // - UNIQUE_ZERO: "-0.0" is converted to "0.0".
+ //
+ // Infinity symbol and nan_symbol provide the string representation for these
+ // special values. If the string is NULL and the special value is encountered
+ // then the conversion functions return false.
+ //
+ // The exponent_character is used in exponential representations. It is
+ // usually 'e' or 'E'.
+ //
+ // When converting to the shortest representation the converter will
+ // represent input numbers in decimal format if they are in the interval
+ // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[
+ // (lower boundary included, greater boundary excluded).
+ // Example: with decimal_in_shortest_low = -6 and
+ // decimal_in_shortest_high = 21:
+ // ToShortest(0.000001) -> "0.000001"
+ // ToShortest(0.0000001) -> "1e-7"
+ // ToShortest(111111111111111111111.0) -> "111111111111111110000"
+ // ToShortest(100000000000000000000.0) -> "100000000000000000000"
+ // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
+ //
+ // When converting to precision mode the converter may add
+ // max_leading_padding_zeroes before returning the number in exponential
+ // format.
+ // Example with max_leading_padding_zeroes_in_precision_mode = 6.
+ // ToPrecision(0.0000012345, 2) -> "0.0000012"
+ // ToPrecision(0.00000012345, 2) -> "1.2e-7"
+ // Similarily the converter may add up to
+ // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
+ // returning an exponential representation. A zero added by the
+ // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
+ // ToPrecision(230.0, 2) -> "230"
+ // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
+ // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
+ DoubleToStringConverter(int flags,
+ const char* infinity_symbol,
+ const char* nan_symbol,
+ char exponent_character,
+ int decimal_in_shortest_low,
+ int decimal_in_shortest_high,
+ int max_leading_padding_zeroes_in_precision_mode,
+ int max_trailing_padding_zeroes_in_precision_mode)
+ : flags_(flags),
+ infinity_symbol_(infinity_symbol),
+ nan_symbol_(nan_symbol),
+ exponent_character_(exponent_character),
+ decimal_in_shortest_low_(decimal_in_shortest_low),
+ decimal_in_shortest_high_(decimal_in_shortest_high),
+ max_leading_padding_zeroes_in_precision_mode_(
+ max_leading_padding_zeroes_in_precision_mode),
+ max_trailing_padding_zeroes_in_precision_mode_(
+ max_trailing_padding_zeroes_in_precision_mode) {
+ // When 'trailing zero after the point' is set, then 'trailing point'
+ // must be set too.
+ ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) ||
+ !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0));
+ }
+
+ // Returns a converter following the EcmaScript specification.
+ static const DoubleToStringConverter& EcmaScriptConverter();
+
+ // Computes the shortest string of digits that correctly represent the input
+ // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high
+ // (see constructor) it then either returns a decimal representation, or an
+ // exponential representation.
+ // Example with decimal_in_shortest_low = -6,
+ // decimal_in_shortest_high = 21,
+ // EMIT_POSITIVE_EXPONENT_SIGN activated, and
+ // EMIT_TRAILING_DECIMAL_POINT deactived:
+ // ToShortest(0.000001) -> "0.000001"
+ // ToShortest(0.0000001) -> "1e-7"
+ // ToShortest(111111111111111111111.0) -> "111111111111111110000"
+ // ToShortest(100000000000000000000.0) -> "100000000000000000000"
+ // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
+ //
+ // Note: the conversion may round the output if the returned string
+ // is accurate enough to uniquely identify the input-number.
+ // For example the most precise representation of the double 9e59 equals
+ // "899999999999999918767229449717619953810131273674690656206848", but
+ // the converter will return the shorter (but still correct) "9e59".
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except when the input value is special and no infinity_symbol or
+ // nan_symbol has been given to the constructor.
+ bool ToShortest(double value, StringBuilder* result_builder) const;
+
+
+ // Computes a decimal representation with a fixed number of digits after the
+ // decimal point. The last emitted digit is rounded.
+ //
+ // Examples:
+ // ToFixed(3.12, 1) -> "3.1"
+ // ToFixed(3.1415, 3) -> "3.142"
+ // ToFixed(1234.56789, 4) -> "1234.5679"
+ // ToFixed(1.23, 5) -> "1.23000"
+ // ToFixed(0.1, 4) -> "0.1000"
+ // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00"
+ // ToFixed(0.1, 30) -> "0.100000000000000005551115123126"
+ // ToFixed(0.1, 17) -> "0.10000000000000001"
+ //
+ // If requested_digits equals 0, then the tail of the result depends on
+ // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT.
+ // Examples, for requested_digits == 0,
+ // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be
+ // - false and false: then 123.45 -> 123
+ // 0.678 -> 1
+ // - true and false: then 123.45 -> 123.
+ // 0.678 -> 1.
+ // - true and true: then 123.45 -> 123.0
+ // 0.678 -> 1.0
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - 'value' > 10^kMaxFixedDigitsBeforePoint, or
+ // - 'requested_digits' > kMaxFixedDigitsAfterPoint.
+ // The last two conditions imply that the result will never contain more than
+ // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters
+ // (one additional character for the sign, and one for the decimal point).
+ bool ToFixed(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const;
+
+ // Computes a representation in exponential format with requested_digits
+ // after the decimal point. The last emitted digit is rounded.
+ // If requested_digits equals -1, then the shortest exponential representation
+ // is computed.
+ //
+ // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and
+ // exponent_character set to 'e'.
+ // ToExponential(3.12, 1) -> "3.1e0"
+ // ToExponential(5.0, 3) -> "5.000e0"
+ // ToExponential(0.001, 2) -> "1.00e-3"
+ // ToExponential(3.1415, -1) -> "3.1415e0"
+ // ToExponential(3.1415, 4) -> "3.1415e0"
+ // ToExponential(3.1415, 3) -> "3.142e0"
+ // ToExponential(123456789000000, 3) -> "1.235e14"
+ // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30"
+ // ToExponential(1000000000000000019884624838656.0, 32) ->
+ // "1.00000000000000001988462483865600e30"
+ // ToExponential(1234, 0) -> "1e3"
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - 'requested_digits' > kMaxExponentialDigits.
+ // The last condition implies that the result will never contain more than
+ // kMaxExponentialDigits + 8 characters (the sign, the digit before the
+ // decimal point, the decimal point, the exponent character, the
+ // exponent's sign, and at most 3 exponent digits).
+ bool ToExponential(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const;
+
+ // Computes 'precision' leading digits of the given 'value' and returns them
+ // either in exponential or decimal format, depending on
+ // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the
+ // constructor).
+ // The last computed digit is rounded.
+ //
+ // Example with max_leading_padding_zeroes_in_precision_mode = 6.
+ // ToPrecision(0.0000012345, 2) -> "0.0000012"
+ // ToPrecision(0.00000012345, 2) -> "1.2e-7"
+ // Similarily the converter may add up to
+ // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
+ // returning an exponential representation. A zero added by the
+ // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
+ // ToPrecision(230.0, 2) -> "230"
+ // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
+ // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no
+ // EMIT_TRAILING_ZERO_AFTER_POINT:
+ // ToPrecision(123450.0, 6) -> "123450"
+ // ToPrecision(123450.0, 5) -> "123450"
+ // ToPrecision(123450.0, 4) -> "123500"
+ // ToPrecision(123450.0, 3) -> "123000"
+ // ToPrecision(123450.0, 2) -> "1.2e5"
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - precision < kMinPericisionDigits
+ // - precision > kMaxPrecisionDigits
+ // The last condition implies that the result will never contain more than
+ // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the
+ // exponent character, the exponent's sign, and at most 3 exponent digits).
+ bool ToPrecision(double value,
+ int precision,
+ StringBuilder* result_builder) const;
+
+ enum DtoaMode {
+ // Produce the shortest correct representation.
+ // For example the output of 0.299999999999999988897 is (the less accurate
+ // but correct) 0.3.
+ SHORTEST,
+ // Produce a fixed number of digits after the decimal point.
+ // For instance fixed(0.1, 4) becomes 0.1000
+ // If the input number is big, the output will be big.
+ FIXED,
+ // Fixed number of digits (independent of the decimal point).
+ PRECISION
+ };
+
+ // The maximal number of digits that are needed to emit a double in base 10.
+ // A higher precision can be achieved by using more digits, but the shortest
+ // accurate representation of any double will never use more digits than
+ // kBase10MaximalLength.
+ // Note that DoubleToAscii null-terminates its input. So the given buffer
+ // should be at least kBase10MaximalLength + 1 characters long.
+ static const int kBase10MaximalLength = 17;
+
+ // Converts the given double 'v' to ascii.
+ // The result should be interpreted as buffer * 10^(point-length).
+ //
+ // The output depends on the given mode:
+ // - SHORTEST: produce the least amount of digits for which the internal
+ // identity requirement is still satisfied. If the digits are printed
+ // (together with the correct exponent) then reading this number will give
+ // 'v' again. The buffer will choose the representation that is closest to
+ // 'v'. If there are two at the same distance, than the one farther away
+ // from 0 is chosen (halfway cases - ending with 5 - are rounded up).
+ // In this mode the 'requested_digits' parameter is ignored.
+ // - FIXED: produces digits necessary to print a given number with
+ // 'requested_digits' digits after the decimal point. The produced digits
+ // might be too short in which case the caller has to fill the remainder
+ // with '0's.
+ // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
+ // Halfway cases are rounded towards +/-Infinity (away from 0). The call
+ // toFixed(0.15, 2) thus returns buffer="2", point=0.
+ // The returned buffer may contain digits that would be truncated from the
+ // shortest representation of the input.
+ // - PRECISION: produces 'requested_digits' where the first digit is not '0'.
+ // Even though the length of produced digits usually equals
+ // 'requested_digits', the function is allowed to return fewer digits, in
+ // which case the caller has to fill the missing digits with '0's.
+ // Halfway cases are again rounded away from 0.
+ // DoubleToAscii expects the given buffer to be big enough to hold all
+ // digits and a terminating null-character. In SHORTEST-mode it expects a
+ // buffer of at least kBase10MaximalLength + 1. In all other modes the
+ // requested_digits parameter (+ 1 for the null-character) limits the size of
+ // the output. The given length is only used in debug mode to ensure the
+ // buffer is big enough.
+ static void DoubleToAscii(double v,
+ DtoaMode mode,
+ int requested_digits,
+ char* buffer,
+ int buffer_length,
+ bool* sign,
+ int* length,
+ int* point);
+
+ private:
+ // If the value is a special value (NaN or Infinity) constructs the
+ // corresponding string using the configured infinity/nan-symbol.
+ // If either of them is NULL or the value is not special then the
+ // function returns false.
+ bool HandleSpecialValues(double value, StringBuilder* result_builder) const;
+ // Constructs an exponential representation (i.e. 1.234e56).
+ // The given exponent assumes a decimal point after the first decimal digit.
+ void CreateExponentialRepresentation(const char* decimal_digits,
+ int length,
+ int exponent,
+ StringBuilder* result_builder) const;
+ // Creates a decimal representation (i.e 1234.5678).
+ void CreateDecimalRepresentation(const char* decimal_digits,
+ int length,
+ int decimal_point,
+ int digits_after_point,
+ StringBuilder* result_builder) const;
+
+ const int flags_;
+ const char* const infinity_symbol_;
+ const char* const nan_symbol_;
+ const char exponent_character_;
+ const int decimal_in_shortest_low_;
+ const int decimal_in_shortest_high_;
+ const int max_leading_padding_zeroes_in_precision_mode_;
+ const int max_trailing_padding_zeroes_in_precision_mode_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
+};
+
+
+class StringToDoubleConverter {
+ public:
+ // Enumeration for allowing octals and ignoring junk when converting
+ // strings to numbers.
+ enum Flags {
+ NO_FLAGS = 0,
+ ALLOW_HEX = 1,
+ ALLOW_OCTALS = 2,
+ ALLOW_TRAILING_JUNK = 4,
+ ALLOW_LEADING_SPACES = 8,
+ ALLOW_TRAILING_SPACES = 16,
+ ALLOW_SPACES_AFTER_SIGN = 32
+ };
+
+ // Flags should be a bit-or combination of the possible Flags-enum.
+ // - NO_FLAGS: no special flags.
+ // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
+ // Ex: StringToDouble("0x1234") -> 4660.0
+ // In StringToDouble("0x1234.56") the characters ".56" are trailing
+ // junk. The result of the call is hence dependent on
+ // the ALLOW_TRAILING_JUNK flag and/or the junk value.
+ // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK,
+ // the string will not be parsed as "0" followed by junk.
+ //
+ // - ALLOW_OCTALS: recognizes the prefix "0" for octals:
+ // If a sequence of octal digits starts with '0', then the number is
+ // read as octal integer. Octal numbers may only be integers.
+ // Ex: StringToDouble("01234") -> 668.0
+ // StringToDouble("012349") -> 12349.0 // Not a sequence of octal
+ // // digits.
+ // In StringToDouble("01234.56") the characters ".56" are trailing
+ // junk. The result of the call is hence dependent on
+ // the ALLOW_TRAILING_JUNK flag and/or the junk value.
+ // In StringToDouble("01234e56") the characters "e56" are trailing
+ // junk, too.
+ // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
+ // a double literal.
+ // - ALLOW_LEADING_SPACES: skip over leading spaces.
+ // - ALLOW_TRAILING_SPACES: ignore trailing spaces.
+ // - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign.
+ // Ex: StringToDouble("- 123.2") -> -123.2.
+ // StringToDouble("+ 123.2") -> 123.2
+ //
+ // empty_string_value is returned when an empty string is given as input.
+ // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
+ // containing only spaces is converted to the 'empty_string_value', too.
+ //
+ // junk_string_value is returned when
+ // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not
+ // part of a double-literal) is found.
+ // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a
+ // double literal.
+ //
+ // infinity_symbol and nan_symbol are strings that are used to detect
+ // inputs that represent infinity and NaN. They can be null, in which case
+ // they are ignored.
+ // The conversion routine first reads any possible signs. Then it compares the
+ // following character of the input-string with the first character of
+ // the infinity, and nan-symbol. If either matches, the function assumes, that
+ // a match has been found, and expects the following input characters to match
+ // the remaining characters of the special-value symbol.
+ // This means that the following restrictions apply to special-value symbols:
+ // - they must not start with signs ('+', or '-'),
+ // - they must not have the same first character.
+ // - they must not start with digits.
+ //
+ // Examples:
+ // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
+ // empty_string_value = 0.0,
+ // junk_string_value = NaN,
+ // infinity_symbol = "infinity",
+ // nan_symbol = "nan":
+ // StringToDouble("0x1234") -> 4660.0.
+ // StringToDouble("0x1234K") -> 4660.0.
+ // StringToDouble("") -> 0.0 // empty_string_value.
+ // StringToDouble(" ") -> NaN // junk_string_value.
+ // StringToDouble(" 1") -> NaN // junk_string_value.
+ // StringToDouble("0x") -> NaN // junk_string_value.
+ // StringToDouble("-123.45") -> -123.45.
+ // StringToDouble("--123.45") -> NaN // junk_string_value.
+ // StringToDouble("123e45") -> 123e45.
+ // StringToDouble("123E45") -> 123e45.
+ // StringToDouble("123e+45") -> 123e45.
+ // StringToDouble("123E-45") -> 123e-45.
+ // StringToDouble("123e") -> 123.0 // trailing junk ignored.
+ // StringToDouble("123e-") -> 123.0 // trailing junk ignored.
+ // StringToDouble("+NaN") -> NaN // NaN string literal.
+ // StringToDouble("-infinity") -> -inf. // infinity literal.
+ // StringToDouble("Infinity") -> NaN // junk_string_value.
+ //
+ // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES,
+ // empty_string_value = 0.0,
+ // junk_string_value = NaN,
+ // infinity_symbol = NULL,
+ // nan_symbol = NULL:
+ // StringToDouble("0x1234") -> NaN // junk_string_value.
+ // StringToDouble("01234") -> 668.0.
+ // StringToDouble("") -> 0.0 // empty_string_value.
+ // StringToDouble(" ") -> 0.0 // empty_string_value.
+ // StringToDouble(" 1") -> 1.0
+ // StringToDouble("0x") -> NaN // junk_string_value.
+ // StringToDouble("0123e45") -> NaN // junk_string_value.
+ // StringToDouble("01239E45") -> 1239e45.
+ // StringToDouble("-infinity") -> NaN // junk_string_value.
+ // StringToDouble("NaN") -> NaN // junk_string_value.
+ StringToDoubleConverter(int flags,
+ double empty_string_value,
+ double junk_string_value,
+ const char* infinity_symbol,
+ const char* nan_symbol)
+ : flags_(flags),
+ empty_string_value_(empty_string_value),
+ junk_string_value_(junk_string_value),
+ infinity_symbol_(infinity_symbol),
+ nan_symbol_(nan_symbol) {
+ }
+
+ // Performs the conversion.
+ // The output parameter 'processed_characters_count' is set to the number
+ // of characters that have been processed to read the number.
+ // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included
+ // in the 'processed_characters_count'. Trailing junk is never included.
+ double StringToDouble(const char* buffer,
+ int length,
+ int* processed_characters_count);
+
+ private:
+ const int flags_;
+ const double empty_string_value_;
+ const double junk_string_value_;
+ const char* const infinity_symbol_;
+ const char* const nan_symbol_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
+};
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
View
39 src/double.h
@@ -25,13 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef V8_DOUBLE_H_
-#define V8_DOUBLE_H_
+#ifndef DOUBLE_CONVERSION_DOUBLE_H_
+#define DOUBLE_CONVERSION_DOUBLE_H_
#include "diy-fp.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
// We assume that doubles and uint64_t have the same endianness.
static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
@@ -40,11 +39,10 @@ static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
// Helper functions for doubles.
class Double {
public:
- static const uint64_t kSignMask = V8_2PART_UINT64_C(0x80000000, 00000000);
- static const uint64_t kExponentMask = V8_2PART_UINT64_C(0x7FF00000, 00000000);
- static const uint64_t kSignificandMask =
- V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
- static const uint64_t kHiddenBit = V8_2PART_UINT64_C(0x00100000, 00000000);
+ static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000);
+ static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000);
+ static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+ static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
static const int kSignificandSize = 53;
@@ -154,7 +152,7 @@ class Double {
return DiyFp(Significand() * 2 + 1, Exponent() - 1);
}
- // Returns the two boundaries of this.
+ // Computes the two boundaries of this.
// The bigger boundary (m_plus) is normalized. The lower boundary has the same
// exponent as m_plus.
// Precondition: the value encoded by this Double must be greater than 0.
@@ -186,9 +184,9 @@ class Double {
// Returns the significand size for a given order of magnitude.
// If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude.
// This function returns the number of significant binary digits v will have
- // once its encoded into a double. In almost all cases this is equal to
- // kSignificandSize. The only exception are denormals. They start with leading
- // zeroes and their effective significand-size is hence smaller.
+ // once it's encoded into a double. In almost all cases this is equal to
+ // kSignificandSize. The only exceptions are denormals. They start with
+ // leading zeroes and their effective significand-size is hence smaller.
static int SignificandSizeForOrderOfMagnitude(int order) {
if (order >= (kDenormalExponent + kSignificandSize)) {
return kSignificandSize;
@@ -197,11 +195,20 @@ class Double {
return order - kDenormalExponent;
}
+ static double Infinity() {
+ return Double(kInfinity).value();
+ }
+
+ static double NaN() {
+ return Double(kNaN).value();
+ }
+
private:
static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
static const int kDenormalExponent = -kExponentBias + 1;
static const int kMaxExponent = 0x7FF - kExponentBias;
- static const uint64_t kInfinity = V8_2PART_UINT64_C(0x7FF00000, 00000000);
+ static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
+ static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);
const uint64_t d64_;
@@ -233,6 +240,6 @@ class Double {
}
};
-} } // namespace v8::internal
+} // namespace double_conversion
-#endif // V8_DOUBLE_H_
+#endif // DOUBLE_CONVERSION_DOUBLE_H_
View
19 src/fast-dtoa.cc
@@ -25,16 +25,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "v8.h"
-
#include "fast-dtoa.h"
#include "cached-powers.h"
#include "diy-fp.h"
#include "double.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
// The minimal and maximal target exponent define the range of w's binary
// exponent, where 'w' is the result of multiplying the input by a cached power
@@ -48,7 +45,7 @@ static const int kMaximalTargetExponent = -32;
// Adjusts the last digit of the generated number, and screens out generated
// solutions that may be inaccurate. A solution may be inaccurate if it is
-// outside the safe interval, or if we ctannot prove that it is closer to the
+// outside the safe interval, or if we cannot prove that it is closer to the
// input than a neighboring representation of the same length.
//
// Input: * buffer containing the digits of too_high / 10^kappa
@@ -233,7 +230,7 @@ static const uint32_t kTen7 = 10000000;
static const uint32_t kTen8 = 100000000;
static const uint32_t kTen9 = 1000000000;
-// Returns the biggest power of ten that is less than or equal than the given
+// Returns the biggest power of ten that is less than or equal to the given
// number. We furthermore receive the maximum number of bits 'number' has.
// If number_bits == 0 then 0^-1 is returned
// The number of bits must be <= 32.
@@ -242,6 +239,8 @@ static void BiggestPowerTen(uint32_t number,
int number_bits,
uint32_t* power,
int* exponent) {
+ ASSERT(number < (1 << (number_bits + 1)));
+
switch (number_bits) {
case 32:
case 31:
@@ -458,7 +457,7 @@ static bool DigitGen(DiyFp low,
// and thus one.e >= -60.
ASSERT(one.e() >= -60);
ASSERT(fractionals < one.f());
- ASSERT(V8_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
+ ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
while (true) {
fractionals *= 10;
unit *= 10;
@@ -478,7 +477,7 @@ static bool DigitGen(DiyFp low,
-// Generates (at most) requested_digits of input number w.
+// Generates (at most) requested_digits digits of input number w.
// w is a floating-point number (DiyFp), consisting of a significand and an
// exponent. Its exponent is bounded by kMinimalTargetExponent and
// kMaximalTargetExponent.
@@ -566,7 +565,7 @@ static bool DigitGenCounted(DiyFp w,
// and thus one.e >= -60.
ASSERT(one.e() >= -60);
ASSERT(fractionals < one.f());
- ASSERT(V8_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
+ ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
while (requested_digits > 0 && fractionals > w_error) {
fractionals *= 10;
w_error *= 10;
@@ -733,4 +732,4 @@ bool FastDtoa(double v,
return result;
}
-} } // namespace v8::internal
+} // namespace double_conversion
View
13 src/fast-dtoa.h
@@ -25,11 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef V8_FAST_DTOA_H_
-#define V8_FAST_DTOA_H_
+#ifndef DOUBLE_CONVERSION_FAST_DTOA_H_
+#define DOUBLE_CONVERSION_FAST_DTOA_H_
-namespace v8 {
-namespace internal {
+#include "utils.h"
+
+namespace double_conversion {
enum FastDtoaMode {
// Computes the shortest representation of the given input. The returned
@@ -78,6 +79,6 @@ bool FastDtoa(double d,
int* length,
int* decimal_point);
-} } // namespace v8::internal
+} // namespace double_conversion
-#endif // V8_FAST_DTOA_H_
+#endif // DOUBLE_CONVERSION_FAST_DTOA_H_
View
11 src/fixed-dtoa.cc
@@ -27,13 +27,10 @@
#include <math.h>
-#include "v8.h"
-
-#include "double.h"
#include "fixed-dtoa.h"
+#include "double.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
// Represents a 128bit type. This class should be replaced by a native type on
// platforms that support 128bit integers.
@@ -335,7 +332,7 @@ bool FastFixedDtoa(double v,
// The quotient delivers the first digits, and the remainder fits into a 64
// bit number.
// Dividing by 10^17 is equivalent to dividing by 5^17*2^17.
- const uint64_t kFive17 = V8_2PART_UINT64_C(0xB1, A2BC2EC5); // 5^17
+ const uint64_t kFive17 = UINT64_2PART_C(0xB1, A2BC2EC5); // 5^17
uint64_t divisor = kFive17;
int divisor_power = 17;
uint64_t dividend = significand;
@@ -402,4 +399,4 @@ bool FastFixedDtoa(double v,
return true;
}
-} } // namespace v8::internal
+} // namespace double_conversion
View
13 src/fixed-dtoa.h
@@ -25,11 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef V8_FIXED_DTOA_H_
-#define V8_FIXED_DTOA_H_
+#ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_
+#define DOUBLE_CONVERSION_FIXED_DTOA_H_
-namespace v8 {
-namespace internal {
+#include "utils.h"
+
+namespace double_conversion {
// Produces digits necessary to print a given number with
// 'fractional_count' digits after the decimal point.
@@ -50,6 +51,6 @@ namespace internal {
bool FastFixedDtoa(double v, int fractional_count,
Vector<char> buffer, int* length, int* decimal_point);
-} } // namespace v8::internal
+} // namespace double_conversion
-#endif // V8_FIXED_DTOA_H_
+#endif // DOUBLE_CONVERSION_FIXED_DTOA_H_
View
35 src/strtod.cc
@@ -28,15 +28,12 @@
#include <stdarg.h>
#include <limits.h>
-#include "v8.h"
-
#include "strtod.h"
#include "bignum.h"
#include "cached-powers.h"
#include "double.h"
-namespace v8 {
-namespace internal {
+namespace double_conversion {
// 2^53 = 9007199254740992.
// Any integer with at most 15 decimal digits will hence fit into a double
@@ -55,7 +52,7 @@ static const int kMaxDecimalPower = 309;
static const int kMinDecimalPower = -324;
// 2^64 = 18446744073709551616
-static const uint64_t kMaxUint64 = V8_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF);
+static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF);
static const double exact_powers_of_ten[] = {
@@ -175,7 +172,7 @@ static void ReadDiyFp(Vector<const char> buffer,
static bool DoubleStrtod(Vector<const char> trimmed,
int exponent,
double* result) {
-#if (defined(V8_TARGET_ARCH_IA32) || defined(USE_SIMULATOR)) && !defined(WIN32)
+#if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS)
// On x86 the floating-point stack can be 64 or 80 bits wide. If it is
// 80 bits wide (as is the case on Linux) then double-rounding occurs and the
// result is not accurate.
@@ -233,13 +230,13 @@ static DiyFp AdjustmentPowerOfTen(int exponent) {
// distance.
ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
switch (exponent) {
- case 1: return DiyFp(V8_2PART_UINT64_C(0xa0000000, 00000000), -60);
- case 2: return DiyFp(V8_2PART_UINT64_C(0xc8000000, 00000000), -57);
- case 3: return DiyFp(V8_2PART_UINT64_C(0xfa000000, 00000000), -54);
- case 4: return DiyFp(V8_2PART_UINT64_C(0x9c400000, 00000000), -50);
- case 5: return DiyFp(V8_2PART_UINT64_C(0xc3500000, 00000000), -47);
- case 6: return DiyFp(V8_2PART_UINT64_C(0xf4240000, 00000000), -44);
- case 7: return DiyFp(V8_2PART_UINT64_C(0x98968000, 00000000), -40);
+ case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60);
+ case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57);
+ case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54);
+ case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50);
+ case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47);
+ case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44);
+ case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
default:
UNREACHABLE();
return DiyFp(0, 0);
@@ -370,7 +367,7 @@ static bool DiyFpStrtod(Vector<const char> buffer,
static double BignumStrtod(Vector<const char> buffer,
int exponent,
double guess) {
- if (guess == V8_INFINITY) {
+ if (guess == Double::Infinity()) {
return guess;
}
@@ -426,8 +423,12 @@ double Strtod(Vector<const char> buffer, int exponent) {
kMaxSignificantDecimalDigits),
significant_exponent);
}
- if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) return V8_INFINITY;
- if (exponent + trimmed.length() <= kMinDecimalPower) return 0.0;
+ if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) {
+ return Double::Infinity();
+ }
+ if (exponent + trimmed.length() <= kMinDecimalPower) {
+ return 0.0;
+ }
double guess;
if (DoubleStrtod(trimmed, exponent, &guess) ||
@@ -437,4 +438,4 @@ double Strtod(Vector<const char> buffer, int exponent) {
return BignumStrtod(trimmed, exponent, guess);
}
-} } // namespace v8::internal
+} // namespace double_conversion
View
13 src/strtod.h