From 4c6ea4a9635bb5d66bf3b2352124b1926dcddf7c Mon Sep 17 00:00:00 2001 From: ronak69 Date: Sat, 12 Aug 2023 15:50:52 +0000 Subject: [PATCH] AK: Fix off-by-one error in round-to-even logic of FixedPoint Because of the off-by-one error, the second bit of the fraction was getting ignored in differentiating between fractions equal to 0.5 or greater than 0.5. This resulted in numbers like 2.75 being considered as having fraction equal to 0.5 and getting rounded incorrectly (to 2). --- AK/FixedPoint.h | 4 ++-- Tests/AK/TestFixedPoint.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/AK/FixedPoint.h b/AK/FixedPoint.h index 2dcb78e13f..f5747415a3 100644 --- a/AK/FixedPoint.h +++ b/AK/FixedPoint.h @@ -111,7 +111,7 @@ public: // fract(m_value) >= .5? if (m_value & (1u << (precision - 1))) { // fract(m_value) > .5? - if (m_value & (radix_mask >> 2u)) { + if (m_value & (radix_mask >> 1)) { // yes: round "up"; value += 1; } else { @@ -219,7 +219,7 @@ public: // If last bit cut off is 1: if (value & (1u << (precision - 1))) { // If the bit after is 1 as well - if (value & (radix_mask >> 2u)) { + if (value & (radix_mask >> 1)) { // We round away from 0 ret.raw() += 1; } else { diff --git a/Tests/AK/TestFixedPoint.cpp b/Tests/AK/TestFixedPoint.cpp index cf7806603b..82bb6dfe5e 100644 --- a/Tests/AK/TestFixedPoint.cpp +++ b/Tests/AK/TestFixedPoint.cpp @@ -58,6 +58,9 @@ TEST_CASE(rounding) EXPECT_EQ(Type(-1.5).ceil(), Type(-1)); EXPECT_EQ(Type(-1.25).trunc(), Type(-1)); + EXPECT_EQ(Type(2.75).rint(), Type(3)); + EXPECT_EQ(Type(-1.25).rint(), Type(-1)); + EXPECT_EQ(Type(0.5).lrint(), 0); EXPECT_EQ(Type(0.5).lfloor(), 0); EXPECT_EQ(Type(0.5).lceil(), 1);