12#ifndef OPENVDB_MATH_HALF_HAS_BEEN_INCLUDED
13#define OPENVDB_MATH_HALF_HAS_BEEN_INCLUDED
193#include <openvdb/version.h>
200#elif defined(__x86_64__)
201#include <x86intrin.h>
202#elif defined(__F16C__)
203#include <immintrin.h>
209#ifdef IMATH_HALF_ENABLE_FP_EXCEPTIONS
231#undef IMATH_HALF_USE_LOOKUP_TABLE
232#define IMATH_HALF_NO_LOOKUP_TABLE
242#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
245#define VDBB_HALF_DENORM_MIN 5.96046448e-08f
247#define VDB_HALF_NRM_MIN 6.10351562e-05f
249#define VDB_HALF_MIN 6.10351562e-05f
251#define VDB_HALF_MAX 65504.0f
253#define VDB_HALF_EPSILON 0.00097656f
256#define VDBB_HALF_DENORM_MIN 5.96046448e-08
258#define VDB_HALF_NRM_MIN 6.10351562e-05
260#define VDB_HALF_MIN 6.10351562e-05f
262#define VDB_HALF_MAX 65504.0
264#define VDB_HALF_EPSILON 0.00097656
268#define VDB_HALF_MANT_DIG 11
272#define VDB_HALF_DIG 3
277#define VDB_HALF_DECIMAL_DIG 5
279#define VDB_HALF_RADIX 2
282#define VDBB_HALF_DENORM_MIN_EXP -13
285#define VDB_HALF_MAX_EXP 16
288#define VDBB_HALF_DENORM_MIN_10_EXP -4
291#define VDB_HALF_MAX_10_EXP 4
295typedef union imath_half_uif
302typedef uint16_t imath_half_bits_t;
304#if !defined(__cplusplus) && !defined(__CUDACC__)
306typedef imath_half_bits_t
half;
309#if !defined(IMATH_HALF_NO_LOOKUP_TABLE)
310#if defined(__cplusplus)
315OPENVDB_API const imath_half_uif_t* imath_half_to_float_table;
323imath_half_to_float (imath_half_bits_t h)
333 return _mm_cvtss_f32 (_mm_cvtph_ps (_mm_set1_epi16 (h)));
335 return _cvtsh_ss (h);
337#elif defined(IMATH_HALF_USE_LOOKUP_TABLE) && !defined(IMATH_HALF_NO_LOOKUP_TABLE)
338 return imath_half_to_float_table[h].f;
345 uint32_t hexpmant = ( (uint32_t)(h) << 17 ) >> 4;
346 v.i = ((uint32_t)(h >> 15)) << 31;
359 else if (hexpmant != 0)
368# if defined(_MSC_VER)
374 _BitScanReverse (&bsr, hexpmant);
376# elif defined(__GNUC__) || defined(__clang__)
377 lc = (uint32_t) __builtin_clz (hexpmant);
380 while (0 == ((hexpmant << lc) & 0x80000000))
396 v.i |= (hexpmant << lc);
410static inline imath_half_bits_t
411imath_float_to_half (
float f)
416 return _mm_extract_epi16 (
417 _mm_cvtps_ph (_mm_set_ss (f), (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC)),
421 return _cvtss_sh (f, (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
425 imath_half_bits_t ret;
426 uint32_t e, m, ui, r, shift;
430 ui = (v.i & ~0x80000000);
431 ret = ((v.i >> 16) & 0x8000);
434 if (ui >= 0x38800000)
440 if (ui == 0x7f800000)
442 m = (ui & 0x7fffff) >> 13;
444 return ret | (uint16_t)m | (uint16_t)(m == 0);
450# ifdef IMATH_HALF_ENABLE_FP_EXCEPTIONS
451 feraiseexcept (FE_OVERFLOW);
457 ui = ((ui + 0x00000fff + ((ui >> 13) & 1)) >> 13);
458 return ret | (uint16_t)ui;
464# ifdef IMATH_HALF_ENABLE_FP_EXCEPTIONS
467 feraiseexcept (FE_UNDERFLOW);
475 m = 0x800000 | (ui & 0x7fffff);
476 r = m << (32 - shift);
478 if (r > 0x80000000 || (r == 0x80000000 && (ret & 0x1) != 0))
545 half() noexcept = default;
548 half (
float f) noexcept;
551 constexpr half (FromBitsTag, uint16_t bits) noexcept;
554 constexpr half (const half&) noexcept = default;
557 constexpr half (half&&) noexcept = default;
560 ~half() noexcept = default;
565 operator
float() const noexcept;
571 constexpr half operator-() const noexcept;
574 half& operator= (const half& h) noexcept = default;
577 half& operator= (half&& h) noexcept = default;
580 half& operator= (
float f) noexcept;
583 half& operator+= (half h) noexcept;
586 half& operator+= (
float f) noexcept;
589 half& operator-= (half h) noexcept;
592 half& operator-= (
float f) noexcept;
595 half& operator*= (half h) noexcept;
598 half& operator*= (
float f) noexcept;
601 half& operator/= (half h) noexcept;
604 half& operator/= (
float f) noexcept;
611 constexpr half round (
unsigned int n) const noexcept;
618 constexpr
bool isFinite() const noexcept;
621 constexpr
bool isNormalized() const noexcept;
624 constexpr
bool isDenormalized() const noexcept;
627 constexpr
bool isZero() const noexcept;
630 constexpr
bool isNan() const noexcept;
633 constexpr
bool isInfinity() const noexcept;
636 constexpr
bool isNegative() const noexcept;
644 static constexpr half posInf() noexcept;
647 static constexpr half negInf() noexcept;
650 static constexpr half qNan() noexcept;
653 static constexpr half sNan() noexcept;
661 constexpr uint16_t bits() const noexcept;
664 constexpr
void setBits (uint16_t bits) noexcept;
669 static_assert (sizeof (
float) == sizeof (uint32_t),
670 "Assumption about the size of floats correct");
671 using uif = imath_half_uif;
675 constexpr uint16_t mantissa() const noexcept;
676 constexpr uint16_t exponent() const noexcept;
685inline half::half (
float f) noexcept
686 : _h (imath_float_to_half (f))
694inline constexpr half::half (FromBitsTag, uint16_t bits) noexcept : _h (bits)
701inline half::operator float() const noexcept
703 return imath_half_to_float (_h);
711half::round (
unsigned int n)
const noexcept
725 uint16_t s = _h & 0x8000;
726 uint16_t e = _h & 0x7fff;
758 half h (FromBits, s | e);
768half::operator-() const noexcept
770 return half (FromBits, bits() ^ 0x8000);
774half::operator= (
float f)
noexcept
781half::operator+= (half h)
noexcept
783 *
this =
half (
float (*
this) +
float (h));
788half::operator+= (
float f)
noexcept
790 *
this =
half (
float (*
this) + f);
795half::operator-= (half h)
noexcept
797 *
this =
half (
float (*
this) -
float (h));
802half::operator-= (
float f)
noexcept
804 *
this =
half (
float (*
this) - f);
809half::operator*= (half h)
noexcept
811 *
this =
half (
float (*
this) *
float (h));
816half::operator*= (
float f)
noexcept
818 *
this =
half (
float (*
this) * f);
823half::operator/= (half h)
noexcept
825 *
this =
half (
float (*
this) /
float (h));
830half::operator/= (
float f)
noexcept
832 *
this =
half (
float (*
this) / f);
836inline constexpr uint16_t
837half::mantissa() const noexcept
842inline constexpr uint16_t
843half::exponent() const noexcept
845 return (_h >> 10) & 0x001f;
849half::isFinite() const noexcept
851 return exponent() < 31;
855half::isNormalized() const noexcept
857 return exponent() > 0 && exponent() < 31;
861half::isDenormalized() const noexcept
863 return exponent() == 0 && mantissa() != 0;
867half::isZero() const noexcept
869 return (_h & 0x7fff) == 0;
873half::isNan() const noexcept
875 return exponent() == 31 && mantissa() != 0;
879half::isInfinity() const noexcept
881 return exponent() == 31 && mantissa() == 0;
885half::isNegative() const noexcept
887 return (_h & 0x8000) != 0;
891half::posInf() noexcept
893 return half (FromBits, 0x7c00);
897half::negInf() noexcept
899 return half (FromBits, 0xfc00);
905 return half (FromBits, 0x7fff);
911 return half (FromBits, 0x7dff);
914inline constexpr uint16_t
915half::bits() const noexcept
921half::setBits (uint16_t bits)
noexcept
930OPENVDB_API void printBits (std::ostream& os, half h);
931OPENVDB_API void printBits (std::ostream& os,
float f);
936OPENVDB_API std::ostream& operator<< (std::ostream& os, half h);
939OPENVDB_API std::istream& operator>> (std::istream& is, half& h);
951template <>
class numeric_limits<openvdb::math::internal::half>
954 static const bool is_specialized =
true;
956 static constexpr openvdb::math::internal::half
min () noexcept
958 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0x0400);
960 static constexpr openvdb::math::internal::half
max () noexcept
962 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0x7bff);
964 static constexpr openvdb::math::internal::half lowest ()
966 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0xfbff);
969 static constexpr int digits = VDB_HALF_MANT_DIG;
970 static constexpr int digits10 = VDB_HALF_DIG;
971 static constexpr int max_digits10 = VDB_HALF_DECIMAL_DIG;
972 static constexpr bool is_signed =
true;
973 static constexpr bool is_integer =
false;
974 static constexpr bool is_exact =
false;
975 static constexpr int radix = VDB_HALF_RADIX;
976 static constexpr openvdb::math::internal::half epsilon () noexcept
978 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0x1400);
980 static constexpr openvdb::math::internal::half round_error () noexcept
982 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0x3800);
985 static constexpr int min_exponent = VDBB_HALF_DENORM_MIN_EXP;
986 static constexpr int min_exponent10 = VDBB_HALF_DENORM_MIN_10_EXP;
987 static constexpr int max_exponent = VDB_HALF_MAX_EXP;
988 static constexpr int max_exponent10 = VDB_HALF_MAX_10_EXP;
990 static constexpr bool has_infinity =
true;
991 static constexpr bool has_quiet_NaN =
true;
992 static constexpr bool has_signaling_NaN =
true;
993 static constexpr float_denorm_style has_denorm = denorm_present;
994 static constexpr bool has_denorm_loss =
false;
995 static constexpr openvdb::math::internal::half infinity () noexcept
997 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0x7c00);
999 static constexpr openvdb::math::internal::half quiet_NaN () noexcept
1001 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0x7fff);
1003 static constexpr openvdb::math::internal::half signaling_NaN () noexcept
1005 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0x7dff);
1007 static constexpr openvdb::math::internal::half denorm_min () noexcept
1009 return openvdb::math::internal::half (openvdb::math::internal::half::FromBits, 0x0001);
1012 static constexpr bool is_iec559 =
false;
1013 static constexpr bool is_bounded =
false;
1014 static constexpr bool is_modulo =
false;
1016 static constexpr bool traps =
true;
1017 static constexpr bool tinyness_before =
false;
1018 static constexpr float_round_style round_style = round_to_nearest;
internal::half half
Definition HalfDecl.h:25
Definition Exceptions.h:13
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:284