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