15hi_warning_ignore_msvc(26472);
17namespace hi::inline
v1 {
19constexpr uint32_t float16_bias = 15;
20constexpr uint32_t float32_bias = 127;
21constexpr uint32_t f32_to_f16_adjustment_exponent = float32_bias - float16_bias;
22constexpr uint32_t f32_to_f16_lowest_normal_exponent = 0x01 + f32_to_f16_adjustment_exponent;
23constexpr uint32_t f32_to_f16_infinite_exponent = 0x1f + f32_to_f16_adjustment_exponent;
24constexpr uint32_t f32_to_f16_adjustment = f32_to_f16_adjustment_exponent << 23;
25constexpr uint32_t f32_to_f16_lowest_normal = f32_to_f16_lowest_normal_exponent << 23;
26constexpr uint32_t f32_to_f16_infinite = f32_to_f16_infinite_exponent << 23;
28constexpr float cvtsh_ss(uint16_t value)
noexcept
34 hilet sign = (u >> 15) << 31;
40 u = u + f32_to_f16_adjustment;
43 hilet is_normal = u > (f32_to_f16_lowest_normal - 1);
49 u = is_normal ? u : 0;
51 return std::bit_cast<float>(u);
54constexpr uint16_t cvtss_sh(
float value)
noexcept
57 auto u = std::bit_cast<uint32_t>(value);
60 hilet sign =
static_cast<uint32_t
>(
static_cast<int32_t
>(u) >> 31) << 15;
66 hilet is_normal = u > (f32_to_f16_lowest_normal - 1);
69 u =
std::min(u, f32_to_f16_infinite);
72 u = u - f32_to_f16_adjustment;
78 u = is_normal ? u : 0;
85 return static_cast<uint16_t
>(u);
91 constexpr float16()
noexcept =
default;
98 constexpr explicit float16(
float other) noexcept : v(cvtss_sh(other)) {}
99 constexpr explicit float16(
double other) noexcept :
float16(
static_cast<float>(other)) {}
100 constexpr explicit float16(
long double other) noexcept :
float16(
static_cast<float>(other)) {}
102 constexpr float16& operator=(
float other)
noexcept
108 constexpr operator float()
const noexcept
113 [[nodiscard]]
static constexpr float16 from_uint16_t(uint16_t
const rhs)
noexcept
120 [[nodiscard]]
constexpr uint16_t get()
const noexcept
125 constexpr float16& set(uint16_t rhs)
noexcept
136 [[nodiscard]]
constexpr friend bool operator==(
float16 const& lhs,
float16 const& rhs)
noexcept
138 return static_cast<float>(lhs) ==
static_cast<float>(rhs);
141 [[nodiscard]]
constexpr friend auto operator<=>(
float16 const& lhs,
float16 const& rhs)
noexcept
143 return static_cast<float>(lhs) <=>
static_cast<float>(rhs);
146#define HI_X_binary_math_op(op) \
147 [[nodiscard]] constexpr friend float16 operator op(float16 const& lhs, float16 const& rhs) noexcept \
149 return float16{static_cast<float>(lhs) op static_cast<float>(rhs)}; \
153 HI_X_binary_math_op(+)
154 HI_X_binary_math_op(-)
155 HI_X_binary_math_op(*)
156 HI_X_binary_math_op(/)
158#undef HI_X_binary_math_op
168#define HI_X_binary_bit_op(op) \
169 [[nodiscard]] constexpr friend float16 operator op(float16 const& lhs, float16 const& rhs) noexcept \
171 return float16::from_uint16_t(lhs.v op rhs.v); \
175 HI_X_binary_bit_op(|)
176 HI_X_binary_bit_op(&)
177 HI_X_binary_bit_op(^)
179#undef HI_X_binary_bit_op
183static_assert(
sizeof(
float16) ==
sizeof(uint16_t));
184static_assert(std::is_trivially_copy_constructible_v<float16>);
185static_assert(std::is_trivially_move_constructible_v<float16>);
186static_assert(std::is_trivially_copy_assignable_v<float16>);
187static_assert(std::is_trivially_move_assignable_v<float16>);
188static_assert(std::is_trivially_destructible_v<float16>);
190static_assert(
requires(
float16 a) { std::bit_cast<uint16_t>(a); });
191static_assert(
requires(uint16_t a) { std::bit_cast<float16>(a); });
205 using value_type = hi::float16;
207 static constexpr bool is_specialized =
true;
209 static constexpr bool is_integer =
false;
210 static constexpr bool is_exact =
false;
211 static constexpr bool has_infinity =
true;
212 static constexpr bool has_quiet_NaN =
true;
213 static constexpr bool has_signaling_NaN =
false;
214 static constexpr float_denorm_style has_denorm = std::denorm_present;
215 static constexpr bool has_denorm_loss =
false;
216 static constexpr float_round_style round_style = std::round_to_nearest;
217 static constexpr bool is_iec559 =
true;
218 static constexpr bool is_bounded =
true;
219 static constexpr bool is_modulo =
false;
220 static constexpr int digits = 10;
221 static constexpr int digits10 = 4;
222 static constexpr int max_digits10 = 4;
223 static constexpr int min_exponent = -14;
224 static constexpr int min_exponent10 = -3;
225 static constexpr int max_exponent = 15;
226 static constexpr int max_exponent10 = 3;
227 static constexpr bool traps =
false;
228 static constexpr bool tinyness_before =
false;
230 static constexpr value_type
min()
noexcept
232 return hi::float16::from_uint16_t(0x0400);
235 static constexpr value_type
lowest()
noexcept
237 return hi::float16::from_uint16_t(0xfbff);
240 static constexpr value_type
max()
noexcept
242 return hi::float16::from_uint16_t(0x7bff);
245 static constexpr value_type
epsilon()
noexcept
247 return hi::float16::from_uint16_t(0xfbff);
252 return hi::float16::from_uint16_t(0x3800);
255 static constexpr value_type
infinity()
noexcept
257 return hi::float16::from_uint16_t(0x7c00);
260 static constexpr value_type
quiet_NaN()
noexcept
262 return hi::float16::from_uint16_t(0x7c01);
267 return hi::float16::from_uint16_t(0x7e01);
270 static constexpr value_type
denorm_min()
noexcept
272 return hi::float16::from_uint16_t(0x0001);
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Definition float16.hpp:88
T signaling_NaN(T... args)