fixed

Pure Haskell large fixed-width integers.
git clone git://git.ppad.tech/fixed.git
Log | Files | Refs | README | LICENSE

commit 2af589212f68432f3a80fb20f615a04e9415489d
parent ebede50c1cb0d7f69338f4cc0a6adcc8638b2f1c
Author: Jared Tobin <jared@jtobin.io>
Date:   Wed, 22 Jan 2025 17:01:24 +0400

lib: quotrem_by1

Diffstat:
Mlib/Data/Word/Extended.hs | 19++++++++++++++-----
Mtest/Main.hs | 16++++++++--------
2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/lib/Data/Word/Extended.hs b/lib/Data/Word/Extended.hs @@ -244,8 +244,8 @@ sub_mul (Word256 x0 x1 x2 x3) (Word256 y0 y1 y2 y3) m = -- quotient, remainder of (hi, lo) divided by y -- translated from Div64 in go's math/bits package -quot_rem_r :: Word64 -> Word64 -> Word64 -> W64Pair -quot_rem_r hi lo y_0 +quotrem_r :: Word64 -> Word64 -> Word64 -> W64Pair +quotrem_r hi lo y_0 | y_0 == 0 = error "ppad-fixed: division by zero" | y_0 <= hi = error "ppad-fixed: overflow" | hi == 0 = P (lo `quot` y_0) (lo `rem` y_0) @@ -289,10 +289,10 @@ quot_rem_r hi lo y_0 recip_2by1 :: Word64 -> Word64 recip_2by1 d = r where - !(P r _) = quot_rem_r (B.complement d) 0xffffffffffffffff d + !(P r _) = quotrem_r (B.complement d) 0xffffffffffffffff d -quot_rem_2by1 :: Word64 -> Word64 -> Word64 -> Word64 -> W64Pair -quot_rem_2by1 uh ul d rec = +quotrem_2by1 :: Word64 -> Word64 -> Word64 -> Word64 -> W64Pair +quotrem_2by1 uh ul d rec = let !(P qh_0 ql) = mul_c rec uh !(P ql_0 c) = add_c ql ul 0 !(P (succ -> qh_1) _) = add_c qh_0 uh c @@ -305,3 +305,12 @@ quot_rem_2by1 uh ul d rec = then P (qh_y + 1) (r_y - d) else P qh_y r_y +quotrem_by1 :: Word256 -> Word64 -> Word256WithOverflow +quotrem_by1 (Word256 u0 u1 u2 u3) d = + let !rec = recip_2by1 d + !r0 = u3 + !(P q2 r1) = quotrem_2by1 r0 u2 d rec + !(P q1 r2) = quotrem_2by1 r1 u1 d rec + !(P q0 r3) = quotrem_2by1 r2 u0 d rec + in Word256WithOverflow (Word256 q0 q1 q2 0) r3 + diff --git a/test/Main.hs b/test/Main.hs @@ -105,14 +105,14 @@ mul_512_matches (Q.NonNegative a) (Q.NonNegative b) = -- assertions ------------------------------------------------------------------ -quot_rem_r_case0 :: H.Assertion -quot_rem_r_case0 = do - let !(P q r) = quot_rem_r 2 4 4 +quotrem_r_case0 :: H.Assertion +quotrem_r_case0 = do + let !(P q r) = quotrem_r 2 4 4 H.assertEqual mempty (P 9223372036854775809 0) (P q r) -quot_rem_r_case1 :: H.Assertion -quot_rem_r_case1 = do - let !(P q r) = quot_rem_r 0 4 2 +quotrem_r_case1 :: H.Assertion +quotrem_r_case1 = do + let !(P q r) = quotrem_r 0 4 2 H.assertEqual mempty (P 2 0) (P q r) recip_2by1_case0 :: H.Assertion @@ -166,8 +166,8 @@ main = defaultMain $ , arithmetic ] , testGroup "unit tests" [ - H.testCase "quot_rem_r matches case0" quot_rem_r_case0 - , H.testCase "quot_rem_r matches case1" quot_rem_r_case1 + H.testCase "quotrem_r matches case0" quotrem_r_case0 + , H.testCase "quotrem_r matches case1" quotrem_r_case1 , H.testCase "recip_2by1 matches case0" recip_2by1_case0 , H.testCase "recip_2by1 matches case1" recip_2by1_case1 ]