Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | // Copyright 2012 the V8 project authors. All rights reserved. |
michael@0 | 2 | // Redistribution and use in source and binary forms, with or without |
michael@0 | 3 | // modification, are permitted provided that the following conditions are |
michael@0 | 4 | // met: |
michael@0 | 5 | // |
michael@0 | 6 | // * Redistributions of source code must retain the above copyright |
michael@0 | 7 | // notice, this list of conditions and the following disclaimer. |
michael@0 | 8 | // * Redistributions in binary form must reproduce the above |
michael@0 | 9 | // copyright notice, this list of conditions and the following |
michael@0 | 10 | // disclaimer in the documentation and/or other materials provided |
michael@0 | 11 | // with the distribution. |
michael@0 | 12 | // * Neither the name of Google Inc. nor the names of its |
michael@0 | 13 | // contributors may be used to endorse or promote products derived |
michael@0 | 14 | // from this software without specific prior written permission. |
michael@0 | 15 | // |
michael@0 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
michael@0 | 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
michael@0 | 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
michael@0 | 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
michael@0 | 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@0 | 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@0 | 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
michael@0 | 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
michael@0 | 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
michael@0 | 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
michael@0 | 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 27 | |
michael@0 | 28 | #ifndef DOUBLE_CONVERSION_DOUBLE_H_ |
michael@0 | 29 | #define DOUBLE_CONVERSION_DOUBLE_H_ |
michael@0 | 30 | |
michael@0 | 31 | #include "diy-fp.h" |
michael@0 | 32 | |
michael@0 | 33 | namespace double_conversion { |
michael@0 | 34 | |
michael@0 | 35 | // We assume that doubles and uint64_t have the same endianness. |
michael@0 | 36 | static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); } |
michael@0 | 37 | static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); } |
michael@0 | 38 | static uint32_t float_to_uint32(float f) { return BitCast<uint32_t>(f); } |
michael@0 | 39 | static float uint32_to_float(uint32_t d32) { return BitCast<float>(d32); } |
michael@0 | 40 | |
michael@0 | 41 | // Helper functions for doubles. |
michael@0 | 42 | class Double { |
michael@0 | 43 | public: |
michael@0 | 44 | static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000); |
michael@0 | 45 | static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000); |
michael@0 | 46 | static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF); |
michael@0 | 47 | static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000); |
michael@0 | 48 | static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. |
michael@0 | 49 | static const int kSignificandSize = 53; |
michael@0 | 50 | |
michael@0 | 51 | Double() : d64_(0) {} |
michael@0 | 52 | explicit Double(double d) : d64_(double_to_uint64(d)) {} |
michael@0 | 53 | explicit Double(uint64_t d64) : d64_(d64) {} |
michael@0 | 54 | explicit Double(DiyFp diy_fp) |
michael@0 | 55 | : d64_(DiyFpToUint64(diy_fp)) {} |
michael@0 | 56 | |
michael@0 | 57 | // The value encoded by this Double must be greater or equal to +0.0. |
michael@0 | 58 | // It must not be special (infinity, or NaN). |
michael@0 | 59 | DiyFp AsDiyFp() const { |
michael@0 | 60 | ASSERT(Sign() > 0); |
michael@0 | 61 | ASSERT(!IsSpecial()); |
michael@0 | 62 | return DiyFp(Significand(), Exponent()); |
michael@0 | 63 | } |
michael@0 | 64 | |
michael@0 | 65 | // The value encoded by this Double must be strictly greater than 0. |
michael@0 | 66 | DiyFp AsNormalizedDiyFp() const { |
michael@0 | 67 | ASSERT(value() > 0.0); |
michael@0 | 68 | uint64_t f = Significand(); |
michael@0 | 69 | int e = Exponent(); |
michael@0 | 70 | |
michael@0 | 71 | // The current double could be a denormal. |
michael@0 | 72 | while ((f & kHiddenBit) == 0) { |
michael@0 | 73 | f <<= 1; |
michael@0 | 74 | e--; |
michael@0 | 75 | } |
michael@0 | 76 | // Do the final shifts in one go. |
michael@0 | 77 | f <<= DiyFp::kSignificandSize - kSignificandSize; |
michael@0 | 78 | e -= DiyFp::kSignificandSize - kSignificandSize; |
michael@0 | 79 | return DiyFp(f, e); |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | // Returns the double's bit as uint64. |
michael@0 | 83 | uint64_t AsUint64() const { |
michael@0 | 84 | return d64_; |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | // Returns the next greater double. Returns +infinity on input +infinity. |
michael@0 | 88 | double NextDouble() const { |
michael@0 | 89 | if (d64_ == kInfinity) return Double(kInfinity).value(); |
michael@0 | 90 | if (Sign() < 0 && Significand() == 0) { |
michael@0 | 91 | // -0.0 |
michael@0 | 92 | return 0.0; |
michael@0 | 93 | } |
michael@0 | 94 | if (Sign() < 0) { |
michael@0 | 95 | return Double(d64_ - 1).value(); |
michael@0 | 96 | } else { |
michael@0 | 97 | return Double(d64_ + 1).value(); |
michael@0 | 98 | } |
michael@0 | 99 | } |
michael@0 | 100 | |
michael@0 | 101 | double PreviousDouble() const { |
michael@0 | 102 | if (d64_ == (kInfinity | kSignMask)) return -Double::Infinity(); |
michael@0 | 103 | if (Sign() < 0) { |
michael@0 | 104 | return Double(d64_ + 1).value(); |
michael@0 | 105 | } else { |
michael@0 | 106 | if (Significand() == 0) return -0.0; |
michael@0 | 107 | return Double(d64_ - 1).value(); |
michael@0 | 108 | } |
michael@0 | 109 | } |
michael@0 | 110 | |
michael@0 | 111 | int Exponent() const { |
michael@0 | 112 | if (IsDenormal()) return kDenormalExponent; |
michael@0 | 113 | |
michael@0 | 114 | uint64_t d64 = AsUint64(); |
michael@0 | 115 | int biased_e = |
michael@0 | 116 | static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize); |
michael@0 | 117 | return biased_e - kExponentBias; |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | uint64_t Significand() const { |
michael@0 | 121 | uint64_t d64 = AsUint64(); |
michael@0 | 122 | uint64_t significand = d64 & kSignificandMask; |
michael@0 | 123 | if (!IsDenormal()) { |
michael@0 | 124 | return significand + kHiddenBit; |
michael@0 | 125 | } else { |
michael@0 | 126 | return significand; |
michael@0 | 127 | } |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | // Returns true if the double is a denormal. |
michael@0 | 131 | bool IsDenormal() const { |
michael@0 | 132 | uint64_t d64 = AsUint64(); |
michael@0 | 133 | return (d64 & kExponentMask) == 0; |
michael@0 | 134 | } |
michael@0 | 135 | |
michael@0 | 136 | // We consider denormals not to be special. |
michael@0 | 137 | // Hence only Infinity and NaN are special. |
michael@0 | 138 | bool IsSpecial() const { |
michael@0 | 139 | uint64_t d64 = AsUint64(); |
michael@0 | 140 | return (d64 & kExponentMask) == kExponentMask; |
michael@0 | 141 | } |
michael@0 | 142 | |
michael@0 | 143 | bool IsNan() const { |
michael@0 | 144 | uint64_t d64 = AsUint64(); |
michael@0 | 145 | return ((d64 & kExponentMask) == kExponentMask) && |
michael@0 | 146 | ((d64 & kSignificandMask) != 0); |
michael@0 | 147 | } |
michael@0 | 148 | |
michael@0 | 149 | bool IsInfinite() const { |
michael@0 | 150 | uint64_t d64 = AsUint64(); |
michael@0 | 151 | return ((d64 & kExponentMask) == kExponentMask) && |
michael@0 | 152 | ((d64 & kSignificandMask) == 0); |
michael@0 | 153 | } |
michael@0 | 154 | |
michael@0 | 155 | int Sign() const { |
michael@0 | 156 | uint64_t d64 = AsUint64(); |
michael@0 | 157 | return (d64 & kSignMask) == 0? 1: -1; |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | // Precondition: the value encoded by this Double must be greater or equal |
michael@0 | 161 | // than +0.0. |
michael@0 | 162 | DiyFp UpperBoundary() const { |
michael@0 | 163 | ASSERT(Sign() > 0); |
michael@0 | 164 | return DiyFp(Significand() * 2 + 1, Exponent() - 1); |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | // Computes the two boundaries of this. |
michael@0 | 168 | // The bigger boundary (m_plus) is normalized. The lower boundary has the same |
michael@0 | 169 | // exponent as m_plus. |
michael@0 | 170 | // Precondition: the value encoded by this Double must be greater than 0. |
michael@0 | 171 | void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const { |
michael@0 | 172 | ASSERT(value() > 0.0); |
michael@0 | 173 | DiyFp v = this->AsDiyFp(); |
michael@0 | 174 | DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1)); |
michael@0 | 175 | DiyFp m_minus; |
michael@0 | 176 | if (LowerBoundaryIsCloser()) { |
michael@0 | 177 | m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2); |
michael@0 | 178 | } else { |
michael@0 | 179 | m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1); |
michael@0 | 180 | } |
michael@0 | 181 | m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e())); |
michael@0 | 182 | m_minus.set_e(m_plus.e()); |
michael@0 | 183 | *out_m_plus = m_plus; |
michael@0 | 184 | *out_m_minus = m_minus; |
michael@0 | 185 | } |
michael@0 | 186 | |
michael@0 | 187 | bool LowerBoundaryIsCloser() const { |
michael@0 | 188 | // The boundary is closer if the significand is of the form f == 2^p-1 then |
michael@0 | 189 | // the lower boundary is closer. |
michael@0 | 190 | // Think of v = 1000e10 and v- = 9999e9. |
michael@0 | 191 | // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but |
michael@0 | 192 | // at a distance of 1e8. |
michael@0 | 193 | // The only exception is for the smallest normal: the largest denormal is |
michael@0 | 194 | // at the same distance as its successor. |
michael@0 | 195 | // Note: denormals have the same exponent as the smallest normals. |
michael@0 | 196 | bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0); |
michael@0 | 197 | return physical_significand_is_zero && (Exponent() != kDenormalExponent); |
michael@0 | 198 | } |
michael@0 | 199 | |
michael@0 | 200 | double value() const { return uint64_to_double(d64_); } |
michael@0 | 201 | |
michael@0 | 202 | // Returns the significand size for a given order of magnitude. |
michael@0 | 203 | // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude. |
michael@0 | 204 | // This function returns the number of significant binary digits v will have |
michael@0 | 205 | // once it's encoded into a double. In almost all cases this is equal to |
michael@0 | 206 | // kSignificandSize. The only exceptions are denormals. They start with |
michael@0 | 207 | // leading zeroes and their effective significand-size is hence smaller. |
michael@0 | 208 | static int SignificandSizeForOrderOfMagnitude(int order) { |
michael@0 | 209 | if (order >= (kDenormalExponent + kSignificandSize)) { |
michael@0 | 210 | return kSignificandSize; |
michael@0 | 211 | } |
michael@0 | 212 | if (order <= kDenormalExponent) return 0; |
michael@0 | 213 | return order - kDenormalExponent; |
michael@0 | 214 | } |
michael@0 | 215 | |
michael@0 | 216 | static double Infinity() { |
michael@0 | 217 | return Double(kInfinity).value(); |
michael@0 | 218 | } |
michael@0 | 219 | |
michael@0 | 220 | static double NaN() { |
michael@0 | 221 | return Double(kNaN).value(); |
michael@0 | 222 | } |
michael@0 | 223 | |
michael@0 | 224 | private: |
michael@0 | 225 | static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; |
michael@0 | 226 | static const int kDenormalExponent = -kExponentBias + 1; |
michael@0 | 227 | static const int kMaxExponent = 0x7FF - kExponentBias; |
michael@0 | 228 | static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000); |
michael@0 | 229 | static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000); |
michael@0 | 230 | |
michael@0 | 231 | const uint64_t d64_; |
michael@0 | 232 | |
michael@0 | 233 | static uint64_t DiyFpToUint64(DiyFp diy_fp) { |
michael@0 | 234 | uint64_t significand = diy_fp.f(); |
michael@0 | 235 | int exponent = diy_fp.e(); |
michael@0 | 236 | while (significand > kHiddenBit + kSignificandMask) { |
michael@0 | 237 | significand >>= 1; |
michael@0 | 238 | exponent++; |
michael@0 | 239 | } |
michael@0 | 240 | if (exponent >= kMaxExponent) { |
michael@0 | 241 | return kInfinity; |
michael@0 | 242 | } |
michael@0 | 243 | if (exponent < kDenormalExponent) { |
michael@0 | 244 | return 0; |
michael@0 | 245 | } |
michael@0 | 246 | while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) { |
michael@0 | 247 | significand <<= 1; |
michael@0 | 248 | exponent--; |
michael@0 | 249 | } |
michael@0 | 250 | uint64_t biased_exponent; |
michael@0 | 251 | if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) { |
michael@0 | 252 | biased_exponent = 0; |
michael@0 | 253 | } else { |
michael@0 | 254 | biased_exponent = static_cast<uint64_t>(exponent + kExponentBias); |
michael@0 | 255 | } |
michael@0 | 256 | return (significand & kSignificandMask) | |
michael@0 | 257 | (biased_exponent << kPhysicalSignificandSize); |
michael@0 | 258 | } |
michael@0 | 259 | }; |
michael@0 | 260 | |
michael@0 | 261 | class Single { |
michael@0 | 262 | public: |
michael@0 | 263 | static const uint32_t kSignMask = 0x80000000; |
michael@0 | 264 | static const uint32_t kExponentMask = 0x7F800000; |
michael@0 | 265 | static const uint32_t kSignificandMask = 0x007FFFFF; |
michael@0 | 266 | static const uint32_t kHiddenBit = 0x00800000; |
michael@0 | 267 | static const int kPhysicalSignificandSize = 23; // Excludes the hidden bit. |
michael@0 | 268 | static const int kSignificandSize = 24; |
michael@0 | 269 | |
michael@0 | 270 | Single() : d32_(0) {} |
michael@0 | 271 | explicit Single(float f) : d32_(float_to_uint32(f)) {} |
michael@0 | 272 | explicit Single(uint32_t d32) : d32_(d32) {} |
michael@0 | 273 | |
michael@0 | 274 | // The value encoded by this Single must be greater or equal to +0.0. |
michael@0 | 275 | // It must not be special (infinity, or NaN). |
michael@0 | 276 | DiyFp AsDiyFp() const { |
michael@0 | 277 | ASSERT(Sign() > 0); |
michael@0 | 278 | ASSERT(!IsSpecial()); |
michael@0 | 279 | return DiyFp(Significand(), Exponent()); |
michael@0 | 280 | } |
michael@0 | 281 | |
michael@0 | 282 | // Returns the single's bit as uint64. |
michael@0 | 283 | uint32_t AsUint32() const { |
michael@0 | 284 | return d32_; |
michael@0 | 285 | } |
michael@0 | 286 | |
michael@0 | 287 | int Exponent() const { |
michael@0 | 288 | if (IsDenormal()) return kDenormalExponent; |
michael@0 | 289 | |
michael@0 | 290 | uint32_t d32 = AsUint32(); |
michael@0 | 291 | int biased_e = |
michael@0 | 292 | static_cast<int>((d32 & kExponentMask) >> kPhysicalSignificandSize); |
michael@0 | 293 | return biased_e - kExponentBias; |
michael@0 | 294 | } |
michael@0 | 295 | |
michael@0 | 296 | uint32_t Significand() const { |
michael@0 | 297 | uint32_t d32 = AsUint32(); |
michael@0 | 298 | uint32_t significand = d32 & kSignificandMask; |
michael@0 | 299 | if (!IsDenormal()) { |
michael@0 | 300 | return significand + kHiddenBit; |
michael@0 | 301 | } else { |
michael@0 | 302 | return significand; |
michael@0 | 303 | } |
michael@0 | 304 | } |
michael@0 | 305 | |
michael@0 | 306 | // Returns true if the single is a denormal. |
michael@0 | 307 | bool IsDenormal() const { |
michael@0 | 308 | uint32_t d32 = AsUint32(); |
michael@0 | 309 | return (d32 & kExponentMask) == 0; |
michael@0 | 310 | } |
michael@0 | 311 | |
michael@0 | 312 | // We consider denormals not to be special. |
michael@0 | 313 | // Hence only Infinity and NaN are special. |
michael@0 | 314 | bool IsSpecial() const { |
michael@0 | 315 | uint32_t d32 = AsUint32(); |
michael@0 | 316 | return (d32 & kExponentMask) == kExponentMask; |
michael@0 | 317 | } |
michael@0 | 318 | |
michael@0 | 319 | bool IsNan() const { |
michael@0 | 320 | uint32_t d32 = AsUint32(); |
michael@0 | 321 | return ((d32 & kExponentMask) == kExponentMask) && |
michael@0 | 322 | ((d32 & kSignificandMask) != 0); |
michael@0 | 323 | } |
michael@0 | 324 | |
michael@0 | 325 | bool IsInfinite() const { |
michael@0 | 326 | uint32_t d32 = AsUint32(); |
michael@0 | 327 | return ((d32 & kExponentMask) == kExponentMask) && |
michael@0 | 328 | ((d32 & kSignificandMask) == 0); |
michael@0 | 329 | } |
michael@0 | 330 | |
michael@0 | 331 | int Sign() const { |
michael@0 | 332 | uint32_t d32 = AsUint32(); |
michael@0 | 333 | return (d32 & kSignMask) == 0? 1: -1; |
michael@0 | 334 | } |
michael@0 | 335 | |
michael@0 | 336 | // Computes the two boundaries of this. |
michael@0 | 337 | // The bigger boundary (m_plus) is normalized. The lower boundary has the same |
michael@0 | 338 | // exponent as m_plus. |
michael@0 | 339 | // Precondition: the value encoded by this Single must be greater than 0. |
michael@0 | 340 | void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const { |
michael@0 | 341 | ASSERT(value() > 0.0); |
michael@0 | 342 | DiyFp v = this->AsDiyFp(); |
michael@0 | 343 | DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1)); |
michael@0 | 344 | DiyFp m_minus; |
michael@0 | 345 | if (LowerBoundaryIsCloser()) { |
michael@0 | 346 | m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2); |
michael@0 | 347 | } else { |
michael@0 | 348 | m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1); |
michael@0 | 349 | } |
michael@0 | 350 | m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e())); |
michael@0 | 351 | m_minus.set_e(m_plus.e()); |
michael@0 | 352 | *out_m_plus = m_plus; |
michael@0 | 353 | *out_m_minus = m_minus; |
michael@0 | 354 | } |
michael@0 | 355 | |
michael@0 | 356 | // Precondition: the value encoded by this Single must be greater or equal |
michael@0 | 357 | // than +0.0. |
michael@0 | 358 | DiyFp UpperBoundary() const { |
michael@0 | 359 | ASSERT(Sign() > 0); |
michael@0 | 360 | return DiyFp(Significand() * 2 + 1, Exponent() - 1); |
michael@0 | 361 | } |
michael@0 | 362 | |
michael@0 | 363 | bool LowerBoundaryIsCloser() const { |
michael@0 | 364 | // The boundary is closer if the significand is of the form f == 2^p-1 then |
michael@0 | 365 | // the lower boundary is closer. |
michael@0 | 366 | // Think of v = 1000e10 and v- = 9999e9. |
michael@0 | 367 | // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but |
michael@0 | 368 | // at a distance of 1e8. |
michael@0 | 369 | // The only exception is for the smallest normal: the largest denormal is |
michael@0 | 370 | // at the same distance as its successor. |
michael@0 | 371 | // Note: denormals have the same exponent as the smallest normals. |
michael@0 | 372 | bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0); |
michael@0 | 373 | return physical_significand_is_zero && (Exponent() != kDenormalExponent); |
michael@0 | 374 | } |
michael@0 | 375 | |
michael@0 | 376 | float value() const { return uint32_to_float(d32_); } |
michael@0 | 377 | |
michael@0 | 378 | static float Infinity() { |
michael@0 | 379 | return Single(kInfinity).value(); |
michael@0 | 380 | } |
michael@0 | 381 | |
michael@0 | 382 | static float NaN() { |
michael@0 | 383 | return Single(kNaN).value(); |
michael@0 | 384 | } |
michael@0 | 385 | |
michael@0 | 386 | private: |
michael@0 | 387 | static const int kExponentBias = 0x7F + kPhysicalSignificandSize; |
michael@0 | 388 | static const int kDenormalExponent = -kExponentBias + 1; |
michael@0 | 389 | static const int kMaxExponent = 0xFF - kExponentBias; |
michael@0 | 390 | static const uint32_t kInfinity = 0x7F800000; |
michael@0 | 391 | static const uint32_t kNaN = 0x7FC00000; |
michael@0 | 392 | |
michael@0 | 393 | const uint32_t d32_; |
michael@0 | 394 | }; |
michael@0 | 395 | |
michael@0 | 396 | } // namespace double_conversion |
michael@0 | 397 | |
michael@0 | 398 | #endif // DOUBLE_CONVERSION_DOUBLE_H_ |