1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_DOUBLE_INTERNALS_H_
6#define RUNTIME_VM_DOUBLE_INTERNALS_H_
7
8#include "platform/utils.h"
9
10namespace dart {
11
12// We assume that doubles and uint64_t have the same endianness.
13static uint64_t double_to_uint64(double d) {
14 return bit_cast<uint64_t>(d);
15}
16
17// Helper functions for doubles.
18class DoubleInternals {
19 public:
20 static const int kSignificandSize = 53;
21
22 explicit DoubleInternals(double d) : d64_(double_to_uint64(d)) {}
23
24 // Returns the double's bit as uint64.
25 uint64_t AsUint64() const { return d64_; }
26
27 int Exponent() const {
28 if (IsDenormal()) return kDenormalExponent;
29
30 uint64_t d64 = AsUint64();
31 int biased_e =
32 static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize);
33 return biased_e - kExponentBias;
34 }
35
36 uint64_t Significand() const {
37 uint64_t d64 = AsUint64();
38 uint64_t significand = d64 & kSignificandMask;
39 if (!IsDenormal()) {
40 return significand + kHiddenBit;
41 } else {
42 return significand;
43 }
44 }
45
46 // Returns true if the double is a denormal.
47 bool IsDenormal() const {
48 uint64_t d64 = AsUint64();
49 return (d64 & kExponentMask) == 0;
50 }
51
52 // We consider denormals not to be special.
53 // Hence only Infinity and NaN are special.
54 bool IsSpecial() const {
55 uint64_t d64 = AsUint64();
56 return (d64 & kExponentMask) == kExponentMask;
57 }
58
59 int Sign() const {
60 uint64_t d64 = AsUint64();
61 return (d64 & kSignMask) == 0 ? 1 : -1;
62 }
63
64 private:
65 static const uint64_t kSignMask = DART_2PART_UINT64_C(0x80000000, 00000000);
66 static const uint64_t kExponentMask =
67 DART_2PART_UINT64_C(0x7FF00000, 00000000);
68 static const uint64_t kSignificandMask =
69 DART_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
70 static const uint64_t kHiddenBit = DART_2PART_UINT64_C(0x00100000, 00000000);
71 static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
72 static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
73 static const int kDenormalExponent = -kExponentBias + 1;
74
75 const uint64_t d64_;
76};
77
78} // namespace dart
79
80#endif // RUNTIME_VM_DOUBLE_INTERNALS_H_
81