@@ -31,49 +31,49 @@ namespace fputil {
31
31
template <typename T> struct FPBits : private FloatProperties <T> {
32
32
static_assert (cpp::is_floating_point_v<T>,
33
33
" FPBits instantiated with invalid type." );
34
- using typename FloatProperties<T>::UIntType ;
35
- using FloatProperties<T>::BIT_WIDTH ;
34
+ using typename FloatProperties<T>::StorageType ;
35
+ using FloatProperties<T>::TOTAL_LEN ;
36
36
using FloatProperties<T>::EXP_MANT_MASK;
37
- using FloatProperties<T>::EXPONENT_MASK ;
38
- using FloatProperties<T>::EXPONENT_BIAS ;
39
- using FloatProperties<T>::EXPONENT_WIDTH ;
40
- using FloatProperties<T>::MANTISSA_MASK ;
41
- using FloatProperties<T>::MANTISSA_WIDTH ;
37
+ using FloatProperties<T>::EXP_MASK ;
38
+ using FloatProperties<T>::EXP_BIAS ;
39
+ using FloatProperties<T>::EXP_LEN ;
40
+ using FloatProperties<T>::FRACTION_MASK ;
41
+ using FloatProperties<T>::FRACTION_LEN ;
42
42
using FloatProperties<T>::QUIET_NAN_MASK;
43
43
using FloatProperties<T>::SIGN_MASK;
44
44
45
45
// Reinterpreting bits as an integer value and interpreting the bits of an
46
46
// integer value as a floating point value is used in tests. So, a convenient
47
47
// type is provided for such reinterpretations.
48
- UIntType bits;
48
+ StorageType bits;
49
49
50
- LIBC_INLINE constexpr void set_mantissa (UIntType mantVal) {
51
- mantVal &= MANTISSA_MASK ;
52
- bits &= ~MANTISSA_MASK ;
50
+ LIBC_INLINE constexpr void set_mantissa (StorageType mantVal) {
51
+ mantVal &= FRACTION_MASK ;
52
+ bits &= ~FRACTION_MASK ;
53
53
bits |= mantVal;
54
54
}
55
55
56
- LIBC_INLINE constexpr UIntType get_mantissa () const {
57
- return bits & MANTISSA_MASK ;
56
+ LIBC_INLINE constexpr StorageType get_mantissa () const {
57
+ return bits & FRACTION_MASK ;
58
58
}
59
59
60
- LIBC_INLINE constexpr void set_biased_exponent (UIntType expVal) {
61
- expVal = (expVal << MANTISSA_WIDTH ) & EXPONENT_MASK ;
62
- bits &= ~EXPONENT_MASK ;
60
+ LIBC_INLINE constexpr void set_biased_exponent (StorageType expVal) {
61
+ expVal = (expVal << FRACTION_LEN ) & EXP_MASK ;
62
+ bits &= ~EXP_MASK ;
63
63
bits |= expVal;
64
64
}
65
65
66
66
LIBC_INLINE constexpr uint16_t get_biased_exponent () const {
67
- return uint16_t ((bits & EXPONENT_MASK ) >> MANTISSA_WIDTH );
67
+ return uint16_t ((bits & EXP_MASK ) >> FRACTION_LEN );
68
68
}
69
69
70
70
// The function return mantissa with the implicit bit set iff the current
71
71
// value is a valid normal number.
72
- LIBC_INLINE constexpr UIntType get_explicit_mantissa () {
72
+ LIBC_INLINE constexpr StorageType get_explicit_mantissa () {
73
73
return ((get_biased_exponent () > 0 && !is_inf_or_nan ())
74
- ? (MANTISSA_MASK + 1 )
74
+ ? (FRACTION_MASK + 1 )
75
75
: 0 ) |
76
- (MANTISSA_MASK & bits);
76
+ (FRACTION_MASK & bits);
77
77
}
78
78
79
79
LIBC_INLINE constexpr void set_sign (bool signVal) {
@@ -86,41 +86,41 @@ template <typename T> struct FPBits : private FloatProperties<T> {
86
86
return (bits & SIGN_MASK) != 0 ;
87
87
}
88
88
89
- static_assert (sizeof (T) == sizeof (UIntType ),
89
+ static_assert (sizeof (T) == sizeof (StorageType ),
90
90
" Data type and integral representation have different sizes." );
91
91
92
- static constexpr int MAX_EXPONENT = (1 << EXPONENT_WIDTH ) - 1 ;
92
+ static constexpr int MAX_EXPONENT = (1 << EXP_LEN ) - 1 ;
93
93
94
- static constexpr UIntType MIN_SUBNORMAL = UIntType (1 );
95
- static constexpr UIntType MAX_SUBNORMAL = (UIntType( 1 ) << MANTISSA_WIDTH) - 1 ;
96
- static constexpr UIntType MIN_NORMAL = (UIntType (1 ) << MANTISSA_WIDTH );
97
- static constexpr UIntType MAX_NORMAL =
98
- ((UIntType (MAX_EXPONENT) - 1 ) << MANTISSA_WIDTH ) | MAX_SUBNORMAL;
94
+ static constexpr StorageType MIN_SUBNORMAL = StorageType (1 );
95
+ static constexpr StorageType MAX_SUBNORMAL = FRACTION_MASK ;
96
+ static constexpr StorageType MIN_NORMAL = (StorageType (1 ) << FRACTION_LEN );
97
+ static constexpr StorageType MAX_NORMAL =
98
+ ((StorageType (MAX_EXPONENT) - 1 ) << FRACTION_LEN ) | MAX_SUBNORMAL;
99
99
100
100
// We don't want accidental type promotions/conversions, so we require exact
101
101
// type match.
102
102
template <typename XType, cpp::enable_if_t <cpp::is_same_v<T, XType>, int > = 0 >
103
103
LIBC_INLINE constexpr explicit FPBits (XType x)
104
- : bits(cpp::bit_cast<UIntType >(x)) {}
104
+ : bits(cpp::bit_cast<StorageType >(x)) {}
105
105
106
106
template <typename XType,
107
- cpp::enable_if_t <cpp::is_same_v<XType, UIntType >, int > = 0 >
107
+ cpp::enable_if_t <cpp::is_same_v<XType, StorageType >, int > = 0 >
108
108
LIBC_INLINE constexpr explicit FPBits (XType x) : bits(x) {}
109
109
110
110
LIBC_INLINE constexpr FPBits () : bits(0 ) {}
111
111
112
112
LIBC_INLINE constexpr T get_val () const { return cpp::bit_cast<T>(bits); }
113
113
114
114
LIBC_INLINE constexpr void set_val (T value) {
115
- bits = cpp::bit_cast<UIntType >(value);
115
+ bits = cpp::bit_cast<StorageType >(value);
116
116
}
117
117
118
118
LIBC_INLINE constexpr explicit operator T () const { return get_val (); }
119
119
120
- LIBC_INLINE constexpr UIntType uintval () const { return bits; }
120
+ LIBC_INLINE constexpr StorageType uintval () const { return bits; }
121
121
122
122
LIBC_INLINE constexpr int get_exponent () const {
123
- return int (get_biased_exponent ()) - EXPONENT_BIAS ;
123
+ return int (get_biased_exponent ()) - EXP_BIAS ;
124
124
}
125
125
126
126
// If the number is subnormal, the exponent is treated as if it were the
@@ -134,9 +134,9 @@ template <typename T> struct FPBits : private FloatProperties<T> {
134
134
if (is_zero ()) {
135
135
return 0 ;
136
136
} else if (biased_exp == 0 ) {
137
- return 1 - EXPONENT_BIAS ;
137
+ return 1 - EXP_BIAS ;
138
138
} else {
139
- return biased_exp - EXPONENT_BIAS ;
139
+ return biased_exp - EXP_BIAS ;
140
140
}
141
141
}
142
142
@@ -146,29 +146,29 @@ template <typename T> struct FPBits : private FloatProperties<T> {
146
146
}
147
147
148
148
LIBC_INLINE constexpr bool is_inf () const {
149
- return (bits & EXP_MANT_MASK) == EXPONENT_MASK ;
149
+ return (bits & EXP_MANT_MASK) == EXP_MASK ;
150
150
}
151
151
152
152
LIBC_INLINE constexpr bool is_nan () const {
153
- return (bits & EXP_MANT_MASK) > EXPONENT_MASK ;
153
+ return (bits & EXP_MANT_MASK) > EXP_MASK ;
154
154
}
155
155
156
156
LIBC_INLINE constexpr bool is_quiet_nan () const {
157
- return (bits & EXP_MANT_MASK) == (EXPONENT_MASK | QUIET_NAN_MASK);
157
+ return (bits & EXP_MANT_MASK) == (EXP_MASK | QUIET_NAN_MASK);
158
158
}
159
159
160
160
LIBC_INLINE constexpr bool is_inf_or_nan () const {
161
- return (bits & EXPONENT_MASK ) == EXPONENT_MASK ;
161
+ return (bits & EXP_MASK ) == EXP_MASK ;
162
162
}
163
163
164
164
LIBC_INLINE static constexpr T zero (bool sign = false ) {
165
- return FPBits (sign ? SIGN_MASK : UIntType (0 )).get_val ();
165
+ return FPBits (sign ? SIGN_MASK : StorageType (0 )).get_val ();
166
166
}
167
167
168
168
LIBC_INLINE static constexpr T neg_zero () { return zero (true ); }
169
169
170
170
LIBC_INLINE static constexpr T inf (bool sign = false ) {
171
- return FPBits ((sign ? SIGN_MASK : UIntType (0 )) | EXPONENT_MASK ).get_val ();
171
+ return FPBits ((sign ? SIGN_MASK : StorageType (0 )) | EXP_MASK ).get_val ();
172
172
}
173
173
174
174
LIBC_INLINE static constexpr T neg_inf () { return inf (true ); }
@@ -189,13 +189,13 @@ template <typename T> struct FPBits : private FloatProperties<T> {
189
189
return FPBits (MAX_SUBNORMAL).get_val ();
190
190
}
191
191
192
- LIBC_INLINE static constexpr T build_nan (UIntType v) {
192
+ LIBC_INLINE static constexpr T build_nan (StorageType v) {
193
193
FPBits<T> bits (inf ());
194
194
bits.set_mantissa (v);
195
195
return T (bits);
196
196
}
197
197
198
- LIBC_INLINE static constexpr T build_quiet_nan (UIntType v) {
198
+ LIBC_INLINE static constexpr T build_quiet_nan (StorageType v) {
199
199
return build_nan (QUIET_NAN_MASK | v);
200
200
}
201
201
@@ -209,10 +209,11 @@ template <typename T> struct FPBits : private FloatProperties<T> {
209
209
// 3) The function did not check exponent high limit.
210
210
// 4) "number" zero value is not processed correctly.
211
211
// 5) Number is unsigned, so the result can be only positive.
212
- LIBC_INLINE static constexpr FPBits<T> make_value (UIntType number, int ep) {
212
+ LIBC_INLINE static constexpr FPBits<T> make_value (StorageType number,
213
+ int ep) {
213
214
FPBits<T> result;
214
215
// offset: +1 for sign, but -1 for implicit first bit
215
- int lz = cpp::countl_zero (number) - EXPONENT_WIDTH ;
216
+ int lz = cpp::countl_zero (number) - EXP_LEN ;
216
217
number <<= lz;
217
218
ep -= lz;
218
219
@@ -227,7 +228,7 @@ template <typename T> struct FPBits : private FloatProperties<T> {
227
228
}
228
229
229
230
LIBC_INLINE static constexpr FPBits<T>
230
- create_value (bool sign, UIntType biased_exp, UIntType mantissa) {
231
+ create_value (bool sign, StorageType biased_exp, StorageType mantissa) {
231
232
FPBits<T> result;
232
233
result.set_sign (sign);
233
234
result.set_biased_exponent (biased_exp);
0 commit comments