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); });
203template<
typename CharT>
204struct std::formatter<
hi::float16, CharT> : std::formatter<float, CharT> {
205 constexpr auto format(hi::float16
const& t,
auto& fc)
207 return std::formatter<float, CharT>::format(
static_cast<float>(t), fc);
213 using value_type = hi::float16;
215 static constexpr bool is_specialized =
true;
217 static constexpr bool is_integer =
false;
218 static constexpr bool is_exact =
false;
219 static constexpr bool has_infinity =
true;
220 static constexpr bool has_quiet_NaN =
true;
221 static constexpr bool has_signaling_NaN =
false;
222 static constexpr float_denorm_style has_denorm = std::denorm_present;
223 static constexpr bool has_denorm_loss =
false;
224 static constexpr float_round_style round_style = std::round_to_nearest;
225 static constexpr bool is_iec559 =
true;
226 static constexpr bool is_bounded =
true;
227 static constexpr bool is_modulo =
false;
228 static constexpr int digits = 10;
229 static constexpr int digits10 = 4;
230 static constexpr int max_digits10 = 4;
231 static constexpr int min_exponent = -14;
232 static constexpr int min_exponent10 = -3;
233 static constexpr int max_exponent = 15;
234 static constexpr int max_exponent10 = 3;
235 static constexpr bool traps =
false;
236 static constexpr bool tinyness_before =
false;
238 static constexpr value_type
min()
noexcept
240 return hi::float16::from_uint16_t(0x0400);
243 static constexpr value_type
lowest()
noexcept
245 return hi::float16::from_uint16_t(0xfbff);
248 static constexpr value_type
max()
noexcept
250 return hi::float16::from_uint16_t(0x7bff);
253 static constexpr value_type
epsilon()
noexcept
255 return hi::float16::from_uint16_t(0xfbff);
260 return hi::float16::from_uint16_t(0x3800);
263 static constexpr value_type
infinity()
noexcept
265 return hi::float16::from_uint16_t(0x7c00);
268 static constexpr value_type
quiet_NaN()
noexcept
270 return hi::float16::from_uint16_t(0x7c01);
275 return hi::float16::from_uint16_t(0x7e01);
278 static constexpr value_type
denorm_min()
noexcept
280 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)