From c1ec2ddb6399666fb84143388c8e3b1ad77a0281 Mon Sep 17 00:00:00 2001 From: rmg-x Date: Sat, 9 Nov 2024 14:25:05 -0600 Subject: [PATCH] AK: Add 16-bit float type --- AK/Format.cpp | 7 +++++++ AK/Format.h | 11 +++++++++++ AK/NumericLimits.h | 11 +++++++++++ AK/StdLibExtraDetails.h | 2 ++ AK/Types.h | 3 +++ 5 files changed, 34 insertions(+) diff --git a/AK/Format.cpp b/AK/Format.cpp index 8d6f14cbc8d..27c30661b01 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -1012,6 +1012,13 @@ ErrorOr Formatter::format(FormatBuilder& builder, long double return builder.put_f80(value, base, upper_case, m_use_separator, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode, real_number_display_mode); } +ErrorOr Formatter::format(FormatBuilder& builder, f16 value) +{ + // FIXME: Create a proper put_f16() implementation + Formatter formatter { *this }; + return TRY(formatter.format(builder, static_cast(value))); +} + ErrorOr Formatter::format(FormatBuilder& builder, double value) { u8 base; diff --git a/AK/Format.h b/AK/Format.h index 695522d3453..b4df3bb0e69 100644 --- a/AK/Format.h +++ b/AK/Format.h @@ -551,6 +551,17 @@ struct Formatter : StandardFormatter { ErrorOr format(FormatBuilder&, long double value); }; +template<> +struct Formatter : StandardFormatter { + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(formatter) + { + } + + ErrorOr format(FormatBuilder&, f16 value); +}; + template<> struct Formatter : Formatter { ErrorOr format(FormatBuilder& builder, nullptr_t) diff --git a/AK/NumericLimits.h b/AK/NumericLimits.h index 8279dfe6f54..c36f05e1e89 100644 --- a/AK/NumericLimits.h +++ b/AK/NumericLimits.h @@ -143,6 +143,17 @@ struct NumericLimits { static constexpr size_t digits() { return __LDBL_MANT_DIG__; } }; +template<> +struct NumericLimits { + static constexpr f16 lowest() { return -__FLT16_MAX__; } + static constexpr f16 min_normal() { return __FLT16_MIN__; } + static constexpr f16 min_denormal() { return __FLT16_DENORM_MIN__; } + static constexpr f16 max() { return __FLT16_MAX__; } + static constexpr f16 epsilon() { return __FLT16_EPSILON__; } + static constexpr bool is_signed() { return true; } + static constexpr size_t digits() { return __FLT16_MANT_DIG__; } +}; + } #if USING_AK_GLOBALLY diff --git a/AK/StdLibExtraDetails.h b/AK/StdLibExtraDetails.h index 15af899a32e..4964cda9d0a 100644 --- a/AK/StdLibExtraDetails.h +++ b/AK/StdLibExtraDetails.h @@ -350,6 +350,8 @@ template<> inline constexpr bool __IsFloatingPoint = true; template<> inline constexpr bool __IsFloatingPoint = true; +template<> +inline constexpr bool __IsFloatingPoint = true; template inline constexpr bool IsFloatingPoint = __IsFloatingPoint>; diff --git a/AK/Types.h b/AK/Types.h index 84e24a0508c..a5bbc0846a8 100644 --- a/AK/Types.h +++ b/AK/Types.h @@ -17,6 +17,9 @@ using i32 = __INT32_TYPE__; using i16 = __INT16_TYPE__; using i8 = __INT8_TYPE__; +using f16 = _Float16; +static_assert(__FLT16_MANT_DIG__ == 11 && __FLT16_MAX_EXP__ == 16); + using f32 = float; static_assert(__FLT_MANT_DIG__ == 24 && __FLT_MAX_EXP__ == 128);