From e74b34b69ecb08afdc944b2be98e41042b613168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Mon, 8 Jan 2024 14:12:33 +0100 Subject: [PATCH] LibC: Fix extended floating point software rounding Contrary to IEEE formats, x86's 80-bit extended floats need the topmost mantissa bit to be 1 or else a special kind of NaN is produced. We fix this by reinserting the special bit if necessary. --- Userland/Libraries/LibC/math.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Userland/Libraries/LibC/math.cpp b/Userland/Libraries/LibC/math.cpp index 6b0568ddc03..dbb76a33e09 100644 --- a/Userland/Libraries/LibC/math.cpp +++ b/Userland/Libraries/LibC/math.cpp @@ -99,6 +99,13 @@ static FloatType internal_to_integer(FloatType x, RoundingMode rounding_mode) auto dead_mask = dead_bitcount == sizeof(typename Extractor::ComponentType) * 8 ? ~zero : (one << dead_bitcount) - 1; auto dead_bits = extractor.mantissa & dead_mask; extractor.mantissa &= ~dead_mask; +#ifdef AK_HAS_FLOAT_80 + if constexpr (IsSame) { + // x86 80-bit extended floating point requires the top mantissa bit to always be 1, or we get a special Intel NaN. + if (extractor.mantissa == 0) + extractor.mantissa = one << (Extractor::mantissa_bits - 1); + } +#endif auto nonhalf_fraction_mask = dead_mask >> 1; has_nonhalf_fraction = (dead_bits & nonhalf_fraction_mask) != 0;