File tree Expand file tree Collapse file tree 2 files changed +18
-7
lines changed
src/__support/fixed_point Expand file tree Collapse file tree 2 files changed +18
-7
lines changed Original file line number Diff line number Diff line change 2222
2323#include " fx_rep.h"
2424
25+ #include < stdio.h>
26+
2527#ifdef LIBC_COMPILER_HAS_FIXED_POINT
2628
2729namespace LIBC_NAMESPACE_DECL {
@@ -246,13 +248,21 @@ template <typename XType> LIBC_INLINE constexpr XType divi(int n, int d) {
246248 }
247249 bool result_is_negative = ((n < 0 ) != (d < 0 ));
248250
249- unsigned int nv = static_cast <unsigned int >(n < 0 ? -n : n);
250- unsigned int dv = static_cast <unsigned int >(d < 0 ? -d : d);
251- unsigned int clz = cpp::countl_zero<unsigned int >(dv) - 1 ;
252- unsigned long int scaled_val = dv << clz;
251+ int64_t n64 = static_cast <int64_t >(n);
252+ int64_t d64 = static_cast <int64_t >(d);
253+
254+ uint64_t nv = static_cast <uint64_t >(n64 < 0 ? -n64 : n64);
255+ uint64_t dv = static_cast <uint64_t >(d64 < 0 ? -d64 : d64);
256+
257+ if (d == INT_MIN) {
258+ dv = dv - 1 ; // Two's complement
259+ }
260+
261+ uint32_t clz = cpp::countl_zero<uint32_t >(static_cast <uint32_t >(dv)) - 1 ;
262+ uint64_t scaled_val = dv << clz;
253263 // Scale denominator to be in the range of [0.5,1]
254264 FXBits<long accum> d_scaled{scaled_val};
255- unsigned long int scaled_val_n = nv << clz;
265+ uint64_t scaled_val_n = nv << clz;
256266 // Scale the numerator as much as the denominator to maintain correctness of
257267 // the original equation
258268 FXBits<long accum> n_scaled{scaled_val_n};
Original file line number Diff line number Diff line change 1111#include " src/__support/fixed_point/fx_rep.h"
1212#include " test/UnitTest/Test.h"
1313
14- #include < stdio.h>
15-
1614template <typename XType> XType get_epsilon () = delete;
1715template <> fract get_epsilon () { return FRACT_EPSILON; }
1816template <> unsigned fract get_epsilon () { return UFRACT_EPSILON; }
@@ -61,6 +59,9 @@ class DivITest : public LIBC_NAMESPACE::testing::Test {
6159 EXPECT_LT (func (1 , INT_MAX) - 0 .r , epsilon);
6260 // This results in 1.1739, which should be saturated to FRACT_MAX
6361 EXPECT_EQ (func (27 , 23 ), FRACT_MAX);
62+
63+ EXPECT_EQ (func (INT_MIN, 1 ), FRACT_MIN);
64+ EXPECT_LT (func (1 , INT_MIN) - 0 .r , epsilon);
6465 }
6566};
6667
You can’t perform that action at this time.
0 commit comments