| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); } | 38 static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); } |
| 39 | 39 |
| 40 // Helper functions for doubles. | 40 // Helper functions for doubles. |
| 41 class Double { | 41 class Double { |
| 42 public: | 42 public: |
| 43 static const uint64_t kSignMask = V8_2PART_UINT64_C(0x80000000, 00000000); | 43 static const uint64_t kSignMask = V8_2PART_UINT64_C(0x80000000, 00000000); |
| 44 static const uint64_t kExponentMask = V8_2PART_UINT64_C(0x7FF00000, 00000000); | 44 static const uint64_t kExponentMask = V8_2PART_UINT64_C(0x7FF00000, 00000000); |
| 45 static const uint64_t kSignificandMask = | 45 static const uint64_t kSignificandMask = |
| 46 V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); | 46 V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); |
| 47 static const uint64_t kHiddenBit = V8_2PART_UINT64_C(0x00100000, 00000000); | 47 static const uint64_t kHiddenBit = V8_2PART_UINT64_C(0x00100000, 00000000); |
| 48 static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. |
| 49 static const int kSignificandSize = 53; |
| 48 | 50 |
| 49 Double() : d64_(0) {} | 51 Double() : d64_(0) {} |
| 50 explicit Double(double d) : d64_(double_to_uint64(d)) {} | 52 explicit Double(double d) : d64_(double_to_uint64(d)) {} |
| 51 explicit Double(uint64_t d64) : d64_(d64) {} | 53 explicit Double(uint64_t d64) : d64_(d64) {} |
| 54 Double(uint64_t significand, int exponent) |
| 55 : d64_(SignificandExponentToUint64(significand, exponent)) {} |
| 52 | 56 |
| 53 DiyFp AsDiyFp() const { | 57 DiyFp AsDiyFp() const { |
| 54 ASSERT(!IsSpecial()); | 58 ASSERT(!IsSpecial()); |
| 55 return DiyFp(Significand(), Exponent()); | 59 return DiyFp(Significand(), Exponent()); |
| 56 } | 60 } |
| 57 | 61 |
| 58 // this->Significand() must not be 0. | 62 // this->Significand() must not be 0. |
| 59 DiyFp AsNormalizedDiyFp() const { | 63 DiyFp AsNormalizedDiyFp() const { |
| 60 uint64_t f = Significand(); | 64 uint64_t f = Significand(); |
| 61 int e = Exponent(); | 65 int e = Exponent(); |
| 62 | 66 |
| 63 ASSERT(f != 0); | 67 ASSERT(f != 0); |
| 64 | 68 |
| 65 // The current double could be a denormal. | 69 // The current double could be a denormal. |
| 66 while ((f & kHiddenBit) == 0) { | 70 while ((f & kHiddenBit) == 0) { |
| 67 f <<= 1; | 71 f <<= 1; |
| 68 e--; | 72 e--; |
| 69 } | 73 } |
| 70 // Do the final shifts in one go. Don't forget the hidden bit (the '-1'). | 74 // Do the final shifts in one go. |
| 71 f <<= DiyFp::kSignificandSize - kSignificandSize - 1; | 75 f <<= DiyFp::kSignificandSize - kSignificandSize; |
| 72 e -= DiyFp::kSignificandSize - kSignificandSize - 1; | 76 e -= DiyFp::kSignificandSize - kSignificandSize; |
| 73 return DiyFp(f, e); | 77 return DiyFp(f, e); |
| 74 } | 78 } |
| 75 | 79 |
| 76 // Returns the double's bit as uint64. | 80 // Returns the double's bit as uint64. |
| 77 uint64_t AsUint64() const { | 81 uint64_t AsUint64() const { |
| 78 return d64_; | 82 return d64_; |
| 79 } | 83 } |
| 80 | 84 |
| 81 int Exponent() const { | 85 int Exponent() const { |
| 82 if (IsDenormal()) return kDenormalExponent; | 86 if (IsDenormal()) return kDenormalExponent; |
| 83 | 87 |
| 84 uint64_t d64 = AsUint64(); | 88 uint64_t d64 = AsUint64(); |
| 85 int biased_e = static_cast<int>((d64 & kExponentMask) >> kSignificandSize); | 89 int biased_e = |
| 90 static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize); |
| 86 return biased_e - kExponentBias; | 91 return biased_e - kExponentBias; |
| 87 } | 92 } |
| 88 | 93 |
| 89 uint64_t Significand() const { | 94 uint64_t Significand() const { |
| 90 uint64_t d64 = AsUint64(); | 95 uint64_t d64 = AsUint64(); |
| 91 uint64_t significand = d64 & kSignificandMask; | 96 uint64_t significand = d64 & kSignificandMask; |
| 92 if (!IsDenormal()) { | 97 if (!IsDenormal()) { |
| 93 return significand + kHiddenBit; | 98 return significand + kHiddenBit; |
| 94 } else { | 99 } else { |
| 95 return significand; | 100 return significand; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1); | 154 m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1); |
| 150 } | 155 } |
| 151 m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e())); | 156 m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e())); |
| 152 m_minus.set_e(m_plus.e()); | 157 m_minus.set_e(m_plus.e()); |
| 153 *out_m_plus = m_plus; | 158 *out_m_plus = m_plus; |
| 154 *out_m_minus = m_minus; | 159 *out_m_minus = m_minus; |
| 155 } | 160 } |
| 156 | 161 |
| 157 double value() const { return uint64_to_double(d64_); } | 162 double value() const { return uint64_to_double(d64_); } |
| 158 | 163 |
| 164 // Returns the significand size for a given order of magnitude. |
| 165 // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude. |
| 166 // This function returns the number of significant binary digits v will have |
| 167 // once its encoded into a double. In almost all cases this is equal to |
| 168 // kSignificandSize. The only exception are denormals. They start with leading |
| 169 // zeroes and their effective significand-size is hence smaller. |
| 170 static int SignificandSizeForOrderOfMagnitude(int order) { |
| 171 if (order >= (kDenormalExponent + kSignificandSize)) { |
| 172 return kSignificandSize; |
| 173 } |
| 174 if (order <= kDenormalExponent) return 0; |
| 175 return order - kDenormalExponent; |
| 176 } |
| 177 |
| 159 private: | 178 private: |
| 160 static const int kSignificandSize = 52; // Excludes the hidden bit. | 179 static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; |
| 161 static const int kExponentBias = 0x3FF + kSignificandSize; | |
| 162 static const int kDenormalExponent = -kExponentBias + 1; | 180 static const int kDenormalExponent = -kExponentBias + 1; |
| 181 static const int kMaxExponent = 0x7FF - kExponentBias; |
| 182 static const uint64_t kInfinity = V8_2PART_UINT64_C(0x7FF00000, 00000000); |
| 163 | 183 |
| 164 uint64_t d64_; | 184 const uint64_t d64_; |
| 185 |
| 186 static uint64_t SignificandExponentToUint64(uint64_t significand, |
| 187 int exponent) { |
| 188 ASSERT(significand <= kSignificandMask + kHiddenBit); |
| 189 ASSERT(((significand & kHiddenBit) != 0) || exponent <= kDenormalExponent); |
| 190 // Clamp. |
| 191 if (exponent < kDenormalExponent) { |
| 192 return 0; |
| 193 } |
| 194 if (exponent >= kMaxExponent) { |
| 195 return kInfinity; |
| 196 } |
| 197 uint64_t biased_exponent; |
| 198 if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) { |
| 199 biased_exponent = 0; |
| 200 } else { |
| 201 biased_exponent = static_cast<uint64_t>(exponent + kExponentBias); |
| 202 } |
| 203 return (significand & kSignificandMask) | |
| 204 (biased_exponent << kPhysicalSignificandSize); |
| 205 } |
| 165 }; | 206 }; |
| 166 | 207 |
| 167 } } // namespace v8::internal | 208 } } // namespace v8::internal |
| 168 | 209 |
| 169 #endif // V8_DOUBLE_H_ | 210 #endif // V8_DOUBLE_H_ |
| OLD | NEW |