fixed

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

commit 202de6475c823c0fea357f39546ee1510825dd20
parent 9bbd83c5cb7e70d86876bc5e00fd5bf0e8b5ab6f
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 29 Nov 2025 08:48:36 +0400

lib: ord for wider

Diffstat:
Mlib/Data/Choice.hs | 6++++++
Mlib/Data/Word/Wider.hs | 41+++++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/lib/Data/Choice.hs b/lib/Data/Choice.hs @@ -10,6 +10,7 @@ module Data.Choice ( , true# , false# , decide + , to_word# -- * MaybeWord# , MaybeWord#(..) @@ -128,10 +129,15 @@ true# _ = case maxBound :: Word of W# w -> Choice w {-# INLINE true# #-} +-- XX this is probably stupid. check decide :: Choice -> Bool decide (Choice c) = isTrue# (neWord# c 0##) {-# INLINE decide #-} +to_word# :: Choice -> Word# +to_word# (Choice c) = and# c 1## +{-# INLINE to_word# #-} + -- constant time 'Maybe Word#' newtype MaybeWord# = MaybeWord# (# Word#, Choice #) diff --git a/lib/Data/Word/Wider.hs b/lib/Data/Word/Wider.hs @@ -35,6 +35,12 @@ data Wider = Wider !(# Word#, Word#, Word#, Word# #) instance Eq Wider where Wider a == Wider b = C.decide (C.ct_eq_wider# a b) +instance Ord Wider where + compare (Wider a) (Wider b) = case cmp# a b of + 1# -> GT + 0# -> EQ + _ -> LT + instance Show Wider where show (Wider (# a, b, c, d #)) = "(" <> show (W# a) <> ", " <> show (W# b) <> ", " @@ -55,6 +61,41 @@ instance Num Wider where | a == Wider (# 0##, 0##, 0##, 0## #) = 0 | otherwise = 1 +-- ordering ------------------------------------------------------------------- + +lt# + :: (# Word#, Word#, Word#, Word# #) + -> (# Word#, Word#, Word#, Word# #) + -> C.Choice +lt# a b = + let !(# _, bit #) = sub_b# a b + in C.from_word_lsb# bit + +gt# + :: (# Word#, Word#, Word#, Word# #) + -> (# Word#, Word#, Word#, Word# #) + -> C.Choice +gt# a b = + let !(# _, bit #) = sub_b# b a + in C.from_word_lsb# bit + +cmp# + :: (# Word#, Word#, Word#, Word# #) + -> (# Word#, Word#, Word#, Word# #) + -> Int# +cmp# (# l0, l1, l2, l3 #) (# r0, r1, r2, r3 #) = + let !(# w0, b0 #) = L.sub_b# r0 l0 0## + !d0 = or# 0## w0 + !(# w1, b1 #) = L.sub_b# r1 l1 b0 + !d1 = or# d0 w1 + !(# w2, b2 #) = L.sub_b# r2 l2 b1 + !d2 = or# d1 w2 + !(# w3, b3 #) = L.sub_b# r3 l3 b2 + !d3 = or# d2 w3 + !s = (word2Int# (uncheckedShiftL# b3 1#)) -# 1# + in (word2Int# (C.to_word# (C.from_word_nonzero# d3))) *# s +{-# INLINE cmp# #-} + -- construction / conversion -------------------------------------------------- -- | Construct a 'Wider' word from four 'Words', provided in