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 explicit Double(DiyFp diy_fp) |
| 55 : d64_(DiyFpToUint64(diy_fp)) {} |
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 DiyFpToUint64(DiyFp diy_fp) { |
| 187 uint64_t significand = diy_fp.f(); |
| 188 int exponent = diy_fp.e(); |
| 189 while (significand > kHiddenBit + kSignificandMask) { |
| 190 significand >>= 1; |
| 191 exponent++; |
| 192 } |
| 193 if (exponent >= kMaxExponent) { |
| 194 return kInfinity; |
| 195 } |
| 196 if (exponent < kDenormalExponent) { |
| 197 return 0; |
| 198 } |
| 199 while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) { |
| 200 significand <<= 1; |
| 201 exponent--; |
| 202 } |
| 203 uint64_t biased_exponent; |
| 204 if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) { |
| 205 biased_exponent = 0; |
| 206 } else { |
| 207 biased_exponent = static_cast<uint64_t>(exponent + kExponentBias); |
| 208 } |
| 209 return (significand & kSignificandMask) | |
| 210 (biased_exponent << kPhysicalSignificandSize); |
| 211 } |
165 }; | 212 }; |
166 | 213 |
167 } } // namespace v8::internal | 214 } } // namespace v8::internal |
168 | 215 |
169 #endif // V8_DOUBLE_H_ | 216 #endif // V8_DOUBLE_H_ |
OLD | NEW |