From 5f57cf449a609c1a0f61453e6a662ef5df93149c Mon Sep 17 00:00:00 2001 From: Michael Suen Date: Fri, 10 May 2024 23:23:44 +0800 Subject: [PATCH] fixed a bug where -0.5 / -epsilon triggers UB --- include/fixmath/fixed_impl.inl | 6 ++++-- tests/unit_tests.cpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/fixmath/fixed_impl.inl b/include/fixmath/fixed_impl.inl index 38ebc7b..5c50d74 100644 --- a/include/fixmath/fixed_impl.inl +++ b/include/fixmath/fixed_impl.inl @@ -294,8 +294,10 @@ constexpr fixed operator/(fixed a, fixed b) { int64_t rem = 0; if constexpr (sizeof(raw_t) == 8) { // use extended int128 division - raw_t _check_bits = a.raw() >> (fixed::ALL_BITS - fixed::FRACTION_BITS - 1); // check for simple division - if (FIXMATH_LIKELY(_check_bits == 0 || _check_bits == -1)) { + raw_t _check_bits = a.raw() >> (fixed::ALL_BITS - fixed::FRACTION_BITS - 1); + raw_t _remain_bits = a.raw() & (fixed::FRACTION_MASK >> 1); + if (FIXMATH_LIKELY(_check_bits == 0 || (_check_bits == -1 && _remain_bits))) { + // check for simplified division qlo = a.raw() * fixed::RATIO; if constexpr (policy::rounding) { rem = qlo % b.raw(); diff --git a/tests/unit_tests.cpp b/tests/unit_tests.cpp index f372c49..bb2d7c6 100644 --- a/tests/unit_tests.cpp +++ b/tests/unit_tests.cpp @@ -267,6 +267,7 @@ TEST(FIXMATH, DIV) { CHECK_FIX_DIV(ABSERROR, -ABSERROR); CHECK_FIX_DIV(-1.234, -4.321); CHECK_FIX_DIV(-1.234, 4.321); + EXPECT_EQ(-Fix32(0.5) / -Fix32::epsilon(), Fix32::max_sat()); EXPECT_EQ(1 / Fix32::epsilon(), Fix32::max_sat()); EXPECT_EQ(1 / -Fix32::epsilon(), Fix32::min_sat()); EXPECT_EQ(Fix32::max_fix() / Fix32(0.5), Fix32::max_sat());