HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
half.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 //
7 // Primary original authors:
8 // Florian Kainz <kainz@ilm.com>
9 // Rod Bogart <rgb@ilm.com>
10 //
11 
12 #ifndef IMATH_HALF_H_
13 #define IMATH_HALF_H_
14 
15 #include "ImathExport.h"
16 #include "ImathNamespace.h"
17 #include "ImathPlatform.h"
18 
19 /// @file half.h
20 /// The half type is a 16-bit floating number, compatible with the
21 /// IEEE 754-2008 binary16 type.
22 ///
23 /// **Representation of a 32-bit float:**
24 ///
25 /// We assume that a float, f, is an IEEE 754 single-precision
26 /// floating point number, whose bits are arranged as follows:
27 ///
28 /// 31 (msb)
29 /// |
30 /// | 30 23
31 /// | | |
32 /// | | | 22 0 (lsb)
33 /// | | | | |
34 /// X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX
35 ///
36 /// s e m
37 ///
38 /// S is the sign-bit, e is the exponent and m is the significand.
39 ///
40 /// If e is between 1 and 254, f is a normalized number:
41 ///
42 /// s e-127
43 /// f = (-1) * 2 * 1.m
44 ///
45 /// If e is 0, and m is not zero, f is a denormalized number:
46 ///
47 /// s -126
48 /// f = (-1) * 2 * 0.m
49 ///
50 /// If e and m are both zero, f is zero:
51 ///
52 /// f = 0.0
53 ///
54 /// If e is 255, f is an "infinity" or "not a number" (NAN),
55 /// depending on whether m is zero or not.
56 ///
57 /// Examples:
58 ///
59 /// 0 00000000 00000000000000000000000 = 0.0
60 /// 0 01111110 00000000000000000000000 = 0.5
61 /// 0 01111111 00000000000000000000000 = 1.0
62 /// 0 10000000 00000000000000000000000 = 2.0
63 /// 0 10000000 10000000000000000000000 = 3.0
64 /// 1 10000101 11110000010000000000000 = -124.0625
65 /// 0 11111111 00000000000000000000000 = +infinity
66 /// 1 11111111 00000000000000000000000 = -infinity
67 /// 0 11111111 10000000000000000000000 = NAN
68 /// 1 11111111 11111111111111111111111 = NAN
69 ///
70 /// **Representation of a 16-bit half:**
71 ///
72 /// Here is the bit-layout for a half number, h:
73 ///
74 /// 15 (msb)
75 /// |
76 /// | 14 10
77 /// | | |
78 /// | | | 9 0 (lsb)
79 /// | | | | |
80 /// X XXXXX XXXXXXXXXX
81 ///
82 /// s e m
83 ///
84 /// S is the sign-bit, e is the exponent and m is the significand.
85 ///
86 /// If e is between 1 and 30, h is a normalized number:
87 ///
88 /// s e-15
89 /// h = (-1) * 2 * 1.m
90 ///
91 /// If e is 0, and m is not zero, h is a denormalized number:
92 ///
93 /// S -14
94 /// h = (-1) * 2 * 0.m
95 ///
96 /// If e and m are both zero, h is zero:
97 ///
98 /// h = 0.0
99 ///
100 /// If e is 31, h is an "infinity" or "not a number" (NAN),
101 /// depending on whether m is zero or not.
102 ///
103 /// Examples:
104 ///
105 /// 0 00000 0000000000 = 0.0
106 /// 0 01110 0000000000 = 0.5
107 /// 0 01111 0000000000 = 1.0
108 /// 0 10000 0000000000 = 2.0
109 /// 0 10000 1000000000 = 3.0
110 /// 1 10101 1111000001 = -124.0625
111 /// 0 11111 0000000000 = +infinity
112 /// 1 11111 0000000000 = -infinity
113 /// 0 11111 1000000000 = NAN
114 /// 1 11111 1111111111 = NAN
115 ///
116 /// **Conversion via Lookup Table:**
117 ///
118 /// Converting from half to float is performed by default using a
119 /// lookup table. There are only 65,536 different half numbers; each
120 /// of these numbers has been converted and stored in a table pointed
121 /// to by the ``imath_half_to_float_table`` pointer.
122 ///
123 /// Prior to Imath v3.1, conversion from float to half was
124 /// accomplished with the help of an exponent look table, but this is
125 /// now replaced with explicit bit shifting.
126 ///
127 /// **Conversion via Hardware:**
128 ///
129 /// For Imath v3.1, the conversion routines have been extended to use
130 /// F16C SSE instructions whenever present and enabled by compiler
131 /// flags.
132 ///
133 /// **Conversion via Bit-Shifting**
134 ///
135 /// If F16C SSE instructions are not available, conversion can be
136 /// accomplished by a bit-shifting algorithm. For half-to-float
137 /// conversion, this is generally slower than the lookup table, but it
138 /// may be preferable when memory limits preclude storing of the
139 /// 65,536-entry lookup table.
140 ///
141 /// The lookup table symbol is included in the compilation even if
142 /// ``IMATH_HALF_USE_LOOKUP_TABLE`` is false, because application code
143 /// using the exported ``half.h`` may choose to enable the use of the table.
144 ///
145 /// An implementation can eliminate the table from compilation by
146 /// defining the ``IMATH_HALF_NO_LOOKUP_TABLE`` preprocessor symbol.
147 /// Simply add:
148 ///
149 /// #define IMATH_HALF_NO_LOOKUP_TABLE
150 ///
151 /// before including ``half.h``, or define the symbol on the compile
152 /// command line.
153 ///
154 /// Furthermore, an implementation wishing to receive ``FE_OVERFLOW``
155 /// and ``FE_UNDERFLOW`` floating point exceptions when converting
156 /// float to half by the bit-shift algorithm can define the
157 /// preprocessor symbol ``IMATH_HALF_ENABLE_FP_EXCEPTIONS`` prior to
158 /// including ``half.h``:
159 ///
160 /// #define IMATH_HALF_ENABLE_FP_EXCEPTIONS
161 ///
162 /// **Conversion Performance Comparison:**
163 ///
164 /// Testing on a Core i9, the timings are approximately:
165 ///
166 /// half to float
167 /// - table: 0.71 ns / call
168 /// - no table: 1.06 ns / call
169 /// - f16c: 0.45 ns / call
170 ///
171 /// float-to-half:
172 /// - original: 5.2 ns / call
173 /// - no exp table + opt: 1.27 ns / call
174 /// - f16c: 0.45 ns / call
175 ///
176 /// **Note:** the timing above depends on the distribution of the
177 /// floats in question.
178 ///
179 
180 #ifdef __CUDA_ARCH__
181 // do not include intrinsics headers on Cuda
182 #elif defined(_WIN32)
183 # include <intrin.h>
184 #elif defined(__x86_64__)
185 # include <x86intrin.h>
186 #elif defined(__F16C__)
187 # include <immintrin.h>
188 #endif
189 
190 #include <stdint.h>
191 #include <stdio.h>
192 
193 #ifdef IMATH_HALF_ENABLE_FP_EXCEPTIONS
194 # include <fenv.h>
195 #endif
196 
197 //-------------------------------------------------------------------------
198 // Limits
199 //
200 // Visual C++ will complain if HALF_DENORM_MIN, HALF_NRM_MIN etc. are not float
201 // constants, but at least one other compiler (gcc 2.96) produces incorrect
202 // results if they are.
203 //-------------------------------------------------------------------------
204 
205 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
206 
207 /// Smallest positive denormalized half
208 # define HALF_DENORM_MIN 5.96046448e-08f
209 /// Smallest positive normalized half
210 # define HALF_NRM_MIN 6.10351562e-05f
211 /// Smallest positive normalized half
212 # define HALF_MIN 6.10351562e-05f
213 /// Largest positive half
214 # define HALF_MAX 65504.0f
215 /// Smallest positive e for which ``half(1.0 + e) != half(1.0)``
216 # define HALF_EPSILON 0.00097656f
217 #else
218 /// Smallest positive denormalized half
219 # define HALF_DENORM_MIN 5.96046448e-08
220 /// Smallest positive normalized half
221 # define HALF_NRM_MIN 6.10351562e-05
222 /// Smallest positive normalized half
223 # define HALF_MIN 6.10351562e-05f
224 /// Largest positive half
225 # define HALF_MAX 65504.0
226 /// Smallest positive e for which ``half(1.0 + e) != half(1.0)``
227 # define HALF_EPSILON 0.00097656
228 #endif
229 
230 /// Number of digits in mantissa (significand + hidden leading 1)
231 #define HALF_MANT_DIG 11
232 /// Number of base 10 digits that can be represented without change:
233 ///
234 /// ``floor( (HALF_MANT_DIG - 1) * log10(2) ) => 3.01... -> 3``
235 #define HALF_DIG 3
236 /// Number of base-10 digits that are necessary to uniquely represent
237 /// all distinct values:
238 ///
239 /// ``ceil(HALF_MANT_DIG * log10(2) + 1) => 4.31... -> 5``
240 #define HALF_DECIMAL_DIG 5
241 /// Base of the exponent
242 #define HALF_RADIX 2
243 /// Minimum negative integer such that ``HALF_RADIX`` raised to the power
244 /// of one less than that integer is a normalized half
245 #define HALF_DENORM_MIN_EXP -13
246 /// Maximum positive integer such that ``HALF_RADIX`` raised to the power
247 /// of one less than that integer is a normalized half
248 #define HALF_MAX_EXP 16
249 /// Minimum positive integer such that 10 raised to that power is a
250 /// normalized half
251 #define HALF_DENORM_MIN_10_EXP -4
252 /// Maximum positive integer such that 10 raised to that power is a
253 /// normalized half
254 #define HALF_MAX_10_EXP 4
255 
256 /// a type for both C-only programs and C++ to use the same utilities
257 typedef union imath_half_uif
258 {
259  uint32_t i;
260  float f;
262 
263 /// a type for both C-only programs and C++ to use the same utilities
264 typedef uint16_t imath_half_bits_t;
265 
266 #if !defined(__cplusplus) && !defined(__CUDACC__)
267 /// if we're in a C-only context, alias the half bits type to half
269 #endif
270 
271 #if !defined(IMATH_HALF_NO_LOOKUP_TABLE)
272 # if defined(__cplusplus)
273 extern "C"
274 # else
275 extern
276 # endif
278 #endif
279 
280 ///
281 /// Convert half to float
282 ///
283 
284 static inline float
285 imath_half_to_float (imath_half_bits_t h)
286 {
287 #if defined(__F16C__)
288  // NB: The intel implementation does seem to treat NaN slightly
289  // different than the original toFloat table does (i.e. where the
290  // 1 bits are, meaning the signalling or not bits). This seems
291  // benign, given that the original library didn't really deal with
292  // signalling vs non-signalling NaNs
293 # ifdef _MSC_VER
294  /* msvc does not seem to have cvtsh_ss :( */
295  return _mm_cvtss_f32 (_mm_cvtph_ps (_mm_set1_epi16 (h)));
296 # else
297  return _cvtsh_ss (h);
298 # endif
299 #elif defined(IMATH_HALF_USE_LOOKUP_TABLE) && \
300  !defined(IMATH_HALF_NO_LOOKUP_TABLE)
301  return imath_half_to_float_table[h].f;
302 #else
304  // this code would be clearer, although it does appear to be faster
305  // (1.06 vs 1.08 ns/call) to avoid the constants and just do 4
306  // shifts.
307  //
308  uint32_t hexpmant = ((uint32_t) (h) << 17) >> 4;
309  v.i = ((uint32_t) (h >> 15)) << 31;
310 
311  // the likely really does help if most of your numbers are "normal" half numbers
312  if (IMATH_LIKELY ((hexpmant >= 0x00800000)))
313  {
314  v.i |= hexpmant;
315  // either we are a normal number, in which case add in the bias difference
316  // otherwise make sure all exponent bits are set
317  if (IMATH_LIKELY ((hexpmant < 0x0f800000)))
318  v.i += 0x38000000;
319  else
320  v.i |= 0x7f800000;
321  }
322  else if (hexpmant != 0)
323  {
324  // exponent is 0 because we're denormal, don't have to extract
325  // the mantissa, can just use as is
326  //
327  //
328  // other compilers may provide count-leading-zeros primitives,
329  // but we need the community to inform us of the variants
330  uint32_t lc;
331 # if defined(_MSC_VER)
332  // The direct intrinsic for this is __lznct, but that is not supported
333  // on older x86_64 hardware or ARM. Instead uses the bsr instruction
334  // and one additional subtraction. This assumes hexpmant != 0, for 0
335  // bsr and lznct would behave differently.
336  unsigned long bsr;
337  _BitScanReverse (&bsr, hexpmant);
338  lc = (31 - bsr);
339 # elif defined(__GNUC__) || defined(__clang__)
340  lc = (uint32_t) __builtin_clz (hexpmant);
341 # else
342  lc = 0;
343  while (0 == ((hexpmant << lc) & 0x80000000))
344  ++lc;
345 # endif
346  lc -= 8;
347  // so nominally we want to remove that extra bit we shifted
348  // up, but we are going to add that bit back in, then subtract
349  // from it with the 0x38800000 - (lc << 23)....
350  //
351  // by combining, this allows us to skip the & operation (and
352  // remove a constant)
353  //
354  // hexpmant &= ~0x00800000;
355  v.i |= 0x38800000;
356  // lc is now x, where the desired exponent is then
357  // -14 - lc
358  // + 127 -> new exponent
359  v.i |= (hexpmant << lc);
360  v.i -= (lc << 23);
361  }
362  return v.f;
363 #endif
364 }
365 
366 ///
367 /// Convert half to float
368 ///
369 /// Note: This only supports the "round to even" rounding mode, which
370 /// was the only mode supported by the original OpenEXR library
371 ///
372 
373 static inline imath_half_bits_t
374 imath_float_to_half (float f)
375 {
376 #if defined(__F16C__)
377 # ifdef _MSC_VER
378  // msvc does not seem to have cvtsh_ss :(
379  return _mm_extract_epi16 (
380  _mm_cvtps_ph (
381  _mm_set_ss (f), (_MM_FROUND_TO_NEAREST_INT)),
382  0);
383 # else
384  // preserve the fixed rounding mode to nearest
385  return _cvtss_sh (f, (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
386 # endif
387 #else
389  imath_half_bits_t ret;
390  uint32_t e, m, ui, r, shift;
391 
392  v.f = f;
393 
394  ui = (v.i & ~0x80000000);
395  ret = ((v.i >> 16) & 0x8000);
396 
397  // exponent large enough to result in a normal number, round and return
398  if (ui >= 0x38800000)
399  {
400  // inf or nan
401  if (IMATH_UNLIKELY (ui >= 0x7f800000))
402  {
403  ret |= 0x7c00;
404  if (ui == 0x7f800000) return ret;
405  m = (ui & 0x7fffff) >> 13;
406  // make sure we have at least one bit after shift to preserve nan-ness
407  return ret | (uint16_t) m | (uint16_t) (m == 0);
408  }
409 
410  // too large, round to infinity
411  if (IMATH_UNLIKELY (ui > 0x477fefff))
412  {
413 # ifdef IMATH_HALF_ENABLE_FP_EXCEPTIONS
414  feraiseexcept (FE_OVERFLOW);
415 # endif
416  return ret | 0x7c00;
417  }
418 
419  ui -= 0x38000000;
420  ui = ((ui + 0x00000fff + ((ui >> 13) & 1)) >> 13);
421  return ret | (uint16_t) ui;
422  }
423 
424  // zero or flush to 0
425  if (ui < 0x33000001)
426  {
427 # ifdef IMATH_HALF_ENABLE_FP_EXCEPTIONS
428  if (ui == 0) return ret;
429  feraiseexcept (FE_UNDERFLOW);
430 # endif
431  return ret;
432  }
433 
434  // produce a denormalized half
435  e = (ui >> 23);
436  shift = 0x7e - e;
437  m = 0x800000 | (ui & 0x7fffff);
438  r = m << (32 - shift);
439  ret |= (m >> shift);
440  if (r > 0x80000000 || (r == 0x80000000 && (ret & 0x1) != 0)) ++ret;
441  return ret;
442 #endif
443 }
444 
445 ////////////////////////////////////////
446 
447 #ifdef __cplusplus
448 
449 # include <iostream>
450 
451 IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
452 
453 ///
454 ///
455 /// class half represents a 16-bit floating point number
456 ///
457 /// Type half can represent positive and negative numbers whose
458 /// magnitude is between roughly 6.1e-5 and 6.5e+4 with a relative
459 /// error of 9.8e-4; numbers smaller than 6.1e-5 can be represented
460 /// with an absolute error of 6.0e-8. All integers from -2048 to
461 /// +2048 can be represented exactly.
462 ///
463 /// Type half behaves (almost) like the built-in C++ floating point
464 /// types. In arithmetic expressions, half, float and double can be
465 /// mixed freely. Here are a few examples:
466 ///
467 /// half a (3.5);
468 /// float b (a + sqrt (a));
469 /// a += b;
470 /// b += a;
471 /// b = a + 7;
472 ///
473 /// Conversions from half to float are lossless; all half numbers
474 /// are exactly representable as floats.
475 ///
476 /// Conversions from float to half may not preserve a float's value
477 /// exactly. If a float is not representable as a half, then the
478 /// float value is rounded to the nearest representable half. If a
479 /// float value is exactly in the middle between the two closest
480 /// representable half values, then the float value is rounded to
481 /// the closest half whose least significant bit is zero.
482 ///
483 /// Overflows during float-to-half conversions cause arithmetic
484 /// exceptions. An overflow occurs when the float value to be
485 /// converted is too large to be represented as a half, or if the
486 /// float value is an infinity or a NAN.
487 ///
488 /// The implementation of type half makes the following assumptions
489 /// about the implementation of the built-in C++ types:
490 ///
491 /// * float is an IEEE 754 single-precision number
492 /// * sizeof (float) == 4
493 /// * sizeof (unsigned int) == sizeof (float)
494 /// * alignof (unsigned int) == alignof (float)
495 /// * sizeof (uint16_t) == 2
496 ///
497 
499 {
500 public:
501  /// A special tag that lets us initialize a half from the raw bits.
502  enum IMATH_EXPORT_ENUM FromBitsTag
503  {
504  FromBits
505  };
506 
507  /// @{
508  /// @name Constructors
509 
510  /// Default construction provides no initialization (hence it is
511  /// not constexpr).
512  half () IMATH_NOEXCEPT = default;
513 
514  /// Construct from float
515  half (float f) IMATH_NOEXCEPT;
516 
517  /// Construct from bit-vector
518  constexpr half (FromBitsTag, uint16_t bits) IMATH_NOEXCEPT;
519 
520  /// Copy constructor
521  constexpr half (const half&) IMATH_NOEXCEPT = default;
522 
523  /// Move constructor
524  constexpr half (half&&) IMATH_NOEXCEPT = default;
525 
526  /// Destructor
527  ~half () IMATH_NOEXCEPT = default;
528 
529  /// @}
530 
531  /// Conversion to float
532  operator float () const IMATH_NOEXCEPT;
533 
534  /// @{
535  /// @name Basic Algebra
536 
537  /// Unary minus
538  constexpr half operator- () const IMATH_NOEXCEPT;
539 
540  /// Assignment
541  half& operator= (const half& h) IMATH_NOEXCEPT = default;
542 
543  /// Move assignment
544  half& operator= (half&& h) IMATH_NOEXCEPT = default;
545 
546  /// Assignment from float
547  half& operator= (float f) IMATH_NOEXCEPT;
548 
549  /// Addition assignment
550  half& operator+= (half h) IMATH_NOEXCEPT;
551 
552  /// Addition assignment from float
553  half& operator+= (float f) IMATH_NOEXCEPT;
554 
555  /// Subtraction assignment
556  half& operator-= (half h) IMATH_NOEXCEPT;
557 
558  /// Subtraction assignment from float
559  half& operator-= (float f) IMATH_NOEXCEPT;
560 
561  /// Multiplication assignment
562  half& operator*= (half h) IMATH_NOEXCEPT;
563 
564  /// Multiplication assignment from float
565  half& operator*= (float f) IMATH_NOEXCEPT;
566 
567  /// Division assignment
568  half& operator/= (half h) IMATH_NOEXCEPT;
569 
570  /// Division assignment from float
571  half& operator/= (float f) IMATH_NOEXCEPT;
572 
573  /// @}
574 
575  /// Round to n-bit precision (n should be between 0 and 10).
576  /// After rounding, the significand's 10-n least significant
577  /// bits will be zero.
578  IMATH_CONSTEXPR14 half round (unsigned int n) const IMATH_NOEXCEPT;
579 
580  /// @{
581  /// @name Classification
582 
583  /// Return true if a normalized number, a denormalized number, or
584  /// zero.
585  constexpr bool isFinite () const IMATH_NOEXCEPT;
586 
587  /// Return true if a normalized number.
588  constexpr bool isNormalized () const IMATH_NOEXCEPT;
589 
590  /// Return true if a denormalized number.
591  constexpr bool isDenormalized () const IMATH_NOEXCEPT;
592 
593  /// Return true if zero.
594  constexpr bool isZero () const IMATH_NOEXCEPT;
595 
596  /// Return true if NAN.
597  constexpr bool isNan () const IMATH_NOEXCEPT;
598 
599  /// Return true if a positive or a negative infinity
600  constexpr bool isInfinity () const IMATH_NOEXCEPT;
601 
602  /// Return true if the sign bit is set (negative)
603  constexpr bool isNegative () const IMATH_NOEXCEPT;
604 
605  /// @}
606 
607  /// @{
608  /// @name Special values
609 
610  /// Return +infinity
611  static constexpr half posInf () IMATH_NOEXCEPT;
612 
613  /// Return -infinity
614  static constexpr half negInf () IMATH_NOEXCEPT;
615 
616  /// Returns a NAN with the bit pattern 0111111111111111
617  static constexpr half qNan () IMATH_NOEXCEPT;
618 
619  /// Return a NAN with the bit pattern 0111110111111111
620  static constexpr half sNan () IMATH_NOEXCEPT;
621 
622  /// @}
623 
624  /// @{
625  /// @name Access to the internal representation
626 
627  /// Return the bit pattern
628  constexpr uint16_t bits () const IMATH_NOEXCEPT;
629 
630  /// Set the bit pattern
631  IMATH_CONSTEXPR14 void setBits (uint16_t bits) IMATH_NOEXCEPT;
632 
633  /// @}
634 
635 public:
636  static_assert (
637  sizeof (float) == sizeof (uint32_t),
638  "Assumption about the size of floats correct");
639  using uif = imath_half_uif;
640 
641 private:
642  constexpr uint16_t mantissa () const IMATH_NOEXCEPT;
643  constexpr uint16_t exponent () const IMATH_NOEXCEPT;
644 
645  uint16_t _h;
646 };
647 
648 //----------------------------
649 // Half-from-float constructor
650 //----------------------------
651 
652 inline half::half (float f) IMATH_NOEXCEPT : _h (imath_float_to_half (f))
653 {}
654 
655 //------------------------------------------
656 // Half from raw bits constructor
657 //------------------------------------------
658 
659 inline constexpr half::half (FromBitsTag, uint16_t bits) IMATH_NOEXCEPT
660  : _h (bits)
661 {}
662 
663 //-------------------------
664 // Half-to-float conversion
665 //-------------------------
666 
667 inline half::operator float () const IMATH_NOEXCEPT
668 {
669  return imath_half_to_float (_h);
670 }
671 
672 //-------------------------
673 // Round to n-bit precision
674 //-------------------------
675 
676 inline IMATH_CONSTEXPR14 half
677 half::round (unsigned int n) const IMATH_NOEXCEPT
678 {
679  //
680  // Parameter check.
681  //
682 
683  if (n >= 10) return *this;
684 
685  //
686  // Disassemble h into the sign, s,
687  // and the combined exponent and significand, e.
688  //
689 
690  uint16_t s = _h & 0x8000;
691  uint16_t e = _h & 0x7fff;
692 
693  //
694  // Round the exponent and significand to the nearest value
695  // where ones occur only in the (10-n) most significant bits.
696  // Note that the exponent adjusts automatically if rounding
697  // up causes the significand to overflow.
698  //
699 
700  e >>= 9 - n;
701  e += e & 1;
702  e <<= 9 - n;
703 
704  //
705  // Check for exponent overflow.
706  //
707 
708  if (e >= 0x7c00)
709  {
710  //
711  // Overflow occurred -- truncate instead of rounding.
712  //
713 
714  e = _h;
715  e >>= 10 - n;
716  e <<= 10 - n;
717  }
718 
719  //
720  // Put the original sign bit back.
721  //
722 
723  half h (FromBits, s | e);
724 
725  return h;
726 }
727 
728 //-----------------------
729 // Other inline functions
730 //-----------------------
731 
732 inline constexpr half
734 {
735  return half (FromBits, bits () ^ 0x8000);
736 }
737 
738 inline half&
740 {
741  *this = half (f);
742  return *this;
743 }
744 
745 inline half&
746 half::operator+= (half h) IMATH_NOEXCEPT
747 {
748  *this = half (float (*this) + float (h));
749  return *this;
750 }
751 
752 inline half&
753 half::operator+= (float f) IMATH_NOEXCEPT
754 {
755  *this = half (float (*this) + f);
756  return *this;
757 }
758 
759 inline half&
760 half::operator-= (half h) IMATH_NOEXCEPT
761 {
762  *this = half (float (*this) - float (h));
763  return *this;
764 }
765 
766 inline half&
767 half::operator-= (float f) IMATH_NOEXCEPT
768 {
769  *this = half (float (*this) - f);
770  return *this;
771 }
772 
773 inline half&
775 {
776  *this = half (float (*this) * float (h));
777  return *this;
778 }
779 
780 inline half&
782 {
783  *this = half (float (*this) * f);
784  return *this;
785 }
786 
787 inline half&
788 half::operator/= (half h) IMATH_NOEXCEPT
789 {
790  *this = half (float (*this) / float (h));
791  return *this;
792 }
793 
794 inline half&
795 half::operator/= (float f) IMATH_NOEXCEPT
796 {
797  *this = half (float (*this) / f);
798  return *this;
799 }
800 
801 inline constexpr uint16_t
802 half::mantissa () const IMATH_NOEXCEPT
803 {
804  return _h & 0x3ff;
805 }
806 
807 inline constexpr uint16_t
808 half::exponent () const IMATH_NOEXCEPT
809 {
810  return (_h >> 10) & 0x001f;
811 }
812 
813 inline constexpr bool
815 {
816  return exponent () < 31;
817 }
818 
819 inline constexpr bool
820 half::isNormalized () const IMATH_NOEXCEPT
821 {
822  return exponent () > 0 && exponent () < 31;
823 }
824 
825 inline constexpr bool
826 half::isDenormalized () const IMATH_NOEXCEPT
827 {
828  return exponent () == 0 && mantissa () != 0;
829 }
830 
831 inline constexpr bool
833 {
834  return (_h & 0x7fff) == 0;
835 }
836 
837 inline constexpr bool
839 {
840  return exponent () == 31 && mantissa () != 0;
841 }
842 
843 inline constexpr bool
844 half::isInfinity () const IMATH_NOEXCEPT
845 {
846  return exponent () == 31 && mantissa () == 0;
847 }
848 
849 inline constexpr bool
851 {
852  return (_h & 0x8000) != 0;
853 }
854 
855 inline constexpr half
856 half::posInf () IMATH_NOEXCEPT
857 {
858  return half (FromBits, 0x7c00);
859 }
860 
861 inline constexpr half
862 half::negInf () IMATH_NOEXCEPT
863 {
864  return half (FromBits, 0xfc00);
865 }
866 
867 inline constexpr half
868 half::qNan () IMATH_NOEXCEPT
869 {
870  return half (FromBits, 0x7fff);
871 }
872 
873 inline constexpr half
874 half::sNan () IMATH_NOEXCEPT
875 {
876  return half (FromBits, 0x7dff);
877 }
878 
879 inline constexpr uint16_t
880 half::bits () const IMATH_NOEXCEPT
881 {
882  return _h;
883 }
884 
885 inline IMATH_CONSTEXPR14 void
886 half::setBits (uint16_t bits) IMATH_NOEXCEPT
887 {
888  _h = bits;
889 }
890 
891 IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
892 
893 /// Output h to os, formatted as a float
894 IMATH_EXPORT std::ostream&
895  operator<< (std::ostream& os, IMATH_INTERNAL_NAMESPACE::half h);
896 
897 /// Input h from is
898 IMATH_EXPORT std::istream&
899  operator>> (std::istream& is, IMATH_INTERNAL_NAMESPACE::half& h);
900 
901 #include <limits>
902 
903 namespace std
904 {
905 
906 template <> class numeric_limits<IMATH_INTERNAL_NAMESPACE::half>
907 {
908 public:
909  static const bool is_specialized = true;
910 
912  {
913  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0x0400); /*HALF_MIN*/
914  }
916  {
917  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0x7bff); /*HALF_MAX*/
918  }
919  static constexpr IMATH_INTERNAL_NAMESPACE::half lowest ()
920  {
921  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0xfbff); /* -HALF_MAX */
922  }
923 
924  static constexpr int digits = HALF_MANT_DIG;
925  static constexpr int digits10 = HALF_DIG;
926  static constexpr int max_digits10 = HALF_DECIMAL_DIG;
927  static constexpr bool is_signed = true;
928  static constexpr bool is_integer = false;
929  static constexpr bool is_exact = false;
930  static constexpr int radix = HALF_RADIX;
931  static constexpr IMATH_INTERNAL_NAMESPACE::half epsilon () IMATH_NOEXCEPT
932  {
933  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0x1400); /*HALF_EPSILON*/
934  }
935  static constexpr IMATH_INTERNAL_NAMESPACE::half round_error () IMATH_NOEXCEPT
936  {
937  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0x3800); /*0.5*/
938  }
939 
940  static constexpr int min_exponent = HALF_DENORM_MIN_EXP;
941  static constexpr int min_exponent10 = HALF_DENORM_MIN_10_EXP;
942  static constexpr int max_exponent = HALF_MAX_EXP;
943  static constexpr int max_exponent10 = HALF_MAX_10_EXP;
944 
945  static constexpr bool has_infinity = true;
946  static constexpr bool has_quiet_NaN = true;
947  static constexpr bool has_signaling_NaN = true;
948  static constexpr float_denorm_style has_denorm = denorm_present;
949  static constexpr bool has_denorm_loss = false;
950  static constexpr IMATH_INTERNAL_NAMESPACE::half infinity () IMATH_NOEXCEPT
951  {
952  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0x7c00); /*half::posInf()*/
953  }
954  static constexpr IMATH_INTERNAL_NAMESPACE::half quiet_NaN () IMATH_NOEXCEPT
955  {
956  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0x7fff); /*half::qNan()*/
957  }
958  static constexpr IMATH_INTERNAL_NAMESPACE::half signaling_NaN () IMATH_NOEXCEPT
959  {
960  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0x7dff); /*half::sNan()*/
961  }
962  static constexpr IMATH_INTERNAL_NAMESPACE::half denorm_min () IMATH_NOEXCEPT
963  {
964  return IMATH_INTERNAL_NAMESPACE::half (IMATH_INTERNAL_NAMESPACE::half::FromBits, 0x0001); /*HALF_DENORM_MIN*/
965  }
966 
967  static constexpr bool is_iec559 = false;
968  static constexpr bool is_bounded = false;
969  static constexpr bool is_modulo = false;
970 
971  static constexpr bool traps = true;
972  static constexpr bool tinyness_before = false;
973  static constexpr float_round_style round_style = round_to_nearest;
974 };
975 
976 } // namespace std
977 
978 //----------
979 // Debugging
980 //----------
981 
982 IMATH_EXPORT void
983 printBits (std::ostream& os, IMATH_INTERNAL_NAMESPACE::half h);
984 IMATH_EXPORT void printBits (std::ostream& os, float f);
986 IMATH_EXPORT void printBits (char c[35], float f);
987 
988 #if !defined(__CUDACC__) && !defined(__CUDA_FP16_HPP__) && !defined(__HIP__)
990 #elif defined(__CUDACC__) || defined(__CUDA_FP16_HPP__)
991 #include <cuda_fp16.h>
992 #elif defined(__HIP__)
993 #include <hip/amd_detail/amd_hip_fp16.h>
994 #endif
995 
996 #endif // __cplusplus
997 
998 #endif // IMATH_HALF_H_
bool_constant< is_integral< T >::value &&!std::is_same< T, bool >::value &&!std::is_same< T, char >::value &&!std::is_same< T, wchar_t >::value > is_integer
Definition: format.h:824
#define IMATH_NOEXCEPT
Definition: ImathConfig.h:78
#define IMATH_INTERNAL_NAMESPACE
Definition: ImathConfig.h:39
#define HALF_DIG
Definition: half.h:235
imath_half_bits_t half
if we're in a C-only context, alias the half bits type to half
Definition: half.h:268
#define IMATH_EXPORT_TYPE
Definition: ImathExport.h:62
const GLdouble * v
Definition: glcorearb.h:837
OPENVDB_API void printBits(std::ostream &os, half h)
IMATH_EXPORT const imath_half_uif_t * imath_half_to_float_table
#define HALF_DECIMAL_DIG
Definition: half.h:240
IMATH_HOSTDEVICE constexpr Plane3< T > operator-(const Plane3< T > &plane) IMATH_NOEXCEPT
Reflect the pla.
Definition: ImathPlane.h:266
a type for both C-only programs and C++ to use the same utilities
Definition: half.h:257
GLdouble s
Definition: glad.h:3009
uint16_t imath_half_bits_t
a type for both C-only programs and C++ to use the same utilities
Definition: half.h:264
float f
Definition: half.h:260
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:380
uint32_t i
Definition: half.h:259
std::ostream & operator<<(std::ostream &ostr, const DataType &a)
Definition: DataType.h:133
#define HALF_DENORM_MIN_EXP
Definition: half.h:245
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
#define HALF_RADIX
Base of the exponent.
Definition: half.h:242
#define IMATH_EXPORT_ENUM
Definition: ImathExport.h:60
bool isNan(const float x)
Return true if x is a NaN (Not-A-Number) value.
Definition: Math.h:416
vfloat4 round(const vfloat4 &a)
Definition: simd.h:7647
#define HALF_MAX_10_EXP
Definition: half.h:254
IMATH_HOSTDEVICE const Vec2< S > & operator*=(Vec2< S > &v, const Matrix22< T > &m) IMATH_NOEXCEPT
Vector-matrix multiplication: v *= m.
Definition: ImathMatrix.h:5082
#define IMATH_EXPORT
Definition: ImathExport.h:47
constexpr auto digits10() noexcept-> int
Definition: format.h:1289
GLsizeiptr size
Definition: glcorearb.h:664
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_opt >::value > is_signed
Definition: format.h:818
IMATH_NAMESPACE::V2f IMATH_NAMESPACE::Box2i std::string this attribute is obsolete as of OpenEXR v3 float
#define IMATH_UNLIKELY(x)
Definition: ImathConfig.h:135
#define HALF_DENORM_MIN_10_EXP
Definition: half.h:251
LeafData & operator=(const LeafData &)=delete
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLboolean r
Definition: glcorearb.h:1222
#define IMATH_LIKELY(x)
Definition: ImathConfig.h:134
union imath_half_uif imath_half_uif_t
a type for both C-only programs and C++ to use the same utilities
#define HALF_MANT_DIG
Number of digits in mantissa (significand + hidden leading 1)
Definition: half.h:231
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:350
#define HALF_MAX_EXP
Definition: half.h:248
bool isFinite(const float x)
Return true if x is finite.
Definition: Math.h:388