Permalink
Browse files

Sync with upstream git repo

commit e5b3442

--HG--
rename : double-conversion/src/double.h => double-conversion/src/ieee.h
  • Loading branch information...
1 parent 88c27fc commit 64206912a2b294e2ee83109c154576f72602a408 @bos committed Dec 31, 2012
View
@@ -0,0 +1,12 @@
+# Below is a list of people and organizations that have contributed
+# to the double-conversion project. Names should be added to the
+# list like so:
+#
+# Name/Organization <email address>
+
+Google Inc.
+Mozilla Foundation
+
+Jeff Muizelaar <jmuizelaar@mozilla.com>
+Mike Hommey <mhommey@mozilla.com>
+Martin Olsson <mnemo@minimum.se>
@@ -0,0 +1,11 @@
+2012-06-10:
+ Tagged v1.1.1.
+ Null terminate exponent buffer (only an issue when asserts are enabled).
+ Support more architectures.
+
+2012-02-05:
+ Merged in Single-branch with single-precision support.
+ Tagged v1.1 (based on b28450f33e1db493948a535d8f84e88fa211bd10).
+
+2012-02-05:
+ Tagged v1.0 (based on eda0196e9ac8fcdf59e92cb62885ee0af5391969).
@@ -2,10 +2,13 @@ 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')
+env = Environment(CPPPATH='#/src', LIBS=['m', 'stdc++'])
debug = ARGUMENTS.get('debug', 0)
+optimize = ARGUMENTS.get('optimize', 0)
if int(debug):
- env.Append(CCFLAGS = '-g')
+ env.Append(CCFLAGS = '-g -Wall -Werror')
+if int(optimize):
+ env.Append(CCFLAGS = '-O3')
print double_conversion_sources
print double_conversion_test_sources
env.Program('run_tests', double_conversion_sources + double_conversion_test_sources)
@@ -30,7 +30,7 @@
#include "bignum-dtoa.h"
#include "bignum.h"
-#include "double.h"
+#include "ieee.h"
namespace double_conversion {
@@ -49,7 +49,9 @@ static int NormalizedExponent(uint64_t significand, int exponent) {
static int EstimatePower(int exponent);
// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
// and denominator.
-static void InitialScaledStartValues(double v,
+static void InitialScaledStartValues(uint64_t significand,
+ int exponent,
+ bool lower_boundary_is_closer,
int estimated_power,
bool need_boundary_deltas,
Bignum* numerator,
@@ -88,9 +90,24 @@ void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
Vector<char> buffer, int* length, int* decimal_point) {
ASSERT(v > 0);
ASSERT(!Double(v).IsSpecial());
- uint64_t significand = Double(v).Significand();
+ uint64_t significand;
+ int exponent;
+ bool lower_boundary_is_closer;
+ if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) {
+ float f = static_cast<float>(v);
+ ASSERT(f == v);
+ significand = Single(f).Significand();
+ exponent = Single(f).Exponent();
+ lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser();
+ } else {
+ significand = Double(v).Significand();
+ exponent = Double(v).Exponent();
+ lower_boundary_is_closer = Double(v).LowerBoundaryIsCloser();
+ }
+ bool need_boundary_deltas =
+ (mode == BIGNUM_DTOA_SHORTEST || mode == BIGNUM_DTOA_SHORTEST_SINGLE);
+
bool is_even = (significand & 1) == 0;
- int exponent = Double(v).Exponent();
int normalized_exponent = NormalizedExponent(significand, exponent);
// estimated_power might be too low by 1.
int estimated_power = EstimatePower(normalized_exponent);
@@ -118,8 +135,8 @@ void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
// The maximum double is 1.7976931348623157e308 which needs fewer than
// 308*4 binary digits.
ASSERT(Bignum::kMaxSignificantBits >= 324*4);
- bool need_boundary_deltas = (mode == BIGNUM_DTOA_SHORTEST);
- InitialScaledStartValues(v, estimated_power, need_boundary_deltas,
+ InitialScaledStartValues(significand, exponent, lower_boundary_is_closer,
+ estimated_power, need_boundary_deltas,
&numerator, &denominator,
&delta_minus, &delta_plus);
// We now have v = (numerator / denominator) * 10^estimated_power.
@@ -130,6 +147,7 @@ void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
// 1 <= (numerator + delta_plus) / denominator < 10
switch (mode) {
case BIGNUM_DTOA_SHORTEST:
+ case BIGNUM_DTOA_SHORTEST_SINGLE:
GenerateShortestDigits(&numerator, &denominator,
&delta_minus, &delta_plus,
is_even, buffer, length);
@@ -388,15 +406,16 @@ static int EstimatePower(int exponent) {
const double k1Log10 = 0.30102999566398114; // 1/lg(10)
// For doubles len(f) == 53 (don't forget the hidden bit).
- const int kSignificandSize = 53;
+ const int kSignificandSize = Double::kSignificandSize;
double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
return static_cast<int>(estimate);
}
// See comments for InitialScaledStartValues.
static void InitialScaledStartValuesPositiveExponent(
- double v, int estimated_power, bool need_boundary_deltas,
+ uint64_t significand, int exponent,
+ int estimated_power, bool need_boundary_deltas,
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
// A positive exponent implies a positive power.
@@ -405,8 +424,8 @@ static void InitialScaledStartValuesPositiveExponent(
// by 10^estimated_power.
// numerator = v.
- numerator->AssignUInt64(Double(v).Significand());
- numerator->ShiftLeft(Double(v).Exponent());
+ numerator->AssignUInt64(significand);
+ numerator->ShiftLeft(exponent);
// denominator = 10^estimated_power.
denominator->AssignPowerUInt16(10, estimated_power);
@@ -418,35 +437,20 @@ static void InitialScaledStartValuesPositiveExponent(
// Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
// denominator (of 2) delta_plus equals 2^e.
delta_plus->AssignUInt16(1);
- delta_plus->ShiftLeft(Double(v).Exponent());
- // Same for delta_minus (with adjustments below if f == 2^p-1).
+ delta_plus->ShiftLeft(exponent);
+ // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
delta_minus->AssignUInt16(1);
- delta_minus->ShiftLeft(Double(v).Exponent());
-
- // If the significand (without the hidden bit) is 0, then the lower
- // boundary is closer than just half a ulp (unit in the last place).
- // There is only one exception: if the next lower number is a denormal then
- // the distance is 1 ulp. This cannot be the case for exponent >= 0 (but we
- // have to test it in the other function where exponent < 0).
- uint64_t v_bits = Double(v).AsUint64();
- if ((v_bits & Double::kSignificandMask) == 0) {
- // The lower boundary is closer at half the distance of "normal" numbers.
- // Increase the common denominator and adapt all but the delta_minus.
- denominator->ShiftLeft(1); // *2
- numerator->ShiftLeft(1); // *2
- delta_plus->ShiftLeft(1); // *2
- }
+ delta_minus->ShiftLeft(exponent);
}
}
// See comments for InitialScaledStartValues
static void InitialScaledStartValuesNegativeExponentPositivePower(
- double v, int estimated_power, bool need_boundary_deltas,
+ uint64_t significand, int exponent,
+ int estimated_power, bool need_boundary_deltas,
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
- uint64_t significand = Double(v).Significand();
- int exponent = Double(v).Exponent();
// v = f * 2^e with e < 0, and with estimated_power >= 0.
// This means that e is close to 0 (have a look at how estimated_power is
// computed).
@@ -469,36 +473,18 @@ static void InitialScaledStartValuesNegativeExponentPositivePower(
// Given that the denominator already includes v's exponent the distance
// to the boundaries is simply 1.
delta_plus->AssignUInt16(1);
- // Same for delta_minus (with adjustments below if f == 2^p-1).
+ // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
delta_minus->AssignUInt16(1);
-
- // If the significand (without the hidden bit) is 0, then the lower
- // boundary is closer than just one ulp (unit in the last place).
- // There is only one exception: if the next lower number is a denormal
- // then the distance is 1 ulp. Since the exponent is close to zero
- // (otherwise estimated_power would have been negative) this cannot happen
- // here either.
- uint64_t v_bits = Double(v).AsUint64();
- if ((v_bits & Double::kSignificandMask) == 0) {
- // The lower boundary is closer at half the distance of "normal" numbers.
- // Increase the denominator and adapt all but the delta_minus.
- denominator->ShiftLeft(1); // *2
- numerator->ShiftLeft(1); // *2
- delta_plus->ShiftLeft(1); // *2
- }
}
}
// See comments for InitialScaledStartValues
static void InitialScaledStartValuesNegativeExponentNegativePower(
- double v, int estimated_power, bool need_boundary_deltas,
+ uint64_t significand, int exponent,
+ int estimated_power, bool need_boundary_deltas,
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
- const uint64_t kMinimalNormalizedExponent =
- 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
// multiply all values (numerator and deltas) by 10^-estimated_power.
@@ -535,18 +521,7 @@ static void InitialScaledStartValuesNegativeExponentNegativePower(
// delta_plus = 10^-estimated_power, and
// delta_minus = 10^-estimated_power.
// These assignments have been done earlier.
-
- // The special case where the lower boundary is twice as close.
- // This time we have to look out for the exception too.
- uint64_t v_bits = Double(v).AsUint64();
- if ((v_bits & Double::kSignificandMask) == 0 &&
- // The only exception where a significand == 0 has its boundaries at
- // "normal" distances:
- (v_bits & Double::kExponentMask) != kMinimalNormalizedExponent) {
- numerator->ShiftLeft(1); // *2
- denominator->ShiftLeft(1); // *2
- delta_plus->ShiftLeft(1); // *2
- }
+ // The adjustments if f == 2^p-1 (lower boundary is closer) are done later.
}
}
@@ -586,27 +561,39 @@ static void InitialScaledStartValuesNegativeExponentNegativePower(
//
// It is then easy to kickstart the digit-generation routine.
//
-// The boundary-deltas are only filled if need_boundary_deltas is set.
-static void InitialScaledStartValues(double v,
+// The boundary-deltas are only filled if the mode equals BIGNUM_DTOA_SHORTEST
+// or BIGNUM_DTOA_SHORTEST_SINGLE.
+
+static void InitialScaledStartValues(uint64_t significand,
+ int exponent,
+ bool lower_boundary_is_closer,
int estimated_power,
bool need_boundary_deltas,
Bignum* numerator,
Bignum* denominator,
Bignum* delta_minus,
Bignum* delta_plus) {
- if (Double(v).Exponent() >= 0) {
+ if (exponent >= 0) {
InitialScaledStartValuesPositiveExponent(
- v, estimated_power, need_boundary_deltas,
+ significand, exponent, estimated_power, need_boundary_deltas,
numerator, denominator, delta_minus, delta_plus);
} else if (estimated_power >= 0) {
InitialScaledStartValuesNegativeExponentPositivePower(
- v, estimated_power, need_boundary_deltas,
+ significand, exponent, estimated_power, need_boundary_deltas,
numerator, denominator, delta_minus, delta_plus);
} else {
InitialScaledStartValuesNegativeExponentNegativePower(
- v, estimated_power, need_boundary_deltas,
+ significand, exponent, estimated_power, need_boundary_deltas,
numerator, denominator, delta_minus, delta_plus);
}
+
+ if (need_boundary_deltas && lower_boundary_is_closer) {
+ // The lower boundary is closer at half the distance of "normal" numbers.
+ // Increase the common denominator and adapt all but the delta_minus.
+ denominator->ShiftLeft(1); // *2
+ numerator->ShiftLeft(1); // *2
+ delta_plus->ShiftLeft(1); // *2
+ }
}
@@ -37,6 +37,8 @@ enum BignumDtoaMode {
// For example the output of 0.299999999999999988897 is (the less accurate but
// correct) 0.3.
BIGNUM_DTOA_SHORTEST,
+ // Same as BIGNUM_DTOA_SHORTEST but for single-precision floats.
+ BIGNUM_DTOA_SHORTEST_SINGLE,
// Return 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.
@@ -69,6 +69,10 @@ class Bignum {
bool ToHexString(char* buffer, int buffer_size) const;
+ // Returns
+ // -1 if a < b,
+ // 0 if a == b, and
+ // +1 if a > b.
static int Compare(const Bignum& a, const Bignum& b);
static bool Equal(const Bignum& a, const Bignum& b) {
return Compare(a, b) == 0;
@@ -132,14 +132,12 @@ static const CachedPower kCachedPowers[] = {
};
static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers);
-static const int kCachedPowersOffset = -kCachedPowers[0].decimal_exponent;
+static const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent.
static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10)
-const int PowersOfTenCache::kDecimalExponentDistance =
- kCachedPowers[1].decimal_exponent - kCachedPowers[0].decimal_exponent;
-const int PowersOfTenCache::kMinDecimalExponent =
- kCachedPowers[0].decimal_exponent;
-const int PowersOfTenCache::kMaxDecimalExponent =
- kCachedPowers[kCachedPowersLength - 1].decimal_exponent;
+// Difference between the decimal exponents in the table above.
+const int PowersOfTenCache::kDecimalExponentDistance = 8;
+const int PowersOfTenCache::kMinDecimalExponent = -348;
+const int PowersOfTenCache::kMaxDecimalExponent = 340;
void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
int min_exponent,
Oops, something went wrong.

0 comments on commit 6420691

Please sign in to comment.