GteIEEEBinary.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <GTEngineDEF.h>
11 #include <cstdint>
12 
13 namespace gte
14 {
15 
16 template <typename Float, typename UInt, int NumBits, int Precision>
18 {
19 public:
20  // For generic access of the template types.
21  typedef Float FloatType;
22  typedef UInt UIntType;
23 
24  // Construction from an encoding. Copy constructor, destructor, and
25  // assignment operator are implicitly generated. For the 3-parameter
26  // constructor, see the comments for SetEncoding(...).
27  ~IEEEBinary ();
28  IEEEBinary (); // The encoding is uninitialized.
29  IEEEBinary (IEEEBinary const& object);
30  IEEEBinary (UInt inEncoding);
31  IEEEBinary (UInt inSign, UInt inBiased, UInt inTrailing);
32  IEEEBinary (Float inNumber);
33 
34  // Implicit conversion to floating-point type.
35  operator UInt () const;
36  operator Float () const;
37 
38  // Assignment.
39  IEEEBinary& operator= (IEEEBinary const& object);
40 
41  // Special constants.
42  static int const NUM_ENCODING_BITS = NumBits;
43  static int const NUM_EXPONENT_BITS = NumBits - Precision;
44  static int const NUM_SIGNIFICAND_BITS = Precision;
45  static int const NUM_TRAILING_BITS = Precision - 1;
46  static int const EXPONENT_BIAS = (1 << (NUM_EXPONENT_BITS - 1)) - 1;
47  static int const MAX_BIASED_EXPONENT = (1 << NUM_EXPONENT_BITS) - 1;
48  static int const MIN_SUB_EXPONENT = 1 - EXPONENT_BIAS;
49  static int const MIN_EXPONENT = MIN_SUB_EXPONENT - NUM_TRAILING_BITS;
50  static int const SIGN_SHIFT = NumBits - 1;
51 
52  static UInt const SIGN_MASK = (UInt(1) << (NumBits - 1));
53  static UInt const NOT_SIGN_MASK = UInt(~SIGN_MASK);
54  static UInt const TRAILING_MASK = (UInt(1) << NUM_TRAILING_BITS) - 1;
55  static UInt const EXPONENT_MASK = NOT_SIGN_MASK & ~TRAILING_MASK;
56  static UInt const NAN_QUIET_MASK = (UInt(1) << (NUM_TRAILING_BITS - 1));
57  static UInt const NAN_PAYLOAD_MASK = (TRAILING_MASK >> 1);
58  static UInt const MAX_TRAILING = TRAILING_MASK;
59  static UInt const SUP_TRAILING = (UInt(1) << NUM_TRAILING_BITS);
60  static UInt const POS_ZERO = UInt(0);
61  static UInt const NEG_ZERO = SIGN_MASK;
62  static UInt const MIN_SUBNORMAL = UInt(1);
63  static UInt const MAX_SUBNORMAL = TRAILING_MASK;
64  static UInt const MIN_NORMAL = SUP_TRAILING;
65  static UInt const MAX_NORMAL = NOT_SIGN_MASK & ~SUP_TRAILING;
66  static UInt const POS_INFINITY = EXPONENT_MASK;
67  static UInt const NEG_INFINITY = SIGN_MASK | EXPONENT_MASK;
68 
69  // The types of numbers.
71  {
82  };
83 
85  bool IsZero () const;
86  bool IsSignMinus () const;
87  bool IsSubnormal () const;
88  bool IsNormal () const;
89  bool IsFinite () const;
90  bool IsInfinite () const;
91  bool IsNaN () const;
92  bool IsSignalingNaN () const;
93 
94  // Get neighboring numbers.
95  UInt GetNextUp () const;
96  UInt GetNextDown () const;
97 
98  // Encode and decode the binary representation. The sign is 0 (number
99  // is nonnegative) or 1 (number is negative). The biased exponent is in
100  // the range [0,MAX_BIASED_EXPONENT]. The trailing significand is in the
101  // range [0,MAX_TRAILING].
102  UInt GetSign () const;
103  UInt GetBiased () const;
104  UInt GetTrailing () const;
105  void SetEncoding (UInt sign, UInt biased, UInt trailing);
106  void GetEncoding (UInt& sign, UInt& biased, UInt& trailing) const;
107 
108  // Access for direct manipulation of the object.
109  union
110  {
111  UInt encoding;
112  Float number;
113  };
114 };
115 
118 
119 
120 template <typename Float, typename UInt, int NumBits, int Precision>
122 {
123 }
124 
125 template <typename Float, typename UInt, int NumBits, int Precision>
127 {
128  // The member mEncoding is uninitialized.
129 }
130 
131 template <typename Float, typename UInt, int NumBits, int Precision>
133  IEEEBinary const& object)
134  :
135  encoding(object.encoding)
136 {
137 }
138 
139 template <typename Float, typename UInt, int NumBits, int Precision>
141  :
142  encoding(inEncoding)
143 {
144 }
145 
146 template <typename Float, typename UInt, int NumBits, int Precision>
148  UInt inBiased, UInt inTrailing)
149 {
150  SetEncoding(inSign, inBiased, inTrailing);
151 }
152 
153 template <typename Float, typename UInt, int NumBits, int Precision>
155  :
156  number(inNumber)
157 {
158 }
159 
160 template <typename Float, typename UInt, int NumBits, int Precision>
162 {
163  return encoding;
164 }
165 
166 template <typename Float, typename UInt, int NumBits, int Precision>
168 {
169  return number;
170 }
171 
172 template <typename Float, typename UInt, int NumBits, int Precision>
175 {
176  encoding = object.encoding;
177  return *this;
178 }
179 
180 template <typename Float, typename UInt, int NumBits, int Precision>
183 {
184  UInt sign, biased, trailing;
185  GetEncoding(sign, biased, trailing);
186 
187  if (biased == 0)
188  {
189  if (trailing == 0)
190  {
191  return (sign != 0 ? CLASS_NEG_ZERO : CLASS_POS_ZERO);
192  }
193  else
194  {
195  return (sign != 0 ? CLASS_NEG_SUBNORMAL : CLASS_POS_SUBNORMAL);
196  }
197  }
198  else if (biased < MAX_BIASED_EXPONENT)
199  {
200  return (sign != 0 ? CLASS_NEG_NORMAL : CLASS_POS_NORMAL);
201  }
202  else if (trailing == 0)
203  {
204  return (sign != 0 ? CLASS_NEG_INFINITY : CLASS_POS_INFINITY);
205  }
206  else if (trailing & NAN_QUIET_MASK)
207  {
208  return CLASS_QUIET_NAN;
209  }
210  else
211  {
212  return CLASS_SIGNALING_NAN;
213  }
214 }
215 
216 template <typename Float, typename UInt, int NumBits, int Precision>
218 {
219  return encoding == POS_ZERO || encoding == NEG_ZERO;
220 }
221 
222 template <typename Float, typename UInt, int NumBits, int Precision>
224 {
225  return (encoding & SIGN_MASK) != 0;
226 }
227 
228 template <typename Float, typename UInt, int NumBits, int Precision>
230 {
231  return GetBiased() == 0 && GetTrailing() > 0;
232 }
233 
234 template <typename Float, typename UInt, int NumBits, int Precision>
236 {
237  UInt biased = GetBiased();
238  return 0 < biased && biased < MAX_BIASED_EXPONENT;
239 }
240 
241 template <typename Float, typename UInt, int NumBits, int Precision>
243 {
244  return GetBiased() < MAX_BIASED_EXPONENT;
245 }
246 
247 template <typename Float, typename UInt, int NumBits, int Precision>
249 {
250  return GetBiased() == MAX_BIASED_EXPONENT && GetTrailing() == 0;
251 }
252 
253 template <typename Float, typename UInt, int NumBits, int Precision>
255 {
256  return GetBiased() == MAX_BIASED_EXPONENT && GetTrailing() != 0;
257 }
258 
259 template <typename Float, typename UInt, int NumBits, int Precision>
261 {
262  UInt trailing = GetTrailing();
263  return GetBiased() == MAX_BIASED_EXPONENT
264  && (trailing & NAN_QUIET_MASK) == 0
265  && (trailing & NAN_PAYLOAD_MASK) != 0;
266 }
267 
268 template <typename Float, typename UInt, int NumBits, int Precision>
270 {
271  UInt sign, biased, trailing;
272  GetEncoding(sign, biased, trailing);
273 
274  if (biased == 0)
275  {
276  if (trailing == 0)
277  {
278  // The next-up for both -0 and +0 is MIN_SUBNORMAL.
279  return MIN_SUBNORMAL;
280  }
281  else
282  {
283  if (sign != 0)
284  {
285  // When trailing is 1, 'this' is -MIN_SUBNORMAL and next-up
286  // is -0.
287  --trailing;
288  return SIGN_MASK | trailing;
289  }
290  else
291  {
292  // When trailing is MAX_TRAILING, 'this' is MAX_SUBNORMAL
293  // and next-up is MIN_NORMAL.
294  ++trailing;
295  return trailing;
296  }
297  }
298  }
299  else if (biased < MAX_BIASED_EXPONENT)
300  {
301  UInt nonnegative = (encoding & NOT_SIGN_MASK);
302  if (sign != 0)
303  {
304  --nonnegative;
305  return SIGN_MASK | nonnegative;
306  }
307  else
308  {
309  ++nonnegative;
310  return nonnegative;
311  }
312  }
313  else if (trailing == 0)
314  {
315  if (sign != 0)
316  {
317  // The next-up of -INFINITY is -MAX_NORMAL.
318  return SIGN_MASK | MAX_NORMAL;
319  }
320  else
321  {
322  // The next-up of +INFINITY is +INFINITY.
323  return POS_INFINITY;
324  }
325  }
326  else if (trailing & NAN_QUIET_MASK)
327  {
328  // TODO. The IEEE standard is not clear what to do here. Figure
329  // out what it means.
330  return 0;
331  }
332  else
333  {
334  // TODO. The IEEE standard is not clear what to do here. Figure
335  // out what it means.
336  return 0;
337  }
338 }
339 
340 template <typename Float, typename UInt, int NumBits, int Precision>
342 {
343  UInt sign, biased, trailing;
344  GetEncoding(sign, biased, trailing);
345 
346  if (biased == 0)
347  {
348  if (trailing == 0)
349  {
350  // The next-down for both -0 and +0 is -MIN_SUBNORMAL.
351  return SIGN_MASK | MIN_SUBNORMAL;
352  }
353  else
354  {
355  if (sign == 0)
356  {
357  // When trailing is 1, 'this' is MIN_SUBNORMAL and next-down
358  // is +0.
359  --trailing;
360  return trailing;
361  }
362  else
363  {
364  // When trailing is MAX_TRAILING, 'this' is -MAX_SUBNORMAL
365  // and next-down is -MIN_NORMAL.
366  ++trailing;
367  return SIGN_MASK | trailing;
368  }
369  }
370  }
371  else if (biased < MAX_BIASED_EXPONENT)
372  {
373  UInt nonnegative = (encoding & NOT_SIGN_MASK);
374  if (sign == 0)
375  {
376  --nonnegative;
377  return nonnegative;
378  }
379  else
380  {
381  ++nonnegative;
382  return SIGN_MASK | nonnegative;
383  }
384  }
385  else if (trailing == 0)
386  {
387  if (sign == 0)
388  {
389  // The next-down of +INFINITY is +MAX_NORMAL.
390  return MAX_NORMAL;
391  }
392  else
393  {
394  // The next-down of -INFINITY is -INFINITY.
395  return NEG_INFINITY;
396  }
397  }
398  else if (trailing & NAN_QUIET_MASK)
399  {
400  // TODO. The IEEE standard is not clear what to do here. Figure
401  // out what it means.
402  return 0;
403  }
404  else
405  {
406  // TODO. The IEEE standard is not clear what to do here. Figure
407  // out what it means.
408  return 0;
409  }
410 }
411 
412 template <typename Float, typename UInt, int NumBits, int Precision>
414 {
415  return (encoding & SIGN_MASK) >> SIGN_SHIFT;
416 }
417 
418 template <typename Float, typename UInt, int NumBits, int Precision>
420 {
422 }
423 
424 template <typename Float, typename UInt, int NumBits, int Precision>
426 {
427  return encoding & TRAILING_MASK;
428 }
429 
430 template <typename Float, typename UInt, int NumBits, int Precision>
432  UInt biased, UInt trailing)
433 {
434  encoding =
435  (sign << SIGN_SHIFT) | (biased << NUM_TRAILING_BITS) | trailing;
436 }
437 
438 template <typename Float, typename UInt, int NumBits, int Precision>
440  UInt& biased, UInt& trailing) const
441 {
442  sign = GetSign();
443  biased = GetBiased();
444  trailing = GetTrailing();
445 }
446 
447 
448 }
static UInt const SUP_TRAILING
Definition: GteIEEEBinary.h:59
static int const NUM_TRAILING_BITS
Definition: GteIEEEBinary.h:45
void SetEncoding(UInt sign, UInt biased, UInt trailing)
static int const NUM_EXPONENT_BITS
Definition: GteIEEEBinary.h:43
void GetEncoding(UInt &sign, UInt &biased, UInt &trailing) const
static int const MAX_BIASED_EXPONENT
Definition: GteIEEEBinary.h:47
IEEEBinary< double, uint64_t, 64, 53 > IEEEBinary64
bool IsZero() const
UInt GetBiased() const
bool IsSubnormal() const
bool IsFinite() const
UInt GetNextUp() const
static UInt const MIN_NORMAL
Definition: GteIEEEBinary.h:64
static UInt const NAN_PAYLOAD_MASK
Definition: GteIEEEBinary.h:57
static UInt const NEG_ZERO
Definition: GteIEEEBinary.h:61
UInt GetTrailing() const
static int const NUM_ENCODING_BITS
Definition: GteIEEEBinary.h:42
static UInt const EXPONENT_MASK
Definition: GteIEEEBinary.h:55
static int const EXPONENT_BIAS
Definition: GteIEEEBinary.h:46
static UInt const NOT_SIGN_MASK
Definition: GteIEEEBinary.h:53
static UInt const MAX_SUBNORMAL
Definition: GteIEEEBinary.h:63
static UInt const NEG_INFINITY
Definition: GteIEEEBinary.h:67
static UInt const MAX_NORMAL
Definition: GteIEEEBinary.h:65
bool IsInfinite() const
static UInt const MIN_SUBNORMAL
Definition: GteIEEEBinary.h:62
static int const SIGN_SHIFT
Definition: GteIEEEBinary.h:50
static int const MIN_EXPONENT
Definition: GteIEEEBinary.h:49
bool IsSignMinus() const
Classification GetClassification() const
static int const MIN_SUB_EXPONENT
Definition: GteIEEEBinary.h:48
static UInt const TRAILING_MASK
Definition: GteIEEEBinary.h:54
static UInt const POS_INFINITY
Definition: GteIEEEBinary.h:66
bool IsSignalingNaN() const
IEEEBinary< float, uint32_t, 32, 24 > IEEEBinary32
UInt GetNextDown() const
bool IsNormal() const
static UInt const MAX_TRAILING
Definition: GteIEEEBinary.h:58
static UInt const NAN_QUIET_MASK
Definition: GteIEEEBinary.h:56
IEEEBinary & operator=(IEEEBinary const &object)
static int const NUM_SIGNIFICAND_BITS
Definition: GteIEEEBinary.h:44
static UInt const POS_ZERO
Definition: GteIEEEBinary.h:60
UInt GetSign() const
static UInt const SIGN_MASK
Definition: GteIEEEBinary.h:52
bool IsNaN() const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00