// 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(d); } // Helper functions for doubles. class DoubleInternals { public: static constexpr 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((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 constexpr uint64_t kSignMask = 0x8000000000000000; static constexpr uint64_t kExponentMask = 0x7FF0000000000000; static constexpr uint64_t kSignificandMask = 0x000FFFFFFFFFFFFF; static constexpr uint64_t kHiddenBit = 0x0010000000000000; static constexpr int kPhysicalSignificandSize = 52; // Excludes the hidden bit. static constexpr int kExponentBias = 0x3FF + kPhysicalSignificandSize; static constexpr int kDenormalExponent = -kExponentBias + 1; const uint64_t d64_; }; } // namespace dart #endif // RUNTIME_VM_DOUBLE_INTERNALS_H_