diff --git a/AK/FixedPoint.h b/AK/FixedPoint.h index a0316ff200e..428298386f5 100644 --- a/AK/FixedPoint.h +++ b/AK/FixedPoint.h @@ -66,19 +66,7 @@ public: template explicit constexpr operator I() const { - I value = m_value >> precision; - // fract(m_value) >= .5? - if (m_value & (1u << (precision - 1))) { - // fract(m_value) > .5? - if (m_value & (radix_mask >> 2u)) { - // yes: round "up"; - value += (m_value > 0 ? 1 : -1); - } else { - // no: round to even; - value += value & 1; - } - } - return value; + return trunc().raw() >> precision; } static constexpr This create_raw(Underlying value) @@ -111,9 +99,23 @@ public: return *this; } + // Note/FIXME: This uses round to nearest break-tie to even + // Not break-tie away from 0 as the C99's round does constexpr This round() const { - return This { static_cast(*this) }; + Underlying value = m_value >> precision; + // fract(m_value) >= .5? + if (m_value & (1u << (precision - 1))) { + // fract(m_value) > .5? + if (m_value & (radix_mask >> 2u)) { + // yes: round "up"; + value += (m_value > 0 ? 1 : -1); + } else { + // no: round to even; + value += value & 1; + } + } + return value; } constexpr This floor() const { @@ -124,7 +126,7 @@ public: return create_raw((m_value & ~radix_mask) + (m_value & radix_mask ? 1 << precision : 0)); } - constexpr This trunk() const + constexpr This trunc() const { return create_raw((m_value & ~radix_mask) + ((m_value & radix_mask) @@ -132,14 +134,14 @@ public: : 0)); } - constexpr Underlying lround() const { return static_cast(*this); } + constexpr Underlying lround() const { return round().raw() >> precision; } constexpr Underlying lfloor() const { return m_value >> precision; } constexpr Underlying lceil() const { return (m_value >> precision) + (m_value & radix_mask ? 1 : 0); } - constexpr Underlying ltrunk() const + constexpr Underlying ltrunc() const { return (m_value >> precision) + ((m_value & radix_mask) @@ -437,7 +439,7 @@ struct Formatter> : StandardFormatter { if constexpr (IsSigned) is_negative = value < 0; - i64 integer = value.ltrunk(); + i64 integer = value.ltrunc(); constexpr u64 one = static_cast(1) << precision; u64 fraction_raw = value.raw() & (one - 1); return builder.put_fixed_point(is_negative, integer, fraction_raw, one, base, upper_case, m_zero_pad, m_use_separator, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode, real_number_display_mode); diff --git a/Tests/AK/TestFixedPoint.cpp b/Tests/AK/TestFixedPoint.cpp index eba039be2d7..b11c8d6ee77 100644 --- a/Tests/AK/TestFixedPoint.cpp +++ b/Tests/AK/TestFixedPoint.cpp @@ -41,42 +41,42 @@ TEST_CASE(rounding) EXPECT_EQ(Type(0.5).round(), Type(0)); EXPECT_EQ(Type(0.5).floor(), Type(0)); EXPECT_EQ(Type(0.5).ceil(), Type(1)); - EXPECT_EQ(Type(0.75).trunk(), Type(0)); + EXPECT_EQ(Type(0.75).trunc(), Type(0)); EXPECT_EQ(Type(1.5).round(), Type(2)); EXPECT_EQ(Type(1.5).floor(), Type(1)); EXPECT_EQ(Type(1.5).ceil(), Type(2)); - EXPECT_EQ(Type(1.25).trunk(), Type(1)); + EXPECT_EQ(Type(1.25).trunc(), Type(1)); EXPECT_EQ(Type(-0.5).round(), Type(0)); EXPECT_EQ(Type(-0.5).floor(), Type(-1)); EXPECT_EQ(Type(-0.5).ceil(), Type(0)); - EXPECT_EQ(Type(-0.75).trunk(), Type(0)); + EXPECT_EQ(Type(-0.75).trunc(), Type(0)); EXPECT_EQ(Type(-1.5).round(), Type(-2)); EXPECT_EQ(Type(-1.5).floor(), Type(-2)); EXPECT_EQ(Type(-1.5).ceil(), Type(-1)); - EXPECT_EQ(Type(-1.25).trunk(), Type(-1)); + EXPECT_EQ(Type(-1.25).trunc(), Type(-1)); EXPECT_EQ(Type(0.5).lround(), 0); EXPECT_EQ(Type(0.5).lfloor(), 0); EXPECT_EQ(Type(0.5).lceil(), 1); - EXPECT_EQ(Type(0.5).ltrunk(), 0); + EXPECT_EQ(Type(0.5).ltrunc(), 0); EXPECT_EQ(Type(1.5).lround(), 2); EXPECT_EQ(Type(1.5).lfloor(), 1); EXPECT_EQ(Type(1.5).lceil(), 2); - EXPECT_EQ(Type(1.5).ltrunk(), 1); + EXPECT_EQ(Type(1.5).ltrunc(), 1); EXPECT_EQ(Type(-0.5).lround(), 0); EXPECT_EQ(Type(-0.5).lfloor(), -1); EXPECT_EQ(Type(-0.5).lceil(), 0); - EXPECT_EQ(Type(-0.5).ltrunk(), 0); + EXPECT_EQ(Type(-0.5).ltrunc(), 0); EXPECT_EQ(Type(-1.5).lround(), -2); EXPECT_EQ(Type(-1.5).lfloor(), -2); EXPECT_EQ(Type(-1.5).lceil(), -1); - EXPECT_EQ(Type(-1.5).ltrunk(), -1); + EXPECT_EQ(Type(-1.5).ltrunc(), -1); // Check that sRGB TRC curve parameters match the s15fixed16 values stored in Gimp's built-in profile. // (This only requires that the FixedPoint<> constructor rounds before truncating to the fixed-point value, diff --git a/Userland/Libraries/LibEDID/DMT.cpp b/Userland/Libraries/LibEDID/DMT.cpp index 6edc39f2e8a..a145e3a0fa4 100644 --- a/Userland/Libraries/LibEDID/DMT.cpp +++ b/Userland/Libraries/LibEDID/DMT.cpp @@ -116,7 +116,7 @@ FixedPoint<16, u32> DMT::MonitorTiming::vertical_frequency_hz() const u32 DMT::MonitorTiming::refresh_rate_hz() const { - return vertical_frequency_hz().ltrunk(); + return vertical_frequency_hz().ltrunc(); } #ifndef KERNEL