Skip to content

Commit

Permalink
Merge pull request #93 from konsumlamm/cmpW
Browse files Browse the repository at this point in the history
Integer: Optimize comparisons
  • Loading branch information
augustss authored Jan 17, 2025
2 parents 37a178d + cc577d2 commit 3bb170f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 23 deletions.
1 change: 1 addition & 0 deletions lib/Data/Integer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ instance Eq Integer where
(/=) = neI

instance Ord Integer where
compare = cmpI
(<) = ltI
(<=) = leI
(>) = gtI
Expand Down
60 changes: 37 additions & 23 deletions lib/Data/Integer/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Data.Integer.Internal(
Integer,
zeroI, oneI, negOneI,
eqI, neI, ltI, leI, gtI, geI,
eqI, neI, cmpI, ltI, leI, gtI, geI,
addI, subI, mulI, quotRemI,
negateI, absI,
andI, orI, xorI,
Expand Down Expand Up @@ -51,12 +51,12 @@ zeroD :: Digit
zeroD = 0

addI :: Integer -> Integer -> Integer
addI (I Plus xs) (I Plus ys) = I Plus (add xs ys)
addI (I Plus xs) (I Minus ys) | ltW xs ys = sI Minus (sub ys xs)
| True = sI Plus (sub xs ys)
addI (I Minus xs) (I Plus ys) | ltW ys xs = sI Minus (sub xs ys)
| True = sI Plus (sub ys xs)
addI (I Minus xs) (I Minus ys) = I Minus (add xs ys)
addI (I Plus xs) (I Plus ys) = I Plus (add xs ys)
addI (I Plus xs) (I Minus ys) | LT <- cmpW xs ys = sI Minus (sub ys xs)
| True = sI Plus (sub xs ys)
addI (I Minus xs) (I Plus ys) | LT <- cmpW ys xs = sI Minus (sub xs ys)
| True = sI Plus (sub ys xs)
addI (I Minus xs) (I Minus ys) = I Minus (add xs ys)

negateI :: Integer -> Integer
negateI i@(I _ []) = i
Expand Down Expand Up @@ -98,15 +98,14 @@ subW b x y =
let d = maxD + x - y - b
in (1 - quotMaxD d, remMaxD d)

-- Is axs < ays?
ltW :: [Digit] -> [Digit] -> Bool
ltW axs ays = lxs < lys || lxs == lys && cmp (reverse axs) (reverse ays)
where
lxs = length axs
lys = length ays
cmp (x:xs) (y:ys) = x < y || x == y && cmp xs ys
cmp [] [] = False
cmp _ _ = error "ltW.cmp"
cmpW :: [Digit] -> [Digit] -> Ordering
cmpW (x : xs) (y : ys) =
case cmpW xs ys of
EQ -> compare x y
res -> res
cmpW (_ : _) [] = GT
cmpW [] (_ : _) = LT
cmpW [] [] = EQ

mulI :: Integer -> Integer -> Integer
mulI (I _ []) _ = I Plus [] -- 0 * x = 0
Expand Down Expand Up @@ -226,20 +225,35 @@ eqI (I sx xs) (I sy ys) = sx == sy && xs == ys
neI :: Integer -> Integer -> Bool
neI x y = not (eqI x y)

cmpI :: Integer -> Integer -> Ordering
cmpI (I Plus xs) (I Plus ys) = cmpW xs ys
cmpI (I Minus _) (I Plus _) = LT
cmpI (I Plus _) (I Minus _) = GT
cmpI (I Minus xs) (I Minus ys) = cmpW ys xs

ltI :: Integer -> Integer -> Bool
ltI (I Plus xs) (I Plus ys) = ltW xs ys
ltI (I Minus _) (I Plus _) = True
ltI (I Plus _) (I Minus _) = False
ltI (I Minus xs) (I Minus ys) = ltW ys xs
ltI x y =
case cmpI x y of
LT -> True
_ -> False

leI :: Integer -> Integer -> Bool
leI x y = not (ltI y x)
leI x y =
case cmpI x y of
GT -> False
_ -> True

gtI :: Integer -> Integer -> Bool
gtI x y = ltI y x
gtI x y =
case cmpI x y of
GT -> True
_ -> False

geI :: Integer -> Integer -> Bool
geI x y = not (ltI x y)
geI x y =
case cmpI x y of
LT -> False
_ -> True

---------------------------------

Expand Down

0 comments on commit 3bb170f

Please sign in to comment.