From 73f4cfa93056556ec454e87147f38dd4a17b0e93 Mon Sep 17 00:00:00 2001 From: Dan Klishch Date: Fri, 4 Nov 2022 11:19:27 -0400 Subject: [PATCH] AK: Introduce fixed-width floating point types (f32, f64, f80 and f128) --- AK/FloatingPoint.h | 18 +++++++----------- AK/Types.h | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/AK/FloatingPoint.h b/AK/FloatingPoint.h index 30b156d17b..02818e8757 100644 --- a/AK/FloatingPoint.h +++ b/AK/FloatingPoint.h @@ -15,13 +15,9 @@ namespace AK { template union FloatExtractor; -#if ARCH(I386) || ARCH(X86_64) || ARCH(AARCH64) -// FIXME: There is no straightforward way, I can think of, to check -// in compile time that long double is really an 80-bit IEEE574 floating point number. -static_assert(__LDBL_MAX__ == 1.189731495357231765e4932L); - +#ifdef AK_HAS_FLOAT_80 template<> -union FloatExtractor { +union FloatExtractor { static constexpr int mantissa_bits = 64; static constexpr unsigned long long mantissa_max = ~0u; static constexpr int exponent_bias = 16383; @@ -32,12 +28,12 @@ union FloatExtractor { unsigned exponent : 15; unsigned sign : 1; }; - long double d; + f80 d; }; #endif template<> -union FloatExtractor { +union FloatExtractor { static constexpr int mantissa_bits = 52; static constexpr unsigned long long mantissa_max = (1ull << 52) - 1; static constexpr int exponent_bias = 1023; @@ -48,11 +44,11 @@ union FloatExtractor { unsigned exponent : 11; unsigned sign : 1; }; - double d; + f64 d; }; template<> -union FloatExtractor { +union FloatExtractor { static constexpr int mantissa_bits = 23; static constexpr unsigned mantissa_max = (1 << 23) - 1; static constexpr int exponent_bias = 127; @@ -63,7 +59,7 @@ union FloatExtractor { unsigned exponent : 8; unsigned sign : 1; }; - float d; + f32 d; }; template diff --git a/AK/Types.h b/AK/Types.h index 7b16d75362..6646fd4254 100644 --- a/AK/Types.h +++ b/AK/Types.h @@ -19,6 +19,22 @@ using i32 = __INT32_TYPE__; using i16 = __INT16_TYPE__; using i8 = __INT8_TYPE__; +#ifndef KERNEL +using f32 = float; +static_assert(__FLT_MANT_DIG__ == 24 && __FLT_MAX_EXP__ == 128); + +using f64 = double; +static_assert(__DBL_MANT_DIG__ == 53 && __DBL_MAX_EXP__ == 1024); + +# if __LDBL_MANT_DIG__ == 64 && __LDBL_MAX_EXP__ == 16384 +# define AK_HAS_FLOAT_80 1 +using f80 = long double; +# elif __LDBL_MANT_DIG__ == 113 && __LDBL_MAX_EXP__ == 16384 +# define AK_HAS_FLOAT_128 1 +using f128 = long double; +# endif +#endif + #ifdef AK_OS_SERENITY using size_t = __SIZE_TYPE__;