fixed

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

commit 9323a83a33ecaeba20eb2b578df1259e8b972353
parent 680a0698c60fe87b21c0d65c20751c2f4b044aed
Author: Jared Tobin <jared@jtobin.io>
Date:   Fri, 24 Jan 2025 11:34:06 +0400

lib: generalize divisors

Diffstat:
Mlib/Data/Word/Extended.hs | 39++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/lib/Data/Word/Extended.hs b/lib/Data/Word/Extended.hs @@ -97,6 +97,11 @@ data Word640 = Word640 {-# UNPACK #-} !Word64 deriving (Eq, Show, Generic) +data Word832 = Word832 + {-# UNPACK #-} !Word576 + {-# UNPACK #-} !Word256 + deriving (Eq, Show, Generic) + data Word1152 = Word1152 -- yikes {-# UNPACK #-} !Word576 {-# UNPACK #-} !Word576 @@ -352,7 +357,7 @@ sub_mul_to x x_offset y m = do sub_mul :: Word576 -- dividend -> Int -- min dividend index - -> Word256 -- divisor + -> Word576 -- divisor -> Int -- max divisor index -> Word64 -- multiplier -> Word640 -- result, borrow @@ -361,7 +366,7 @@ sub_mul u u_start d d_len m = loop 0 u 0 where | j == d_len = Word640 acc borrow | otherwise = let !u_j = sel576 acc (u_start + j) - !d_j = sel256 d j + !d_j = sel576 d j !(P s carry1) = sub_b u_j borrow 0 !(P ph pl) = mul_c d_j m !(P t carry2) = sub_b s pl 0 @@ -391,7 +396,7 @@ add_to x x_offset y = do add_big :: Word576 -> Int - -> Word256 + -> Word576 -> Int -> Word640 add_big u u_start d d_len = loop 0 u 0 where @@ -399,7 +404,7 @@ add_big u u_start d d_len = loop 0 u 0 where | j == d_len = Word640 acc car | otherwise = let !u_j = sel576 acc (u_start + j) - !d_j = sel256 d j + !d_j = sel576 d j !(P w64 ncar) = add_c u_j d_j car !nacc = set576 acc (u_start + j) w64 in loop (succ j) nacc ncar @@ -511,12 +516,12 @@ quotrem_by1_gen u ulen d = quotrem_knuth_gen :: Word576 -> Int - -> Word256 + -> Word576 -> Int -> Word1152 quotrem_knuth_gen u ulen d dlen = loop (ulen - dlen - 1) zero576 u where - !d_hi = sel256 d (dlen - 1) - !d_lo = sel256 d (dlen - 2) + !d_hi = sel576 d (dlen - 1) + !d_lo = sel576 d (dlen - 2) !rec = recip_2by1 d_hi loop j !qacc !uacc | j < 0 = Word1152 qacc uacc @@ -660,6 +665,26 @@ quotrem_knuth quo u d = do -- !nacc = set acc j val -- in munge (pred j) ref nacc s + + +-- quotrem_gen +-- :: Word576 +-- -> Int +-- -> Word256 -- needs to be more general +-- -> Int +-- -> Word832 +-- quotrem_gen u ulen d@(Word256 d0 _ _ d3) dlen = +-- let !dlen = len_set_words d +-- !shift = B.countLeadingZeros d3 +-- !ulen = len_set_words u +-- where +-- len_set_words (Word256 z0 z1 z2 z3) +-- | z3 /= 0 = 4 +-- | z2 /= 0 = 3 +-- | z1 /= 0 = 2 +-- | z0 /= 0 = 1 +-- | otherwise = error "ppad-fixed (quotrem_256): division by zero" + -- XX primarray; dynamic size requirements quotrem :: PrimMonad m