| Index: src/double.h
|
| diff --git a/src/double.h b/src/double.h
|
| index 65f8c9444b0bb25295de9694208d634fa4edf49f..a17242fbddfcbb1436870e4a9cc64ae87b1c6c80 100644
|
| --- a/src/double.h
|
| +++ b/src/double.h
|
| @@ -45,10 +45,14 @@ class Double {
|
| static const uint64_t kSignificandMask =
|
| V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
|
| static const uint64_t kHiddenBit = V8_2PART_UINT64_C(0x00100000, 00000000);
|
| + static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
|
| + static const int kSignificandSize = 53;
|
|
|
| Double() : d64_(0) {}
|
| explicit Double(double d) : d64_(double_to_uint64(d)) {}
|
| explicit Double(uint64_t d64) : d64_(d64) {}
|
| + Double(uint64_t significand, int exponent)
|
| + : d64_(SignificandExponentToUint64(significand, exponent)) {}
|
|
|
| DiyFp AsDiyFp() const {
|
| ASSERT(!IsSpecial());
|
| @@ -67,9 +71,9 @@ class Double {
|
| f <<= 1;
|
| e--;
|
| }
|
| - // Do the final shifts in one go. Don't forget the hidden bit (the '-1').
|
| - f <<= DiyFp::kSignificandSize - kSignificandSize - 1;
|
| - e -= DiyFp::kSignificandSize - kSignificandSize - 1;
|
| + // Do the final shifts in one go.
|
| + f <<= DiyFp::kSignificandSize - kSignificandSize;
|
| + e -= DiyFp::kSignificandSize - kSignificandSize;
|
| return DiyFp(f, e);
|
| }
|
|
|
| @@ -82,7 +86,8 @@ class Double {
|
| if (IsDenormal()) return kDenormalExponent;
|
|
|
| uint64_t d64 = AsUint64();
|
| - int biased_e = static_cast<int>((d64 & kExponentMask) >> kSignificandSize);
|
| + int biased_e =
|
| + static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize);
|
| return biased_e - kExponentBias;
|
| }
|
|
|
| @@ -156,12 +161,48 @@ class Double {
|
|
|
| double value() const { return uint64_to_double(d64_); }
|
|
|
| + // 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.
|
| + static int SignificandSizeForOrderOfMagnitude(int order) {
|
| + if (order >= (kDenormalExponent + kSignificandSize)) {
|
| + return kSignificandSize;
|
| + }
|
| + if (order <= kDenormalExponent) return 0;
|
| + return order - kDenormalExponent;
|
| + }
|
| +
|
| private:
|
| - static const int kSignificandSize = 52; // Excludes the hidden bit.
|
| - static const int kExponentBias = 0x3FF + kSignificandSize;
|
| + static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
|
| static const int kDenormalExponent = -kExponentBias + 1;
|
| -
|
| - uint64_t d64_;
|
| + static const int kMaxExponent = 0x7FF - kExponentBias;
|
| + static const uint64_t kInfinity = V8_2PART_UINT64_C(0x7FF00000, 00000000);
|
| +
|
| + const uint64_t d64_;
|
| +
|
| + static uint64_t SignificandExponentToUint64(uint64_t significand,
|
| + int exponent) {
|
| + ASSERT(significand <= kSignificandMask + kHiddenBit);
|
| + ASSERT(((significand & kHiddenBit) != 0) || exponent <= kDenormalExponent);
|
| + // Clamp.
|
| + if (exponent < kDenormalExponent) {
|
| + return 0;
|
| + }
|
| + if (exponent >= kMaxExponent) {
|
| + return kInfinity;
|
| + }
|
| + uint64_t biased_exponent;
|
| + if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) {
|
| + biased_exponent = 0;
|
| + } else {
|
| + biased_exponent = static_cast<uint64_t>(exponent + kExponentBias);
|
| + }
|
| + return (significand & kSignificandMask) |
|
| + (biased_exponent << kPhysicalSignificandSize);
|
| + }
|
| };
|
|
|
| } } // namespace v8::internal
|
|
|