OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_DOUBLE_H_ | 5 #ifndef V8_DOUBLE_H_ |
6 #define V8_DOUBLE_H_ | 6 #define V8_DOUBLE_H_ |
7 | 7 |
8 #include "src/diy-fp.h" | 8 #include "src/diy-fp.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 Double() : d64_(0) {} | 28 Double() : d64_(0) {} |
29 explicit Double(double d) : d64_(double_to_uint64(d)) {} | 29 explicit Double(double d) : d64_(double_to_uint64(d)) {} |
30 explicit Double(uint64_t d64) : d64_(d64) {} | 30 explicit Double(uint64_t d64) : d64_(d64) {} |
31 explicit Double(DiyFp diy_fp) | 31 explicit Double(DiyFp diy_fp) |
32 : d64_(DiyFpToUint64(diy_fp)) {} | 32 : d64_(DiyFpToUint64(diy_fp)) {} |
33 | 33 |
34 // The value encoded by this Double must be greater or equal to +0.0. | 34 // The value encoded by this Double must be greater or equal to +0.0. |
35 // It must not be special (infinity, or NaN). | 35 // It must not be special (infinity, or NaN). |
36 DiyFp AsDiyFp() const { | 36 DiyFp AsDiyFp() const { |
37 ASSERT(Sign() > 0); | 37 DCHECK(Sign() > 0); |
38 ASSERT(!IsSpecial()); | 38 DCHECK(!IsSpecial()); |
39 return DiyFp(Significand(), Exponent()); | 39 return DiyFp(Significand(), Exponent()); |
40 } | 40 } |
41 | 41 |
42 // The value encoded by this Double must be strictly greater than 0. | 42 // The value encoded by this Double must be strictly greater than 0. |
43 DiyFp AsNormalizedDiyFp() const { | 43 DiyFp AsNormalizedDiyFp() const { |
44 ASSERT(value() > 0.0); | 44 DCHECK(value() > 0.0); |
45 uint64_t f = Significand(); | 45 uint64_t f = Significand(); |
46 int e = Exponent(); | 46 int e = Exponent(); |
47 | 47 |
48 // The current double could be a denormal. | 48 // The current double could be a denormal. |
49 while ((f & kHiddenBit) == 0) { | 49 while ((f & kHiddenBit) == 0) { |
50 f <<= 1; | 50 f <<= 1; |
51 e--; | 51 e--; |
52 } | 52 } |
53 // Do the final shifts in one go. | 53 // Do the final shifts in one go. |
54 f <<= DiyFp::kSignificandSize - kSignificandSize; | 54 f <<= DiyFp::kSignificandSize - kSignificandSize; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 } | 114 } |
115 | 115 |
116 int Sign() const { | 116 int Sign() const { |
117 uint64_t d64 = AsUint64(); | 117 uint64_t d64 = AsUint64(); |
118 return (d64 & kSignMask) == 0? 1: -1; | 118 return (d64 & kSignMask) == 0? 1: -1; |
119 } | 119 } |
120 | 120 |
121 // Precondition: the value encoded by this Double must be greater or equal | 121 // Precondition: the value encoded by this Double must be greater or equal |
122 // than +0.0. | 122 // than +0.0. |
123 DiyFp UpperBoundary() const { | 123 DiyFp UpperBoundary() const { |
124 ASSERT(Sign() > 0); | 124 DCHECK(Sign() > 0); |
125 return DiyFp(Significand() * 2 + 1, Exponent() - 1); | 125 return DiyFp(Significand() * 2 + 1, Exponent() - 1); |
126 } | 126 } |
127 | 127 |
128 // Returns the two boundaries of this. | 128 // Returns the two boundaries of this. |
129 // The bigger boundary (m_plus) is normalized. The lower boundary has the same | 129 // The bigger boundary (m_plus) is normalized. The lower boundary has the same |
130 // exponent as m_plus. | 130 // exponent as m_plus. |
131 // Precondition: the value encoded by this Double must be greater than 0. | 131 // Precondition: the value encoded by this Double must be greater than 0. |
132 void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const { | 132 void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const { |
133 ASSERT(value() > 0.0); | 133 DCHECK(value() > 0.0); |
134 DiyFp v = this->AsDiyFp(); | 134 DiyFp v = this->AsDiyFp(); |
135 bool significand_is_zero = (v.f() == kHiddenBit); | 135 bool significand_is_zero = (v.f() == kHiddenBit); |
136 DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1)); | 136 DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1)); |
137 DiyFp m_minus; | 137 DiyFp m_minus; |
138 if (significand_is_zero && v.e() != kDenormalExponent) { | 138 if (significand_is_zero && v.e() != kDenormalExponent) { |
139 // The boundary is closer. Think of v = 1000e10 and v- = 9999e9. | 139 // The boundary is closer. Think of v = 1000e10 and v- = 9999e9. |
140 // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but | 140 // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but |
141 // at a distance of 1e8. | 141 // at a distance of 1e8. |
142 // The only exception is for the smallest normal: the largest denormal is | 142 // The only exception is for the smallest normal: the largest denormal is |
143 // at the same distance as its successor. | 143 // at the same distance as its successor. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 biased_exponent = static_cast<uint64_t>(exponent + kExponentBias); | 200 biased_exponent = static_cast<uint64_t>(exponent + kExponentBias); |
201 } | 201 } |
202 return (significand & kSignificandMask) | | 202 return (significand & kSignificandMask) | |
203 (biased_exponent << kPhysicalSignificandSize); | 203 (biased_exponent << kPhysicalSignificandSize); |
204 } | 204 } |
205 }; | 205 }; |
206 | 206 |
207 } } // namespace v8::internal | 207 } } // namespace v8::internal |
208 | 208 |
209 #endif // V8_DOUBLE_H_ | 209 #endif // V8_DOUBLE_H_ |
OLD | NEW |