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 |