fixed

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

commit 49327c1fc42a0c3e19656ef921169f139b3f13f0
parent 7938767108f3c2225e7f35470c53f08b12c44a6e
Author: Jared Tobin <jared@jtobin.io>
Date:   Sun,  2 Nov 2025 17:42:23 +0400

lib: gut existing test, bench suites

Diffstat:
Dbench/Criterion/Choice.hs | 19-------------------
Dbench/Criterion/Limb.hs | 27---------------------------
Dbench/Criterion/Wide.hs | 30------------------------------
Dbench/Main.hs | 164-------------------------------------------------------------------------------
Dbench/Weight.hs | 45---------------------------------------------
Mppad-fixed.cabal | 58+---------------------------------------------------------
Dtest/Main.hs | 242-------------------------------------------------------------------------------
Dtest/Wide.hs | 110-------------------------------------------------------------------------------
8 files changed, 1 insertion(+), 694 deletions(-)

diff --git a/bench/Criterion/Choice.hs b/bench/Criterion/Choice.hs @@ -1,19 +0,0 @@ -{-# LANGUAGE MagicHash #-} - -module Criterion.Choice ( - choice_utils - ) where - -import Criterion.Main -import qualified Data.Choice as C -import GHC.Exts - --- XX some of these are so fast that they're difficult to benchmark naively --- like this; performance is dominated by function call overhead and such. --- likely it would be better to benchmark them executed repeatedly in --- a loop - -choice_utils :: Benchmark -choice_utils = bgroup "choice utilities" [ - ] - diff --git a/bench/Criterion/Limb.hs b/bench/Criterion/Limb.hs @@ -1,27 +0,0 @@ -module Criterion.Limb ( - benches - ) where - -import Criterion.Main -import qualified Data.Word.Limb as Limb -import Prelude hiding (recip) - -benches :: Benchmark -benches = bgroup "limb arithmetic" [ - quot_big - , quot_small - , recip - ] - -quot_big :: Benchmark -quot_big = bench "wide quot (big)" $ - nf (Limb.quot 4294967294 32 4294967293) 32 - -quot_small :: Benchmark -quot_small = bench "wide quot (small)" $ - nf (Limb.quot 4294967294 32 2) 2 - -recip :: Benchmark -recip = bench "wide recip" $ - nf Limb.recip 18446744073709551606 - diff --git a/bench/Criterion/Wide.hs b/bench/Criterion/Wide.hs @@ -1,30 +0,0 @@ -module Criterion.Wide ( - benches - ) where - -import Criterion.Main -import qualified Data.Word.Wide as Wide -import Prelude hiding (recip) - -benches :: Benchmark -benches = bgroup "wide arithmetic" [ - quotrem_by1_bench - , shr_bench_small - , shr_bench_big - ] - -quotrem_by1_bench :: Benchmark -quotrem_by1_bench = bench "wide quotrem_by1" $ - nf (Wide.quotrem_by1 (Wide.wide 4294967294 32)) 18446744073709551606 - -_quotrem_by1_bench :: Benchmark -_quotrem_by1_bench = bench "wide _quotrem_by1" $ - nf (Wide._quotrem_by1 (Wide.wide 4294967294 32)) 18446744073709551606 - -shr_bench_small :: Benchmark -shr_bench_small = bench "wide shr (small)" $ - nf (Wide.shr (Wide.wide maxBound maxBound)) 1 - -shr_bench_big :: Benchmark -shr_bench_big = bench "wide shr (big)" $ - nf (Wide.shr (Wide.wide maxBound maxBound)) 127 diff --git a/bench/Main.hs b/bench/Main.hs @@ -1,164 +0,0 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} -{-# LANGUAGE BangPatterns #-} -{-# LANGUAGE NumericUnderscores #-} - -module Main where - -import Criterion.Main -import qualified Data.Bits as B -import qualified Data.Primitive.PrimArray as PA -import qualified Data.Word.Extended as W -import Data.Word (Word64) -import Prelude hiding (or, and, div, mod) -import qualified Prelude (div) -import qualified Criterion.Limb as Limb -import qualified Criterion.Wide as Wide - -add_sub :: Benchmark -add_sub = bgroup "addition & subtraction" [ - add - , add_baseline - , sub - , sub_baseline - ] - -multiplication :: Benchmark -multiplication = bgroup "multiplication" [ - mul - , mul_baseline - ] - -division :: Benchmark -division = bgroup "division" [ - div - , div_baseline - , mod - , mod_baseline - ] - -division_utils :: Benchmark -division_utils = bgroup "division utilities" [ - recip_2by1 - , quotrem_by1 - , rem_by1 - , quotrem_2by1 - , quot_r - , quotrem_r - ] - -main :: IO () -main = defaultMain [ - bgroup "extended" [ - add_sub - , multiplication - , division - , division_utils - ] - , Wide.benches - , Limb.benches - ] - --- addition and subtraction --------------------------------------------------- - -add_baseline :: Benchmark -add_baseline = bench "add (baseline)" $ nf ((+) w0) w1 where - w0, w1 :: Integer - !w0 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed - !w1 = 0x7fffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffed - -add :: Benchmark -add = bench "add" $ nf (W.add w0) w1 where - !w0 = W.to_word256 - 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed - !w1 = W.to_word256 - 0x7fffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffed - -sub_baseline :: Benchmark -sub_baseline = bench "sub (baseline)" $ nf ((-) w0) w1 where - w0, w1 :: Integer - !w0 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed - !w1 = 0x7fffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffed - -sub :: Benchmark -sub = bench "sub" $ nf (W.sub w0) w1 where - !w0 = W.to_word256 - 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed - !w1 = W.to_word256 - 0x7fffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffed - --- multiplication ------------------------------------------------------------- -mul_baseline :: Benchmark -mul_baseline = bench "mul (baseline)" $ nf ((*) w0) w1 where - w0, w1 :: Integer - !w0 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed - !w1 = 0x7fffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffed - -mul :: Benchmark -mul = bench "mul" $ nf (W.mul w0) w1 where - !w0 = W.to_word256 - 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed - !w1 = W.to_word256 - 0x7fffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffed - --- division ------------------------------------------------------------------- - -quotrem_r :: Benchmark -quotrem_r = bench "quotrem_r" $ - nf (W.quotrem_r 4 0xffffffffffffffff) (B.complement 4) - -quot_r :: Benchmark -quot_r = bench "quot_r" $ - nf (W.quot_r 4 0xffffffffffffffff) (B.complement 4) - -recip_2by1 :: Benchmark -recip_2by1 = bench "recip_2by1" $ - nf W.recip_2by1 0xFFFF_FFFF_FFFF_FF00 - -quotrem_2by1 :: Benchmark -quotrem_2by1 = bench "quotrem_2by1" $ - nf (W.quotrem_2by1 8 4 0xFFFF_FFFF_FFFF_FF00) r - where - !r = W.recip_2by1 0xFFFF_FFFF_FFFF_FF00 - -quotrem_by1 :: Benchmark -quotrem_by1 = env setup $ \ ~(q, u, d) -> - bench "quotrem_by1" $ - nfAppIO (W.quotrem_by1 q u) d - where - setup = do - qm <- PA.newPrimArray 2 - PA.setPrimArray qm 0 2 0 - let !u = PA.primArrayFromList [4, 8] - !d = B.complement 0xFF :: Word64 - pure (qm, u, d) - -rem_by1 :: Benchmark -rem_by1 = bench "rem_by1" $ - nf (W.rem_by1 (PA.primArrayFromList [4, 8])) (B.complement 0xFF :: Word64) - -div_baseline :: Benchmark -div_baseline = bench "div (baseline)" $ nf (Prelude.div w0) w1 where - w0, w1 :: Integer - !w0 = 0x41cf50c7d0d65afabcf5ba37750dba71c7db29ec9f20a216d3ef013a59b9188a - !w1 = 0x066bd4c3c10e30260cb6e7832af25f15527b089b258a1fef13b6eec3ce73bf06 - -div :: Benchmark -div = bench "div" $ nf (W.div w0) w1 where - !w0 = W.to_word256 - 0x41cf50c7d0d65afabcf5ba37750dba71c7db29ec9f20a216d3ef013a59b9188a - !w1 = W.to_word256 - 0x066bd4c3c10e30260cb6e7832af25f15527b089b258a1fef13b6eec3ce73bf06 - -mod_baseline :: Benchmark -mod_baseline = bench "mod (baseline)" $ nf (Prelude.rem w0) w1 where - w0, w1 :: Integer - !w0 = 0x41cf50c7d0d65afabcf5ba37750dba71c7db29ec9f20a216d3ef013a59b9188a - !w1 = 0x066bd4c3c10e30260cb6e7832af25f15527b089b258a1fef13b6eec3ce73bf06 - -mod :: Benchmark -mod = bench "mod" $ nf (W.mod w0) w1 where - !w0 = W.to_word256 - 0x41cf50c7d0d65afabcf5ba37750dba71c7db29ec9f20a216d3ef013a59b9188a - !w1 = W.to_word256 - 0x066bd4c3c10e30260cb6e7832af25f15527b089b258a1fef13b6eec3ce73bf06 - diff --git a/bench/Weight.hs b/bench/Weight.hs @@ -1,45 +0,0 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} -{-# LANGUAGE BangPatterns #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE PackageImports #-} - -module Main where - -import qualified Data.Bits as B -import qualified Data.Word.Extended as E -import qualified Weigh as W - -i0, i1 :: Integer -i0 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed -i1 = 0x7fffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffed - -w0, w1 :: E.Word256 -w0 = E.to_word256 i0 -w1 = E.to_word256 i1 - -i2, i3 :: Integer -i2 = 0x41cf50c7d0d65afabcf5ba37750dba71c7db29ec9f20a216d3ef013a59b9188a -i3 = 0x066bd4c3c10e30260cb6e7832af25f15527b089b258a1fef13b6eec3ce73bf06 - -w2, w3 :: E.Word256 -w2 = E.to_word256 i2 -w3 = E.to_word256 i3 - -main :: IO () -main = W.mainWith $ do - W.func "add (baseline)" ((+) i0) i1 - W.func "add" (E.add w0) w1 - W.func "sub (baseline)" ((-) i0) i1 - W.func "sub" (E.sub w0) w1 - W.func "mul (baseline)" ((*) i0) i1 - W.func "mul" (E.mul w0) w1 - W.func "quotrem_r" (E.quotrem_r 4 0xffffffffffffffff) (B.complement 4) - W.func "quotrem_2by1" (E.quotrem_2by1 8 4 0xffffffffffffffff) r - W.func "div (baseline)" (Prelude.div i2) i3 - W.func "div" (E.div w2) w3 - W.func "mod (baseline)" (Prelude.mod i2) i3 - W.func "mod" (E.mod w2) w3 - where - !r = E.recip_2by1 0xFFFF_FFFF_FFFF_FF00 - diff --git a/ppad-fixed.cabal b/ppad-fixed.cabal @@ -23,66 +23,10 @@ library ghc-options: -Wall exposed-modules: - Data.Choice - , Data.Word.Extended - , Data.Word.Limb - , Data.Word.Wide - , Data.Word.Wider + Data.Word.Limb , Data.Word.Montgomery build-depends: base >= 4.9 && < 5 , deepseq >= 1.5 && < 1.6 , primitive >= 0.8 && < 0.10 -test-suite fixed-tests - type: exitcode-stdio-1.0 - default-language: Haskell2010 - hs-source-dirs: test - main-is: Main.hs - - ghc-options: - -rtsopts -Wall -O2 - - build-depends: - base - , bytestring - , ppad-fixed - , primitive - , tasty - , tasty-hunit - , tasty-quickcheck - -benchmark fixed-bench - type: exitcode-stdio-1.0 - default-language: Haskell2010 - hs-source-dirs: bench - main-is: Main.hs - other-modules: - Criterion.Choice - , Criterion.Limb - , Criterion.Wide - - ghc-options: - -rtsopts -O2 -Wall - - build-depends: - base - , criterion - , ppad-fixed - , primitive - -benchmark fixed-weigh - type: exitcode-stdio-1.0 - default-language: Haskell2010 - hs-source-dirs: bench - main-is: Weight.hs - - ghc-options: - -rtsopts -O2 -Wall - - build-depends: - base - , ppad-fixed - , primitive - , weigh - diff --git a/test/Main.hs b/test/Main.hs @@ -1,242 +0,0 @@ - {-# OPTIONS_GHC -fno-warn-unused-imports #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} -{-# LANGUAGE BangPatterns #-} -{-# LANGUAGE MagicHash #-} -{-# LANGUAGE UnboxedTuples #-} - -module Main where - -import Data.Bits ((.|.), (.&.), (.>>.), (.<<.), (.^.)) -import qualified Data.Bits as B -import qualified Data.Primitive.PrimArray as PA -import Data.Word.Extended -import GHC.Exts -import GHC.Word -import Prelude hiding (and, or, div, mod) -import qualified Prelude (div, rem) -import Test.Tasty -import qualified Test.Tasty.HUnit as H -import qualified Test.Tasty.QuickCheck as Q -import qualified Wide as W - -fi :: (Integral a, Num b) => a -> b -fi = fromIntegral -{-# INLINE fi #-} - -to_word512 - :: Integer - -> (# Word64#, Word64#, Word64#, Word64#, Word64#, Word64#, Word64#, Word64# #) -to_word512 n = - let !mask64 = 2 ^ (64 :: Int) - 1 - !(W64# w0) = fi (n .&. mask64) - !(W64# w1) = fi ((n .>>. 64) .&. mask64) - !(W64# w2) = fi ((n .>>. 128) .&. mask64) - !(W64# w3) = fi ((n .>>. 192) .&. mask64) - !(W64# w4) = fi ((n .>>. 256) .&. mask64) - !(W64# w5) = fi ((n .>>. 320) .&. mask64) - !(W64# w6) = fi ((n .>>. 384) .&. mask64) - !(W64# w7) = fi ((n .>>. 448) .&. mask64) - in (# w0, w1, w2, w3, w4, w5, w6, w7 #) - -word512_to_integer - :: (# Word64#, Word64#, Word64#, Word64#, Word64#, Word64#, Word64#, Word64# #) - -> Integer -word512_to_integer (# w0, w1, w2, w3, w4, w5, w6, w7 #) = - fi (W64# w7) .<<. 448 - .|. fi (W64# w6) .<<. 384 - .|. fi (W64# w5) .<<. 320 - .|. fi (W64# w4) .<<. 256 - .|. fi (W64# w3) .<<. 192 - .|. fi (W64# w2) .<<. 128 - .|. fi (W64# w1) .<<. 64 - .|. fi (W64# w0) - -instance Q.Arbitrary Word256 where - arbitrary = do - w0 <- Q.arbitrary - w1 <- Q.arbitrary - w2 <- Q.arbitrary - w3 <- Q.arbitrary - pure (Word256 w0 w1 w2 w3) - -newtype Monotonic = Monotonic (Integer, Integer) - deriving Show - -instance Q.Arbitrary Monotonic where - arbitrary = do - a <- Q.chooseInteger (0, 2 ^ (256 :: Int) - 1) - b <- (Q.chooseInteger (0, 2 ^ (256 :: Int) - 1)) - `Q.suchThat` (\b -> b <= a) - pure (Monotonic (a, b)) - -newtype DivMonotonic = DivMonotonic (Integer, Integer) - deriving Show - -instance Q.Arbitrary DivMonotonic where - arbitrary = do - a <- Q.chooseInteger (1, 2 ^ (256 :: Int) - 1) - b <- (Q.chooseInteger (1, 2 ^ (256 :: Int) - 1)) - `Q.suchThat` (\b -> b <= a) - pure (DivMonotonic (a, b)) - --- addition / subtraction ---------------- - -add_matches :: Q.NonNegative Integer -> Q.NonNegative Integer -> Bool -add_matches (Q.NonNegative a) (Q.NonNegative b) = - to_integer (to_word256 a `add` to_word256 b) == a + b - -sub_matches :: Monotonic -> Bool -sub_matches (Monotonic (a, b)) = - to_integer (to_word256 a `sub` to_word256 b) == a - b - --- multiplication ------------------------ - -mul_c_matches :: Word64 -> Word64 -> Bool -mul_c_matches a@(W64# a_ubox) b@(W64# b_ubox) = - let c = fi a * fi b :: Integer - c_hi = fi (c .>>. 64) :: Word64 - c_lo = fi (c .&. 0xffffffffffffffff) :: Word64 - - !(# hi, lo #) = mul_c# a_ubox b_ubox - in (W64# hi) == c_hi && (W64# lo) == c_lo - --- (hi * 2 ^ 64 + lo) = z + (x * y) -umul_hop_predicate_holds :: Word64 -> Word64 -> Word64 -> Bool -umul_hop_predicate_holds z@(W64# z_ubox) x@(W64# x_ubox) y@(W64# y_ubox) = - let !(# hi, lo #) = umul_hop# z_ubox x_ubox y_ubox - in fi (W64# hi) * 2 ^ (64 :: Int) + fi (W64# lo) - == (fi z + (fi x * fi y) :: Integer) - --- (hi * 2 ^ 64 + lo) = z + (x * y) + c -umul_step_predicate_holds :: Word64 -> Word64 -> Word64 -> Word64 -> Bool -umul_step_predicate_holds - z@(W64# z_ubox) x@(W64# x_ubox) y@(W64# y_ubox) c@(W64# c_ubox) = - let !(# hi, lo #) = umul_step# z_ubox x_ubox y_ubox c_ubox - !left = fi (W64# hi) * 2 ^ (64 :: Int) + fi (W64# lo) :: Integer - !rite = fi z + (fi x * fi y) + fi c :: Integer - in left == rite - -mul_lo_matches :: Q.NonNegative Integer -> Q.NonNegative Integer -> Bool -mul_lo_matches (Q.NonNegative a) (Q.NonNegative b) = - let !mask128 = 0xffffffffffffffffffffffffffffffff - !a_lo = a .&. mask128 - !b_lo = b .&. mask128 - - in to_word256 a_lo `mul` to_word256 b_lo == to_word256 (a_lo * b_lo) - -mul_512_matches :: Q.NonNegative Integer -> Q.NonNegative Integer -> Bool -mul_512_matches (Q.NonNegative a) (Q.NonNegative b) = - let !(Word256 (W64# a0) (W64# a1) (W64# a2) (W64# a3)) = to_word256 a - !(Word256 (W64# b0) (W64# b1) (W64# b2) (W64# b3)) = to_word256 b - !left = word512_to_integer $ - (# a0, a1, a2, a3 #) `mul_512#` (# b0, b1, b2, b3 #) - !rite = a * b - in left == rite - --- division ------------------------------ - -div_matches :: DivMonotonic -> Bool -div_matches (DivMonotonic (a, b)) = - let !left = to_word256 a `div` to_word256 b - !rite = to_word256 (a `Prelude.div` b) - in left == rite - -mod_matches :: DivMonotonic -> Bool -mod_matches (DivMonotonic (a, b)) = - let !left = to_word256 a `mod` to_word256 b - !rite = to_word256 (a `Prelude.rem` b) - in left == rite - -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) - -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) - -quotrem_r_case2 :: H.Assertion -quotrem_r_case2 = do - let !(P q r) = quotrem_r 4 0xffffffffffffffff (B.complement 4) - H.assertEqual mempty (P 5 24) (P q r) - -recip_2by1_case0 :: H.Assertion -recip_2by1_case0 = do - let !q = recip_2by1 (B.complement 4) - H.assertEqual mempty 5 q - -recip_2by1_case1 :: H.Assertion -recip_2by1_case1 = do - let !q = recip_2by1 (B.complement 0xff) - H.assertEqual mempty 256 q - -quotrem_2by1_case0 :: H.Assertion -quotrem_2by1_case0 = do - let !d = B.complement 0xFF :: Word64 - !o = quotrem_2by1 8 4 d (recip_2by1 d) - H.assertEqual mempty (P 8 2052) o - -quotrem_by1_case0 :: H.Assertion -quotrem_by1_case0 = do - qm <- PA.newPrimArray 2 - PA.setPrimArray qm 0 2 0 - let !u = PA.primArrayFromList [4, 8] - !d = B.complement 0xFF :: Word64 - r <- quotrem_by1 qm u d - q <- PA.unsafeFreezePrimArray qm - H.assertEqual "quotient" (PA.primArrayFromList [8, 0]) q - H.assertEqual "remainder" 2052 r - --- tests ---------------------------------------------------------------------- - -add_sub :: TestTree -add_sub = testGroup "addition & subtraction" [ - Q.testProperty "addition matches (nonneg)" $ - Q.withMaxSuccess 1000 add_matches - , Q.testProperty "subtraction matches (nonneg, monotonic)" $ - Q.withMaxSuccess 1000 sub_matches - ] - -multiplication :: TestTree -multiplication = testGroup "arithmetic" [ - Q.testProperty "mul_c matches integer multiplication" $ - Q.withMaxSuccess 1000 mul_c_matches - , Q.testProperty "umul_hop: (hi * 2 ^ 64 + lo) = z + (x * y)" $ - Q.withMaxSuccess 1000 umul_hop_predicate_holds - , Q.testProperty "umul_step: (hi * 2 ^ 64 + lo) = z + (x * y) + c" $ - Q.withMaxSuccess 1000 umul_step_predicate_holds - , Q.testProperty "mul matches (nonneg, low bits)" $ - Q.withMaxSuccess 1000 mul_lo_matches - , Q.testProperty "mul_512# matches" $ - Q.withMaxSuccess 1000 mul_512_matches - ] - -division :: TestTree -division = testGroup "division" [ - Q.testProperty "division matches" $ - Q.withMaxSuccess 1000 div_matches - , Q.testProperty "mod matches" $ - Q.withMaxSuccess 1000 mod_matches - ] - -main :: IO () -main = defaultMain $ testGroup "ppad-fixed" [ - testGroup "property tests" [ - add_sub - , multiplication - , division - ] - , testGroup "unit tests" [ - H.testCase "quotrem_r matches case0" quotrem_r_case0 - , H.testCase "quotrem_r matches case1" quotrem_r_case1 - , H.testCase "quotrem_r matches case2" quotrem_r_case2 - , H.testCase "recip_2by1 matches case0" recip_2by1_case0 - , H.testCase "recip_2by1 matches case1" recip_2by1_case1 - , H.testCase "quotrem_2by1 matches case0" quotrem_2by1_case0 - , H.testCase "quotrem_by1 matches case0" quotrem_by1_case0 - ] - , W.tests - ] - diff --git a/test/Wide.hs b/test/Wide.hs @@ -1,110 +0,0 @@ -module Wide ( - tests - ) where - -import qualified Data.Word.Wide as W -import Prelude hiding (div, recip) -import Test.Tasty -import qualified Test.Tasty.HUnit as H - -tests = testGroup "wide unit tests" [] --- tests :: TestTree --- tests = testGroup "wide unit tests" [ --- H.testCase "mul_c, case 0" mul_c_case0 --- , H.testCase "div1by1, case 0" div1by1_case0 --- , H.testCase "div1by1, case 1" div1by1_case1 --- , H.testCase "recip, case 0" recip_case0 --- , H.testCase "recip, case 1" recip_case1 --- , H.testCase "recip, case 2" recip_case2 --- , H.testCase "div2by1, case 0" div2by1_case0 --- , H.testCase "div2by1, case 1" div2by1_case1 --- , H.testCase "div2by1, case 2" div2by1_case2 --- , H.testCase "div2by1, case 3 (GHC.Exts reference)" div2by1_case3 --- , H.testCase "div2by1, case 4 (GHC.Exts reference)" div2by1_case4 --- , H.testCase "div2by1, case 5 (GHC.Exts reference)" div2by1_case5 --- ] --- --- mul_c_case0 :: H.Assertion --- mul_c_case0 = do --- let a = 4294967294 --- b = 2 --- H.assertEqual "matches" (W.wide 8589934588 0) (W.mul_c a b) --- --- div1by1_case0 :: H.Assertion --- div1by1_case0 = do --- let dnd = 4294967294 --- dnb = 32 --- div = 4294967293 --- dib = 32 --- v0 = W.div1by1 dnd dnb div dib --- H.assertEqual "matches" 1 v0 --- --- div1by1_case1 :: H.Assertion --- div1by1_case1 = do --- let dnd = 4294967294 --- dnb = 32 --- div = 2 --- dib = 2 --- v0 = W.div1by1 dnd dnb div dib --- H.assertEqual "matches" 2147483647 v0 --- --- recip_case0 :: H.Assertion --- recip_case0 = do --- let d = 18446744073709551606 --- e = W.recip d --- H.assertEqual "matches" 10 e --- --- recip_case1 :: H.Assertion --- recip_case1 = do --- let d = 0x8000000000000000 -- 2^63 --- e = W.recip d --- H.assertEqual "matches" 0xffffffffffffffff e --- --- recip_case2 :: H.Assertion --- recip_case2 = do --- let d = 0x8000000000000001 -- 2^63 + 1 --- e = W.recip d --- H.assertEqual "matches" 0xfffffffffffffffc e --- --- div2by1_case0 :: H.Assertion --- div2by1_case0 = do --- let d = maxBound - 1 --- r = W.div2by1 (W.wide (maxBound - 63) (maxBound - 2)) d --- e = (maxBound, maxBound - 65) --- H.assertEqual "matches" e r --- --- div2by1_case1 :: H.Assertion --- div2by1_case1 = do --- let d = 0x8000000000000000 -- 2^63 --- r = W.div2by1 (W.wide 0xffffffffffffffff 0x7fffffffffffffff) d --- e = (0xffffffffffffffff, 0x7fffffffffffffff) --- H.assertEqual "matches" e r --- --- div2by1_case2 :: H.Assertion --- div2by1_case2 = do --- let d = 0x8000000000000001 -- 2^63 + 1 --- r = W.div2by1 (W.wide 0x0000000000000000 0x8000000000000000) d --- e = (0xfffffffffffffffe, 0x2) --- H.assertEqual "matches" e r --- --- div2by1_case3 :: H.Assertion --- div2by1_case3 = do --- let d = maxBound - 1 --- r = W.div2by1 (W.wide (maxBound - 63) (maxBound - 2)) d --- e = W.quotrem2by1 (W.wide (maxBound - 63) (maxBound - 2)) d --- H.assertEqual "matches" e r --- --- div2by1_case4 :: H.Assertion --- div2by1_case4 = do --- let d = 0x8000000000000000 -- 2^63 --- r = W.div2by1 (W.wide 0xffffffffffffffff 0x7fffffffffffffff) d --- e = W.quotrem2by1 (W.wide 0xffffffffffffffff 0x7fffffffffffffff) d --- H.assertEqual "matches" e r --- --- div2by1_case5 :: H.Assertion --- div2by1_case5 = do --- let d = 0x8000000000000001 -- 2^63 + 1 --- r = W.div2by1 (W.wide 0x0000000000000000 0x8000000000000000) d --- e = W.quotrem2by1 (W.wide 0x0000000000000000 0x8000000000000000) d --- H.assertEqual "matches" e r ---