| // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | #ifndef RUNTIME_VM_DOUBLE_INTERNALS_H_ | 
 | #define RUNTIME_VM_DOUBLE_INTERNALS_H_ | 
 |  | 
 | #include "platform/utils.h" | 
 |  | 
 | namespace dart { | 
 |  | 
 | // We assume that doubles and uint64_t have the same endianness. | 
 | static uint64_t double_to_uint64(double d) { | 
 |   return bit_cast<uint64_t>(d); | 
 | } | 
 |  | 
 | // Helper functions for doubles. | 
 | class DoubleInternals { | 
 |  public: | 
 |   static const int kSignificandSize = 53; | 
 |  | 
 |   explicit DoubleInternals(double d) : d64_(double_to_uint64(d)) {} | 
 |  | 
 |   // Returns the double's bit as uint64. | 
 |   uint64_t AsUint64() const { return d64_; } | 
 |  | 
 |   int Exponent() const { | 
 |     if (IsDenormal()) return kDenormalExponent; | 
 |  | 
 |     uint64_t d64 = AsUint64(); | 
 |     int biased_e = | 
 |         static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize); | 
 |     return biased_e - kExponentBias; | 
 |   } | 
 |  | 
 |   uint64_t Significand() const { | 
 |     uint64_t d64 = AsUint64(); | 
 |     uint64_t significand = d64 & kSignificandMask; | 
 |     if (!IsDenormal()) { | 
 |       return significand + kHiddenBit; | 
 |     } else { | 
 |       return significand; | 
 |     } | 
 |   } | 
 |  | 
 |   // Returns true if the double is a denormal. | 
 |   bool IsDenormal() const { | 
 |     uint64_t d64 = AsUint64(); | 
 |     return (d64 & kExponentMask) == 0; | 
 |   } | 
 |  | 
 |   // We consider denormals not to be special. | 
 |   // Hence only Infinity and NaN are special. | 
 |   bool IsSpecial() const { | 
 |     uint64_t d64 = AsUint64(); | 
 |     return (d64 & kExponentMask) == kExponentMask; | 
 |   } | 
 |  | 
 |   int Sign() const { | 
 |     uint64_t d64 = AsUint64(); | 
 |     return (d64 & kSignMask) == 0 ? 1 : -1; | 
 |   } | 
 |  | 
 |  private: | 
 |   static const uint64_t kSignMask = DART_2PART_UINT64_C(0x80000000, 00000000); | 
 |   static const uint64_t kExponentMask = | 
 |       DART_2PART_UINT64_C(0x7FF00000, 00000000); | 
 |   static const uint64_t kSignificandMask = | 
 |       DART_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); | 
 |   static const uint64_t kHiddenBit = DART_2PART_UINT64_C(0x00100000, 00000000); | 
 |   static const int kPhysicalSignificandSize = 52;  // Excludes the hidden bit. | 
 |   static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; | 
 |   static const int kDenormalExponent = -kExponentBias + 1; | 
 |  | 
 |   const uint64_t d64_; | 
 | }; | 
 |  | 
 | }  // namespace dart | 
 |  | 
 | #endif  // RUNTIME_VM_DOUBLE_INTERNALS_H_ |