fixed

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

commit 085c244b34572417f3216a775e443cafbc20026d
parent 1517cd938c0447460d32872e75ab798d2d5d245b
Author: Jared Tobin <jared@jtobin.io>
Date:   Sun, 23 Nov 2025 20:06:51 +0400

lib: mul for wider and basic Num instance

Diffstat:
Mlib/Data/Word/Wider.hs | 107+++++++++++++++++++++++++++++++++++++++++++------------------------------------
1 file changed, 58 insertions(+), 49 deletions(-)

diff --git a/lib/Data/Word/Wider.hs b/lib/Data/Word/Wider.hs @@ -40,6 +40,14 @@ instance Show Wider where instance NFData Wider where rnf (Wider a) = case a of (# _, _, _, _ #) -> () +instance Num Wider where + (+) = add + (-) = sub + (*) = mul + abs = id + fromInteger = to + negate = to . negate . from + signum = to . signum . from -- construction / conversion -------------------------------------------------- -- | Construct a 'Wider' word from four 'Words', provided in @@ -120,6 +128,14 @@ add_w# a b = in c {-# INLINE add_w# #-} +-- | Wrapping addition, computing 'a + b'. +add + :: Wider + -> Wider + -> Wider +add (Wider a) (Wider b) = Wider (add_w# a b) +{-# INLINE add #-} + -- | Modular addition. add_mod# :: (# Word#, Word#, Word#, Word# #) -- ^ augend @@ -145,6 +161,14 @@ sub_b# (# a0, a1, a2, a3 #) (# b0, b1, b2, b3 #) = in (# (# s0, s1, s2, s3 #), c3 #) {-# INLINE sub_b# #-} +sub + :: Wider + -> Wider + -> Wider +sub (Wider a) (Wider b) = + let !(# d, _ #) = sub_b# a b + in Wider d + -- | Modular subtraction. Computes a - b mod m. sub_mod# :: (# Word#, Word#, Word#, Word# #) -- ^ minuend @@ -174,63 +198,47 @@ sub_mod_c# a c b (# p0, p1, p2, p3 #) = -- multiplication ------------------------------------------------------------- --- returning (# hi, lo #) -umul_hop# :: Word# -> Word# -> Word# -> (# Word#, Word# #) -umul_hop# z x y = - let !(# lo_0, hi_0 #) = L.mul_c# x y - !(# lo, c #) = L.add_c# lo_0 z 0## - !(# hi, _ #) = L.add_c# hi_0 0## c - in (# hi, lo #) -{-# INLINE umul_hop# #-} - --- returning (# hi, lo #) -umul_step# - :: Word# - -> Word# - -> Word# - -> Word# - -> (# Word#, Word# #) -umul_step# z x y c = - let !(# lo_0, hi_0 #) = L.mul_c# x y - !(# lo_1, c_0 #) = L.add_c# lo_0 c 0## - !(# hi_1, _ #) = L.add_c# hi_0 0## c_0 - !(# lo, c_1 #) = L.add_c# lo_1 z 0## - !(# hi, _ #) = L.add_c# hi_1 0## c_1 - in (# hi, lo #) -{-# INLINE umul_step# #-} - -- widening multiplication mul_c# :: (# Word#, Word#, Word#, Word# #) -> (# Word#, Word#, Word#, Word# #) -> (# (# Word#, Word#, Word#, Word# #), (# Word#, Word#, Word#, Word# #) #) mul_c# (# x0, x1, x2, x3 #) (# y0, y1, y2, y3 #) = - let !(# r0, c4_0 #) = L.mul_c# x0 y0 - !(# c4_1, r0_1 #) = umul_hop# c4_0 x1 y0 - !(# c4_2, r0_2 #) = umul_hop# c4_1 x2 y0 - !(# c4, r0_3 #) = umul_hop# c4_2 x3 y0 - - !(# c5_0, r1 #) = umul_hop# r0_1 x0 y1 - !(# c5_1, r1_2 #) = umul_step# r0_2 x1 y1 c5_0 - !(# c5_2, r1_3 #) = umul_step# r0_3 x2 y1 c5_1 - !(# c5, r1_4 #) = umul_step# c4 x3 y1 c5_2 - - !(# c6_0, r2 #) = umul_hop# r1_2 x0 y2 - !(# c6_1, r2_3 #) = umul_step# r1_3 x1 y2 c6_0 - !(# c6_2, r2_4 #) = umul_step# r1_4 x2 y2 c6_1 - !(# c6, r2_5 #) = umul_step# c5 x3 y2 c6_2 - - !(# c7_0, r3 #) = umul_hop# r2_3 x0 y3 - !(# c7_1, r4 #) = umul_step# r2_4 x1 y3 c7_0 - !(# c7_2, r5 #) = umul_step# r2_5 x2 y3 c7_1 - !(# r7, r6 #) = umul_step# c6 x3 y3 c7_2 - in (# (# r0, r1, r2, r3 #), (# r4, r5, r6, r7 #) #) + let !(# z0, c0_0 #) = L.mac# x0 y0 0## 0## + !(# s1_0, c1_0 #) = L.mac# x0 y1 0## c0_0 + !(# z1, c1_1 #) = L.mac# x1 y0 s1_0 0## + !(# s2_0, c2_0 #) = L.mac# x0 y2 0## c1_0 + !(# s2_1, c2_1 #) = L.mac# x1 y1 s2_0 c1_1 + !(# z2, c2_2 #) = L.mac# x2 y0 s2_1 0## + !(# s3_0, c3_0 #) = L.mac# x0 y3 0## c2_0 + !(# s3_1, c3_1 #) = L.mac# x1 y2 s3_0 c2_1 + !(# s3_2, c3_2 #) = L.mac# x2 y1 s3_1 c2_2 + !(# z3, c3_3 #) = L.mac# x3 y0 s3_2 0## + !(# s4_0, c4_0 #) = L.mac# x1 y3 0## c3_0 + !(# s4_1, c4_1 #) = L.mac# x2 y2 s4_0 c3_1 + !(# s4_2, c4_2 #) = L.mac# x3 y1 s4_1 c3_2 + !(# w4, c4_3 #) = L.add_c# s4_2 c3_3 0## + !(# s5_0, c5_0 #) = L.mac# x2 y3 0## c4_0 + !(# s5_1, c5_1 #) = L.mac# x3 y2 s5_0 c4_1 + !(# w5, c5_2 #) = L.add_c# s5_1 c4_2 0## + !(# w5f, c5_3 #) = L.add_c# w5 c4_3 0## + !(# s6_0, c6_0 #) = L.mac# x3 y3 0## c5_0 + !(# w6, c6_1 #) = L.add_c# s6_0 c5_1 0## + !(# w6f, c6_2 #) = L.add_c# w6 c5_2 0## + !(# w6ff, c6_3 #) = L.add_c# w6f c5_3 0## + !(# w7, _ #) = L.add_c# c6_0 c6_1 0## + !(# w7f, _ #) = L.add_c# w7 c6_2 0## + !(# w7ff, _ #) = L.add_c# w7f c6_3 0## + in (# (# z0, z1, z2, z3 #), (# w4, w5f, w6ff, w7ff #) #) {-# INLINE mul_c# #-} -mul_c :: Wider -> Wider -> (Wider, Wider) -mul_c (Wider a) (Wider b) = - let !(# lo, hi #) = mul_c# a b - in (Wider lo, Wider hi) +mul + :: Wider + -> Wider + -> Wider +mul (Wider a) (Wider b) = + let !(# l, _ #) = mul_c# a b + in Wider l sqr# :: (# Word#, Word#, Word#, Word# #) @@ -274,3 +282,4 @@ sqr :: Wider -> (Wider, Wider) sqr (Wider w) = let !(# l, h #) = sqr# w in (Wider l, Wider h) +