Add additional support for GCD on signed numbers.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user