7#include "../macros.hpp"
15hi_export_module(hikogui.utility.float16);
20hi_warning_ignore_msvc(26472);
24constexpr uint32_t float16_bias = 15;
25constexpr uint32_t float32_bias = 127;
26constexpr uint32_t f32_to_f16_adjustment_exponent = float32_bias - float16_bias;
27constexpr uint32_t f32_to_f16_lowest_normal_exponent = 0x01 + f32_to_f16_adjustment_exponent;
28constexpr uint32_t f32_to_f16_infinite_exponent = 0x1f + f32_to_f16_adjustment_exponent;
29constexpr uint32_t f32_to_f16_adjustment = f32_to_f16_adjustment_exponent << 23;
30constexpr uint32_t f32_to_f16_lowest_normal = f32_to_f16_lowest_normal_exponent << 23;
31constexpr uint32_t f32_to_f16_infinite = f32_to_f16_infinite_exponent << 23;
33constexpr float cvtsh_ss(uint16_t value)
noexcept
39 hilet
sign = (
u >> 15) << 31;
45 u =
u + f32_to_f16_adjustment;
48 hilet
is_normal =
u > (f32_to_f16_lowest_normal - 1);
56 return std::bit_cast<float>(
u);
59constexpr uint16_t cvtss_sh(
float value)
noexcept
62 auto u = std::bit_cast<uint32_t>(value);
65 hilet
sign =
static_cast<uint32_t
>(
static_cast<int32_t
>(
u) >> 31) << 15;
71 hilet
is_normal =
u > (f32_to_f16_lowest_normal - 1);
77 u =
u - f32_to_f16_adjustment;
90 return static_cast<uint16_t
>(
u);
96 constexpr float16()
noexcept =
default;
103 constexpr explicit float16(
float other) noexcept : v(cvtss_sh(other)) {}
104 constexpr explicit float16(
double other) noexcept :
float16(
static_cast<float>(other)) {}
105 constexpr explicit float16(
long double other) noexcept :
float16(
static_cast<float>(other)) {}
107 constexpr float16& operator=(
float other)
noexcept
113 constexpr operator float()
const noexcept
118 [[nodiscard]]
constexpr static float16 from_uint16_t(uint16_t
const rhs)
noexcept
125 [[nodiscard]]
constexpr uint16_t get()
const noexcept
130 constexpr float16& set(uint16_t rhs)
noexcept
141 [[nodiscard]]
constexpr friend bool operator==(
float16 const& lhs,
float16 const& rhs)
noexcept
143 return static_cast<float>(lhs) ==
static_cast<float>(rhs);
146 [[nodiscard]]
constexpr friend auto operator<=>(
float16 const& lhs,
float16 const& rhs)
noexcept
148 return static_cast<float>(lhs) <=>
static_cast<float>(rhs);
151#define HI_X_binary_math_op(op) \
152 [[nodiscard]] constexpr friend float16 operator op(float16 const& lhs, float16 const& rhs) noexcept \
154 return float16{static_cast<float>(lhs) op static_cast<float>(rhs)}; \
158 HI_X_binary_math_op(+)
159 HI_X_binary_math_op(-)
160 HI_X_binary_math_op(*)
161 HI_X_binary_math_op(/)
163#undef HI_X_binary_math_op
173#define HI_X_binary_bit_op(op) \
174 [[nodiscard]] constexpr friend float16 operator op(float16 const& lhs, float16 const& rhs) noexcept \
176 return float16::from_uint16_t(lhs.v op rhs.v); \
180 HI_X_binary_bit_op(|)
181 HI_X_binary_bit_op(&)
182 HI_X_binary_bit_op(^)
184#undef HI_X_binary_bit_op
188static_assert(
sizeof(
float16) ==
sizeof(uint16_t));
189static_assert(std::is_trivially_copy_constructible_v<float16>);
190static_assert(std::is_trivially_move_constructible_v<float16>);
191static_assert(std::is_trivially_copy_assignable_v<float16>);
192static_assert(std::is_trivially_move_assignable_v<float16>);
193static_assert(std::is_trivially_destructible_v<float16>);
195static_assert(
requires(
float16 a) { std::bit_cast<uint16_t>(a); });
196static_assert(
requires(uint16_t a) { std::bit_cast<float16>(a); });
208hi_export
template<
typename CharT>
209struct std::formatter<
hi::float16, CharT> : std::formatter<float, CharT> {
210 constexpr auto format(hi::float16
const& t,
auto& fc)
const
212 return std::formatter<float, CharT>::format(
static_cast<float>(t), fc);
218 using value_type = hi::float16;
220 constexpr static bool is_specialized =
true;
222 constexpr static bool is_integer =
false;
223 constexpr static bool is_exact =
false;
224 constexpr static bool has_infinity =
true;
225 constexpr static bool has_quiet_NaN =
true;
226 constexpr static bool has_signaling_NaN =
false;
227 constexpr static float_round_style round_style = std::round_to_nearest;
228 constexpr static bool is_iec559 =
true;
229 constexpr static bool is_bounded =
true;
230 constexpr static bool is_modulo =
false;
231 constexpr static int digits = 10;
232 constexpr static int digits10 = 4;
233 constexpr static int max_digits10 = 4;
234 constexpr static int min_exponent = -14;
235 constexpr static int min_exponent10 = -3;
236 constexpr static int max_exponent = 15;
237 constexpr static int max_exponent10 = 3;
238 constexpr static bool traps =
false;
239 constexpr static bool tinyness_before =
false;
241 constexpr static value_type
min()
noexcept
243 return hi::float16::from_uint16_t(0x0400);
246 constexpr static value_type
lowest()
noexcept
248 return hi::float16::from_uint16_t(0xfbff);
251 constexpr static value_type
max()
noexcept
253 return hi::float16::from_uint16_t(0x7bff);
256 constexpr static value_type
epsilon()
noexcept
258 return hi::float16::from_uint16_t(0xfbff);
263 return hi::float16::from_uint16_t(0x3800);
266 constexpr static value_type
infinity()
noexcept
268 return hi::float16::from_uint16_t(0x7c00);
271 constexpr static value_type
quiet_NaN()
noexcept
273 return hi::float16::from_uint16_t(0x7c01);
278 return hi::float16::from_uint16_t(0x7e01);
281 constexpr static value_type
denorm_min()
noexcept
283 return hi::float16::from_uint16_t(0x0001);
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Definition float16.hpp:93
T signaling_NaN(T... args)