00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef DOUBLE_CONVERSION_DOUBLE_H_
00029 #define DOUBLE_CONVERSION_DOUBLE_H_
00030
00031 #include "diy-fp.h"
00032
00033 namespace double_conversion {
00034
00035
00036 static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
00037 static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
00038 static uint32_t float_to_uint32(float f) { return BitCast<uint32_t>(f); }
00039 static float uint32_to_float(uint32_t d32) { return BitCast<float>(d32); }
00040
00041
00042 class Double {
00043 public:
00044 static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000);
00045 static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000);
00046 static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
00047 static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
00048 static const int kPhysicalSignificandSize = 52;
00049 static const int kSignificandSize = 53;
00050
00051 Double() : d64_(0) {}
00052 explicit Double(double d) : d64_(double_to_uint64(d)) {}
00053 explicit Double(uint64_t d64) : d64_(d64) {}
00054 explicit Double(DiyFp diy_fp)
00055 : d64_(DiyFpToUint64(diy_fp)) {}
00056
00057
00058
00059 DiyFp AsDiyFp() const {
00060 ASSERT(Sign() > 0);
00061 ASSERT(!IsSpecial());
00062 return DiyFp(Significand(), Exponent());
00063 }
00064
00065
00066 DiyFp AsNormalizedDiyFp() const {
00067 ASSERT(value() > 0.0);
00068 uint64_t f = Significand();
00069 int e = Exponent();
00070
00071
00072 while ((f & kHiddenBit) == 0) {
00073 f <<= 1;
00074 e--;
00075 }
00076
00077 f <<= DiyFp::kSignificandSize - kSignificandSize;
00078 e -= DiyFp::kSignificandSize - kSignificandSize;
00079 return DiyFp(f, e);
00080 }
00081
00082
00083 uint64_t AsUint64() const {
00084 return d64_;
00085 }
00086
00087
00088 double NextDouble() const {
00089 if (d64_ == kInfinity) return Double(kInfinity).value();
00090 if (Sign() < 0 && Significand() == 0) {
00091
00092 return 0.0;
00093 }
00094 if (Sign() < 0) {
00095 return Double(d64_ - 1).value();
00096 } else {
00097 return Double(d64_ + 1).value();
00098 }
00099 }
00100
00101 double PreviousDouble() const {
00102 if (d64_ == (kInfinity | kSignMask)) return -Double::Infinity();
00103 if (Sign() < 0) {
00104 return Double(d64_ + 1).value();
00105 } else {
00106 if (Significand() == 0) return -0.0;
00107 return Double(d64_ - 1).value();
00108 }
00109 }
00110
00111 int Exponent() const {
00112 if (IsDenormal()) return kDenormalExponent;
00113
00114 uint64_t d64 = AsUint64();
00115 int biased_e =
00116 static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize);
00117 return biased_e - kExponentBias;
00118 }
00119
00120 uint64_t Significand() const {
00121 uint64_t d64 = AsUint64();
00122 uint64_t significand = d64 & kSignificandMask;
00123 if (!IsDenormal()) {
00124 return significand + kHiddenBit;
00125 } else {
00126 return significand;
00127 }
00128 }
00129
00130
00131 bool IsDenormal() const {
00132 uint64_t d64 = AsUint64();
00133 return (d64 & kExponentMask) == 0;
00134 }
00135
00136
00137
00138 bool IsSpecial() const {
00139 uint64_t d64 = AsUint64();
00140 return (d64 & kExponentMask) == kExponentMask;
00141 }
00142
00143 bool IsNan() const {
00144 uint64_t d64 = AsUint64();
00145 return ((d64 & kExponentMask) == kExponentMask) &&
00146 ((d64 & kSignificandMask) != 0);
00147 }
00148
00149 bool IsInfinite() const {
00150 uint64_t d64 = AsUint64();
00151 return ((d64 & kExponentMask) == kExponentMask) &&
00152 ((d64 & kSignificandMask) == 0);
00153 }
00154
00155 int Sign() const {
00156 uint64_t d64 = AsUint64();
00157 return (d64 & kSignMask) == 0? 1: -1;
00158 }
00159
00160
00161
00162 DiyFp UpperBoundary() const {
00163 ASSERT(Sign() > 0);
00164 return DiyFp(Significand() * 2 + 1, Exponent() - 1);
00165 }
00166
00167
00168
00169
00170
00171 void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
00172 ASSERT(value() > 0.0);
00173 DiyFp v = this->AsDiyFp();
00174 DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
00175 DiyFp m_minus;
00176 if (LowerBoundaryIsCloser()) {
00177 m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
00178 } else {
00179 m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
00180 }
00181 m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
00182 m_minus.set_e(m_plus.e());
00183 *out_m_plus = m_plus;
00184 *out_m_minus = m_minus;
00185 }
00186
00187 bool LowerBoundaryIsCloser() const {
00188
00189
00190
00191
00192
00193
00194
00195
00196 bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0);
00197 return physical_significand_is_zero && (Exponent() != kDenormalExponent);
00198 }
00199
00200 double value() const { return uint64_to_double(d64_); }
00201
00202
00203
00204
00205
00206
00207
00208 static int SignificandSizeForOrderOfMagnitude(int order) {
00209 if (order >= (kDenormalExponent + kSignificandSize)) {
00210 return kSignificandSize;
00211 }
00212 if (order <= kDenormalExponent) return 0;
00213 return order - kDenormalExponent;
00214 }
00215
00216 static double Infinity() {
00217 return Double(kInfinity).value();
00218 }
00219
00220 static double NaN() {
00221 return Double(kNaN).value();
00222 }
00223
00224 private:
00225 static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
00226 static const int kDenormalExponent = -kExponentBias + 1;
00227 static const int kMaxExponent = 0x7FF - kExponentBias;
00228 static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
00229 static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);
00230
00231 const uint64_t d64_;
00232
00233 static uint64_t DiyFpToUint64(DiyFp diy_fp) {
00234 uint64_t significand = diy_fp.f();
00235 int exponent = diy_fp.e();
00236 while (significand > kHiddenBit + kSignificandMask) {
00237 significand >>= 1;
00238 exponent++;
00239 }
00240 if (exponent >= kMaxExponent) {
00241 return kInfinity;
00242 }
00243 if (exponent < kDenormalExponent) {
00244 return 0;
00245 }
00246 while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) {
00247 significand <<= 1;
00248 exponent--;
00249 }
00250 uint64_t biased_exponent;
00251 if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) {
00252 biased_exponent = 0;
00253 } else {
00254 biased_exponent = static_cast<uint64_t>(exponent + kExponentBias);
00255 }
00256 return (significand & kSignificandMask) |
00257 (biased_exponent << kPhysicalSignificandSize);
00258 }
00259 };
00260
00261 class Single {
00262 public:
00263 static const uint32_t kSignMask = 0x80000000;
00264 static const uint32_t kExponentMask = 0x7F800000;
00265 static const uint32_t kSignificandMask = 0x007FFFFF;
00266 static const uint32_t kHiddenBit = 0x00800000;
00267 static const int kPhysicalSignificandSize = 23;
00268 static const int kSignificandSize = 24;
00269
00270 Single() : d32_(0) {}
00271 explicit Single(float f) : d32_(float_to_uint32(f)) {}
00272 explicit Single(uint32_t d32) : d32_(d32) {}
00273
00274
00275
00276 DiyFp AsDiyFp() const {
00277 ASSERT(Sign() > 0);
00278 ASSERT(!IsSpecial());
00279 return DiyFp(Significand(), Exponent());
00280 }
00281
00282
00283 uint32_t AsUint32() const {
00284 return d32_;
00285 }
00286
00287 int Exponent() const {
00288 if (IsDenormal()) return kDenormalExponent;
00289
00290 uint32_t d32 = AsUint32();
00291 int biased_e =
00292 static_cast<int>((d32 & kExponentMask) >> kPhysicalSignificandSize);
00293 return biased_e - kExponentBias;
00294 }
00295
00296 uint32_t Significand() const {
00297 uint32_t d32 = AsUint32();
00298 uint32_t significand = d32 & kSignificandMask;
00299 if (!IsDenormal()) {
00300 return significand + kHiddenBit;
00301 } else {
00302 return significand;
00303 }
00304 }
00305
00306
00307 bool IsDenormal() const {
00308 uint32_t d32 = AsUint32();
00309 return (d32 & kExponentMask) == 0;
00310 }
00311
00312
00313
00314 bool IsSpecial() const {
00315 uint32_t d32 = AsUint32();
00316 return (d32 & kExponentMask) == kExponentMask;
00317 }
00318
00319 bool IsNan() const {
00320 uint32_t d32 = AsUint32();
00321 return ((d32 & kExponentMask) == kExponentMask) &&
00322 ((d32 & kSignificandMask) != 0);
00323 }
00324
00325 bool IsInfinite() const {
00326 uint32_t d32 = AsUint32();
00327 return ((d32 & kExponentMask) == kExponentMask) &&
00328 ((d32 & kSignificandMask) == 0);
00329 }
00330
00331 int Sign() const {
00332 uint32_t d32 = AsUint32();
00333 return (d32 & kSignMask) == 0? 1: -1;
00334 }
00335
00336
00337
00338
00339
00340 void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
00341 ASSERT(value() > 0.0);
00342 DiyFp v = this->AsDiyFp();
00343 DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
00344 DiyFp m_minus;
00345 if (LowerBoundaryIsCloser()) {
00346 m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
00347 } else {
00348 m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
00349 }
00350 m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
00351 m_minus.set_e(m_plus.e());
00352 *out_m_plus = m_plus;
00353 *out_m_minus = m_minus;
00354 }
00355
00356
00357
00358 DiyFp UpperBoundary() const {
00359 ASSERT(Sign() > 0);
00360 return DiyFp(Significand() * 2 + 1, Exponent() - 1);
00361 }
00362
00363 bool LowerBoundaryIsCloser() const {
00364
00365
00366
00367
00368
00369
00370
00371
00372 bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0);
00373 return physical_significand_is_zero && (Exponent() != kDenormalExponent);
00374 }
00375
00376 float value() const { return uint32_to_float(d32_); }
00377
00378 static float Infinity() {
00379 return Single(kInfinity).value();
00380 }
00381
00382 static float NaN() {
00383 return Single(kNaN).value();
00384 }
00385
00386 private:
00387 static const int kExponentBias = 0x7F + kPhysicalSignificandSize;
00388 static const int kDenormalExponent = -kExponentBias + 1;
00389 static const int kMaxExponent = 0xFF - kExponentBias;
00390 static const uint32_t kInfinity = 0x7F800000;
00391 static const uint32_t kNaN = 0x7FC00000;
00392
00393 const uint32_t d32_;
00394 };
00395
00396 }
00397
00398 #endif // DOUBLE_CONVERSION_DOUBLE_H_