Add additional support for GCD on signed numbers.

This commit is contained in:
2018-12-30 17:13:01 -08:00
parent 14fd156d3c
commit a6a82773d3
3 changed files with 85 additions and 16 deletions

View File

@@ -1,6 +1,6 @@
{-# LANGUAGE RecordWildCards #-}
module Math(
extendedGCD
extendedGCD, safeGCD
, barrett, computeK, base
, modulate, modulate'
, isqrt
@@ -31,6 +31,21 @@ printState a =
putStrLn ("C: " ++ showX (bigC a))
putStrLn ("D: " ++ showX (bigD a))
safeGCD :: Integer -> Integer -> (Integer, Integer, Integer)
safeGCD self rhs = go (self, 1, 0) (rhs, 0, 1)
where
go (v, a, b) (0, _, _) = if v < 0
then (-a, -b, -v)
else (a, b, v)
go old new = go new (step old new)
--
step (old_r, old_s, old_t) (r, s, t) =
let quotient = old_r `div` r
r' = old_r - (r * quotient)
s' = old_s - (s * quotient)
t' = old_t - (t * quotient)
in (r', s', t')
extendedGCD :: Integer -> Integer -> (Integer, Integer, Integer)
extendedGCD x y = (a, b, g * (v finalState))
where

View File

@@ -271,13 +271,17 @@ sigmulTest size memory0 =
egcdTest :: Test
egcdTest size memory0 =
let (x, memory1) = generateNum memory0 "x" size
(y, memory2) = generateNum memory1 "y" size
(a, b, v) = extendedGCD x y
let (x, memory1) = genSign (generateNum memory0 "x" size)
(y, memory2) = genSign (generateNum memory1 "y" size)
(a, b, v) = if (x >= 0) && (y >= 0)
then extendedGCD x y
else safeGCD x y
res = Map.fromList [("x", showX x), ("y", showX y),
("a", showX a), ("b", showX b),
("v", showX v)]
in assert (v == gcd x y) (res, v, memory2)
in assert (((a * x) + (b * y)) == v) $
assert (v == gcd x y) $
(res, v, memory2)
moddivTest :: Test
moddivTest size memoryIn =