15 #ifndef LIBSPIRV_UTIL_HEX_FLOAT_H_ 16 #define LIBSPIRV_UTIL_HEX_FLOAT_H_ 26 #if defined(_MSC_VER) && _MSC_VER < 1800 30 return ::_isnan(
f) != 0;
34 return ::_finite(
f) == 0;
48 return ((
val.val & 0x7C00) == 0x7C00) && ((
val.val & 0x3FF) != 0);
52 return ((
val.val & 0x7C00) == 0x7C00) && ((
val.val & 0x3FF) == 0);
78 static bool isNan(
float f) {
return std::isnan(
f); }
82 static float max() {
return std::numeric_limits<float>::max(); }
84 static float lowest() {
return std::numeric_limits<float>::lowest(); }
90 static bool isNan(
double f) {
return std::isnan(
f); }
94 static double max() {
return std::numeric_limits<double>::max(); }
96 static double lowest() {
return std::numeric_limits<double>::lowest(); }
114 template <
typename T>
161 template <
typename T>
167 template <
typename T>
177 template <
typename T>
252 template <
typename T,
typename Traits = HexFloatTraits<T>>
329 return static_cast<uint_type>(spvutils::BitwiseCast<uint_type>(
value_) &
361 significand_bits =
static_cast<uint_type>(significand_bits << 1);
374 significand =
static_cast<uint_type>(significand << 1);
397 bool round_denorm_up) {
398 bool significand_is_zero = significand == 0;
403 significand_is_zero =
false;
405 significand =
static_cast<uint_type>(significand >> 1);
409 significand =
static_cast<uint_type>(significand >> 1);
414 if (significand == 0 && !significand_is_zero && round_denorm_up) {
415 significand =
static_cast<uint_type>(0x1);
431 value_ = BitwiseCast<T>(new_value);
442 significand =
static_cast<uint_type>(significand + to_increment);
449 significand =
static_cast<uint_type>(significand >> 1);
459 template <
typename int_type>
468 template <
typename int_type>
481 template <
typename other_T>
484 typedef typename other_T::uint_type other_uint_type;
485 static const int_type num_throwaway_bits =
487 static_cast<int_type>(other_T::num_fraction_bits);
489 static const uint_type last_significant_bit =
490 (num_throwaway_bits < 0)
493 static const uint_type first_rounded_bit =
494 (num_throwaway_bits < 1)
498 static const uint_type throwaway_mask_bits =
499 num_throwaway_bits > 0 ? num_throwaway_bits : 0;
504 other_uint_type out_val = 0;
507 if (num_throwaway_bits <= 0) {
508 out_val =
static_cast<other_uint_type
>(significand);
510 out_val =
static_cast<other_uint_type
>(out_val << shift_amount);
516 if ((significand & throwaway_mask) == 0) {
517 return static_cast<other_uint_type
>(
521 bool round_away_from_zero =
false;
535 if ((first_rounded_bit & significand) == 0) {
538 if (((significand & throwaway_mask) & ~first_rounded_bit) != 0) {
541 round_away_from_zero =
true;
545 if ((significand & last_significant_bit) != 0) {
547 round_away_from_zero =
true;
553 if (round_away_from_zero) {
554 return static_cast<other_uint_type
>(
556 significand, last_significant_bit, carry_bit)));
558 return static_cast<other_uint_type
>(
569 template <
typename other_T>
571 other = other_T(static_cast<typename other_T::native_type>(0));
575 other.set_value(-other.value());
580 bool carried =
false;
581 typename other_T::uint_type rounded_significand =
582 getRoundedNormalizedSignificand<other_T>(round_dir, &carried);
590 check_bit =
static_cast<uint_type>(check_bit >> 1)) {
592 if (check_bit & significand)
break;
600 ((
exponent + carried) > static_cast<int_type>(other_T::exponent_bias) ||
605 other.set_value(BitwiseCast<typename other_T::underlying_type>(
606 static_cast<typename other_T::uint_type>(
607 (negate ? other_T::sign_mask : 0) | other_T::exponent_mask)));
611 typename other_T::uint_type shifted_significand;
612 shifted_significand =
static_cast<typename other_T::uint_type
>(
614 static_cast<int_type>(other_T::num_fraction_bits) -
620 other.set_value(BitwiseCast<typename other_T::underlying_type>(
621 static_cast<typename other_T::uint_type>(
622 (negate ? other_T::sign_mask : 0) | other_T::exponent_mask |
623 (shifted_significand == 0 ? 0x1 : shifted_significand))));
627 bool round_underflow_up =
630 typedef typename other_T::int_type other_int_type;
633 other.setFromSignUnbiasedExponentAndNormalizedSignificand(
634 negate, static_cast<other_int_type>(
exponent), rounded_significand,
643 Traits::num_exponent_bits + Traits::num_fraction_bits + 1,
644 "The number of bits do not fit");
645 static_assert(
sizeof(
T) ==
sizeof(
uint_type),
"The type sizes do not match");
650 const char* dec =
"0123456789";
651 const char* lower =
"abcdef";
652 const char* upper =
"ABCDEF";
653 const char*
p =
nullptr;
654 if ((
p =
strchr(dec, character))) {
655 return static_cast<uint8_t>(
p - dec);
656 }
else if ((
p =
strchr(lower, character))) {
657 return static_cast<uint8_t>(
p - lower + 0xa);
658 }
else if ((
p =
strchr(upper, character))) {
659 return static_cast<uint8_t>(
p - upper + 0xa);
662 assert(
false &&
"This was called with a non-hex character");
667 template <
typename T,
typename Traits>
670 typedef typename HF::uint_type uint_type;
671 typedef typename HF::int_type int_type;
673 static_assert(HF::num_used_bits != 0,
674 "num_used_bits must be non-zero for a valid float");
675 static_assert(HF::num_exponent_bits != 0,
676 "num_exponent_bits must be non-zero for a valid float");
677 static_assert(HF::num_fraction_bits != 0,
678 "num_fractin_bits must be non-zero for a valid float");
680 const uint_type
bits = spvutils::BitwiseCast<uint_type>(
value.value());
681 const char*
const sign = (
bits & HF::sign_mask) ?
"-" :
"";
682 const uint_type
exponent =
static_cast<uint_type
>(
683 (
bits & HF::exponent_mask) >> HF::num_fraction_bits);
685 uint_type fraction =
static_cast<uint_type
>((
bits & HF::fraction_encode_mask)
686 << HF::num_overflow_bits);
688 const bool is_zero =
exponent == 0 && fraction == 0;
689 const bool is_denorm =
exponent == 0 && !is_zero;
693 int_type int_exponent =
static_cast<int_type
>(
exponent - HF::exponent_bias);
696 int_exponent = is_zero ? 0 : int_exponent;
702 while ((fraction & HF::fraction_top_bit) == 0) {
703 fraction =
static_cast<uint_type
>(fraction << 1);
704 int_exponent =
static_cast<int_type
>(int_exponent - 1);
708 fraction =
static_cast<uint_type
>(fraction << 1);
709 fraction &= HF::fraction_represent_mask;
712 uint_type fraction_nibbles = HF::fraction_nibbles;
715 while (fraction_nibbles > 0 && (fraction & 0xF) == 0) {
717 fraction =
static_cast<uint_type
>(fraction >> 4);
721 const auto saved_flags = os.flags();
722 const auto saved_fill = os.fill();
724 os <<
sign <<
"0x" << (is_zero ?
'0' :
'1');
725 if (fraction_nibbles) {
728 os <<
"." << std::setw(static_cast<int>(fraction_nibbles))
729 << std::setfill(
'0') <<
std::hex << fraction;
731 os <<
"p" << std::dec << (int_exponent >= 0 ?
"+" :
"") << int_exponent;
733 os.flags(saved_flags);
742 template <
typename T,
typename Traits>
746 auto next_char = is.peek();
747 if (next_char ==
'-' || next_char ==
'+') {
751 is.setstate(std::ios_base::failbit);
768 template <
typename T,
typename Traits>
781 if (is.fail() &&
value.getUnsignedBits() == 0u) {
784 if (
val.isInfinity()) {
789 is.setstate(std::ios_base::failbit);
809 std::istream& is,
bool negate_value,
823 is.setstate(std::ios_base::failbit);
847 template <
typename T,
typename Traits>
850 using uint_type =
typename HF::uint_type;
851 using int_type =
typename HF::int_type;
853 value.set_value(static_cast<typename HF::native_type>(0.
f));
855 if (is.flags() & std::ios::skipws) {
862 auto next_char = is.peek();
863 bool negate_value =
false;
865 if (next_char !=
'-' && next_char !=
'0') {
869 if (next_char ==
'-') {
872 next_char = is.peek();
875 if (next_char ==
'0') {
877 auto maybe_hex_start = is.peek();
878 if (maybe_hex_start !=
'x' && maybe_hex_start !=
'X') {
890 bool seen_dot =
false;
891 uint_type fraction_index = 0;
893 uint_type fraction = 0;
894 int_type
exponent = HF::exponent_bias;
897 while ((next_char = is.peek()) ==
'0') {
905 bool bits_written =
false;
906 while (!seen_p && !seen_dot) {
908 if (next_char ==
'.') {
910 }
else if (next_char ==
'p') {
917 for (
int i = 0; i < 4; ++i,
number <<= 1) {
918 uint_type write_bit = (
number & 0x8) ? 0x1 : 0x0;
922 fraction =
static_cast<uint_type
>(
924 static_cast<uint_type
>(
925 write_bit << (HF::top_bit_left_shift - fraction_index++)));
928 bits_written |= write_bit != 0;
932 is.setstate(std::ios::failbit);
936 next_char = is.peek();
938 bits_written =
false;
939 while (seen_dot && !seen_p) {
941 if (next_char ==
'p') {
945 for (
int i = 0; i < 4; ++i,
number <<= 1) {
946 uint_type write_bit = (
number & 0x8) ? 0x01 : 0x00;
947 bits_written |= write_bit != 0;
948 if (is_denorm && !bits_written) {
954 fraction =
static_cast<uint_type
>(
956 static_cast<uint_type
>(
957 write_bit << (HF::top_bit_left_shift - fraction_index++)));
963 is.setstate(std::ios::failbit);
967 next_char = is.peek();
970 bool seen_sign =
false;
972 int_type written_exponent = 0;
974 if ((next_char ==
'-' || next_char ==
'+')) {
976 is.setstate(std::ios::failbit);
980 exponent_sign = (next_char ==
'-') ? -1 : 1;
981 }
else if (::
isdigit(next_char)) {
983 written_exponent =
static_cast<int_type
>(written_exponent * 10);
985 static_cast<int_type
>(written_exponent + (next_char -
'0'));
990 next_char = is.peek();
993 written_exponent =
static_cast<int_type
>(written_exponent * exponent_sign);
996 bool is_zero = is_denorm && (fraction == 0);
997 if (is_denorm && !is_zero) {
998 fraction =
static_cast<uint_type
>(fraction << 1);
1000 }
else if (is_zero) {
1005 fraction =
static_cast<uint_type
>(fraction >> 1);
1006 fraction |=
static_cast<uint_type
>(1) << HF::top_bit_left_shift;
1009 fraction = (fraction >> HF::fraction_right_shift) & HF::fraction_encode_mask;
1011 const int_type max_exponent =
1016 fraction =
static_cast<uint_type
>(fraction >> 1);
1019 fraction &= HF::fraction_encode_mask;
1020 if (fraction == 0) {
1033 uint_type output_bits =
static_cast<uint_type
>(
1034 static_cast<uint_type
>(negate_value ? 1 : 0) << HF::top_bit_left_shift);
1035 output_bits |= fraction;
1037 uint_type shifted_exponent =
static_cast<uint_type
>(
1038 static_cast<uint_type
>(
exponent << HF::exponent_left_shift) &
1040 output_bits |= shifted_exponent;
1042 T output_float = spvutils::BitwiseCast<T>(output_bits);
1043 value.set_value(output_float);
1052 template <
typename T>
1054 auto float_val =
value.getAsFloat();
1055 switch (std::fpclassify(float_val)) {
1058 auto saved_precision = os.precision();
1059 os.precision(std::numeric_limits<T>::digits10);
1061 os.precision(saved_precision);
1064 os << HexFloat<FloatProxy<T>>(
value);
1073 os << HexFloat<FloatProxy<Float16>>(
value);
1078 #endif // LIBSPIRV_UTIL_HEX_FLOAT_H_ void underlying_type
Definition: hex_float.h:184
static const uint_type first_exponent_bit
Definition: hex_float.h:296
#define isxdigit(c)
Definition: network_common.c:9
static char * number(char *str, long num, int base, int size, int precision, int type)
Definition: kprintf.c:42
static const uint32_t exponent_left_shift
Definition: hex_float.h:312
void uint_type
Definition: hex_float.h:72
const GLint * first
Definition: glext.h:6478
static const uint32_t num_exponent_bits
Definition: hex_float.h:271
const int_type getUnbiasedNormalizedExponent() const
Definition: hex_float.h:353
char * strchr(const char *string, int c)
Definition: compat_ctype.c:102
GLuint GLfloat * val
Definition: glext.h:7847
static bool isInfinity(double f)
Definition: hex_float.h:92
static const int_type max_exponent
Definition: hex_float.h:319
bool RejectParseDueToLeadingSign(std::istream &is, bool negate_value, HexFloat< T, Traits > &value)
Definition: hex_float.h:743
Definition: hex_float.h:115
const uint_type getNormalizedSignificand() const
Definition: hex_float.h:370
uint_type data_
Definition: hex_float.h:158
static const uint_type fraction_top_bit
Definition: hex_float.h:291
Definition: hex_float.h:246
static const uint32_t num_fraction_bits
Definition: hex_float.h:272
int64_t int_type
Definition: hex_float.h:219
uint64_t uint_type
Definition: hex_float.h:89
uint_type getUnsignedBits() const
Definition: hex_float.h:328
void uint_type
Definition: hex_float.h:180
uint32_t uint_type
Definition: hex_float.h:204
other_T::uint_type getRoundedNormalizedSignificand(round_direction dir, bool *carry_bit)
Definition: hex_float.h:482
double native_type
Definition: hex_float.h:221
GLfloat f
Definition: glext.h:8207
static double lowest()
Definition: hex_float.h:96
uint_type negatable_right_shift(int_type N, uint_type val)
Definition: hex_float.h:469
uint16_t uint_type
Definition: hex_float.h:232
HexFloat(T f)
Definition: hex_float.h:260
FloatProxyTraits< T >::uint_type uint_type
Definition: hex_float.h:117
#define exp(a)
Definition: math.h:32
uint16_t uint_type
Definition: hex_float.h:101
Traits::native_type native_type
Definition: hex_float.h:258
static uint_type incrementSignificand(uint_type significand, uint_type to_increment, bool *carry)
Definition: hex_float.h:440
void native_type
Definition: hex_float.h:186
bool isNegative() const
Definition: hex_float.h:381
static const uint32_t fraction_right_shift
Definition: hex_float.h:315
Definition: bitutils.h:21
std::ostream & operator<<(std::ostream &os, const HexFloat< T, Traits > &value)
Definition: hex_float.h:668
static const T get
Definition: bitutils.h:42
static float max()
Definition: hex_float.h:82
T value_
Definition: hex_float.h:640
Definition: bitutils.h:39
static const uint32_t fraction_nibbles
Definition: hex_float.h:277
#define isdigit(c)
Definition: network_common.c:8
Float16(uint16_t v)
Definition: hex_float.h:45
uint16_t get_value() const
Definition: hex_float.h:55
Float16(const Float16 &other)
Definition: hex_float.h:54
FloatProxy< T > operator-() const
Definition: hex_float.h:132
std::istream & ParseNormalFloat(std::istream &is, bool negate_value, HexFloat< T, Traits > &value)
Definition: hex_float.h:769
T value() const
Definition: hex_float.h:262
Float16()
Definition: hex_float.h:46
Traits::underlying_type underlying_type
Definition: hex_float.h:257
FloatProxy()
Definition: hex_float.h:121
static float lowest()
Definition: hex_float.h:84
uint_type negatable_left_shift(int_type N, uint_type val)
Definition: hex_float.h:460
static const uint_type sign_mask
Definition: hex_float.h:305
signed short int16_t
Definition: stdint.h:122
static Float16 max()
Definition: hex_float.h:58
static bool isInfinity(float f)
Definition: hex_float.h:80
int32_t int_type
Definition: hex_float.h:205
static bool isNan(float f)
Definition: hex_float.h:78
Definition: hex_float.h:244
static FloatProxy< T > lowest()
Definition: hex_float.h:153
const int_type getUnbiasedExponent() const
Definition: hex_float.h:342
void setFromSignUnbiasedExponentAndNormalizedSignificand(bool negative, int_type exponent, uint_type significand, bool round_denorm_up)
Definition: hex_float.h:395
static bool isInfinity(const Float16 &val)
Definition: hex_float.h:51
Definition: hex_float.h:245
uint8_t get_nibble_from_character(int character)
Definition: hex_float.h:649
void set_value(T f)
Definition: hex_float.h:263
uint32_t uint_type
Definition: hex_float.h:77
uint16_t native_type
Definition: hex_float.h:235
GLfloat GLfloat p
Definition: glext.h:9809
signed int int32_t
Definition: stdint.h:123
#define isspace(c)
Definition: network_common.c:11
static s32 hex(char ch)
Definition: debug.c:111
round_direction
Definition: hex_float.h:242
void int_type
Definition: hex_float.h:182
uint_type data() const
Definition: hex_float.h:141
int16_t int_type
Definition: hex_float.h:233
uint16_t underlying_type
Definition: hex_float.h:234
static bool isInfinity(Float16 f)
Definition: hex_float.h:104
GLint * exponent
Definition: glsym_gl.h:1069
static const uint_type exponent_mask
Definition: hex_float.h:308
bool operator==(const FloatProxy< T > &first, const FloatProxy< T > &second)
Definition: hex_float.h:162
const GLdouble * v
Definition: glext.h:6391
uint_type getBits() const
Definition: hex_float.h:325
Definition: hex_float.h:253
float native_type
Definition: hex_float.h:207
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:11836
static const uint32_t num_used_bits
Definition: hex_float.h:190
static const uint_type fraction_represent_mask
Definition: hex_float.h:286
const uint_type getExponentBits() const
Definition: hex_float.h:335
Traits::uint_type uint_type
Definition: hex_float.h:255
static bool isNan(Float16 f)
Definition: hex_float.h:102
std::istream & operator>>(std::istream &is, FloatProxy< T > &value)
Definition: hex_float.h:168
T getAsFloat() const
Definition: hex_float.h:138
static Float16 lowest()
Definition: hex_float.h:108
def sign()
Definition: build.py:201
signed __int64 int64_t
Definition: stdint.h:135
static const uint32_t num_overflow_bits
Definition: hex_float.h:281
bool isNan()
Definition: hex_float.h:144
static const int_type min_exponent
Definition: hex_float.h:322
static const uint32_t num_fraction_bits
Definition: hex_float.h:194
GLsizei const GLfloat * value
Definition: glext.h:6709
static bool isNan(const Float16 &val)
Definition: hex_float.h:47
Definition: hex_float.h:71
static Float16 lowest()
Definition: hex_float.h:60
static const uint_type fraction_encode_mask
Definition: hex_float.h:301
bool isInfinity()
Definition: hex_float.h:146
FloatProxy< float > underlying_type
Definition: hex_float.h:206
static const uint32_t num_used_bits
Definition: hex_float.h:269
uint16_t val
Definition: hex_float.h:63
FloatProxy(uint_type val)
Definition: hex_float.h:129
Definition: hex_float.h:243
const uint_type getSignificandBits() const
Definition: hex_float.h:347
unsigned short uint16_t
Definition: stdint.h:125
FloatProxy< double > underlying_type
Definition: hex_float.h:220
unsigned __int64 uint64_t
Definition: stdint.h:136
static double max()
Definition: hex_float.h:94
unsigned char uint8_t
Definition: stdint.h:124
static const uint32_t exponent_bias
Definition: hex_float.h:197
unsigned int uint32_t
Definition: stdint.h:126
Definition: hex_float.h:178
Traits::int_type int_type
Definition: hex_float.h:256
static const uint32_t num_exponent_bits
Definition: hex_float.h:192
static const uint32_t top_bit_left_shift
Definition: hex_float.h:275
static bool isNan(double f)
Definition: hex_float.h:90
static FloatProxy< T > max()
Definition: hex_float.h:149
static Float16 max()
Definition: hex_float.h:106
signed char int8_t
Definition: stdint.h:121
FloatProxy(T val)
Definition: hex_float.h:125
static const uint32_t exponent_bias
Definition: hex_float.h:270
Definition: hex_float.h:43
void castTo(other_T &other, round_direction round_dir)
Definition: hex_float.h:570
uint64_t uint_type
Definition: hex_float.h:218
std::ostream & operator<<<Float16 >(std::ostream &os, const FloatProxy< Float16 > &value)
Definition: hex_float.h:1071