| 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; | |
| 50 | 48 |
| 51 Double() : d64_(0) {} | 49 Double() : d64_(0) {} |
| 52 explicit Double(double d) : d64_(double_to_uint64(d)) {} | 50 explicit Double(double d) : d64_(double_to_uint64(d)) {} |
| 53 explicit Double(uint64_t d64) : d64_(d64) {} | 51 explicit Double(uint64_t d64) : d64_(d64) {} |
| 54 Double(uint64_t significand, int exponent) | |
| 55 : d64_(SignificandExponentToUint64(significand, exponent)) {} | |
| 56 | 52 |
| 57 DiyFp AsDiyFp() const { | 53 DiyFp AsDiyFp() const { |
| 58 ASSERT(!IsSpecial()); | 54 ASSERT(!IsSpecial()); |
| 59 return DiyFp(Significand(), Exponent()); | 55 return DiyFp(Significand(), Exponent()); |
| 60 } | 56 } |
| 61 | 57 |
| 62 // this->Significand() must not be 0. | 58 // this->Significand() must not be 0. |
| 63 DiyFp AsNormalizedDiyFp() const { | 59 DiyFp AsNormalizedDiyFp() const { |
| 64 uint64_t f = Significand(); | 60 uint64_t f = Significand(); |
| 65 int e = Exponent(); | 61 int e = Exponent(); |
| 66 | 62 |
| 67 ASSERT(f != 0); | 63 ASSERT(f != 0); |
| 68 | 64 |
| 69 // The current double could be a denormal. | 65 // The current double could be a denormal. |
| 70 while ((f & kHiddenBit) == 0) { | 66 while ((f & kHiddenBit) == 0) { |
| 71 f <<= 1; | 67 f <<= 1; |
| 72 e--; | 68 e--; |
| 73 } | 69 } |
| 74 // Do the final shifts in one go. | 70 // Do the final shifts in one go. Don't forget the hidden bit (the '-1'). |
| 75 f <<= DiyFp::kSignificandSize - kSignificandSize; | 71 f <<= DiyFp::kSignificandSize - kSignificandSize - 1; |
| 76 e -= DiyFp::kSignificandSize - kSignificandSize; | 72 e -= DiyFp::kSignificandSize - kSignificandSize - 1; |
| 77 return DiyFp(f, e); | 73 return DiyFp(f, e); |
| 78 } | 74 } |
| 79 | 75 |
| 80 // Returns the double's bit as uint64. | 76 // Returns the double's bit as uint64. |
| 81 uint64_t AsUint64() const { | 77 uint64_t AsUint64() const { |
| 82 return d64_; | 78 return d64_; |
| 83 } | 79 } |
| 84 | 80 |
| 85 int Exponent() const { | 81 int Exponent() const { |
| 86 if (IsDenormal()) return kDenormalExponent; | 82 if (IsDenormal()) return kDenormalExponent; |
| 87 | 83 |
| 88 uint64_t d64 = AsUint64(); | 84 uint64_t d64 = AsUint64(); |
| 89 int biased_e = | 85 int biased_e = static_cast<int>((d64 & kExponentMask) >> kSignificandSize); |
| 90 static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize); | |
| 91 return biased_e - kExponentBias; | 86 return biased_e - kExponentBias; |
| 92 } | 87 } |
| 93 | 88 |
| 94 uint64_t Significand() const { | 89 uint64_t Significand() const { |
| 95 uint64_t d64 = AsUint64(); | 90 uint64_t d64 = AsUint64(); |
| 96 uint64_t significand = d64 & kSignificandMask; | 91 uint64_t significand = d64 & kSignificandMask; |
| 97 if (!IsDenormal()) { | 92 if (!IsDenormal()) { |
| 98 return significand + kHiddenBit; | 93 return significand + kHiddenBit; |
| 99 } else { | 94 } else { |
| 100 return significand; | 95 return significand; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1); | 149 m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1); |
| 155 } | 150 } |
| 156 m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e())); | 151 m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e())); |
| 157 m_minus.set_e(m_plus.e()); | 152 m_minus.set_e(m_plus.e()); |
| 158 *out_m_plus = m_plus; | 153 *out_m_plus = m_plus; |
| 159 *out_m_minus = m_minus; | 154 *out_m_minus = m_minus; |
| 160 } | 155 } |
| 161 | 156 |
| 162 double value() const { return uint64_to_double(d64_); } | 157 double value() const { return uint64_to_double(d64_); } |
| 163 | 158 |
| 164 // Returns the significand size for a given order of magnitude. | 159 private: |
| 165 // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude. | 160 static const int kSignificandSize = 52; // Excludes the hidden bit. |
| 166 // This function returns the number of significant binary digits v will have | 161 static const int kExponentBias = 0x3FF + kSignificandSize; |
| 167 // once its encoded into a double. In almost all cases this is equal to | 162 static const int kDenormalExponent = -kExponentBias + 1; |
| 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 | 163 |
| 178 private: | 164 uint64_t d64_; |
| 179 static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; | |
| 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); | |
| 183 | |
| 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 } | |
| 206 }; | 165 }; |
| 207 | 166 |
| 208 } } // namespace v8::internal | 167 } } // namespace v8::internal |
| 209 | 168 |
| 210 #endif // V8_DOUBLE_H_ | 169 #endif // V8_DOUBLE_H_ |
| OLD | NEW |