我刚刚了解了Karatsuba算法,并尝试在Haskell中实现它。
这是我的代码:
(***) :: Integer -> Integer -> Integer
x *** y
| max x y < ub = x*y
| otherwise =z2*base*base + ((x1+x0)***(y1+y0)-z2-z0)*base + z0
where
base =10^((length . show $ max x y) `div` 2)
z2 =x1***y1
z0 = x0***y0
(x1, x0) = helper x
(y1, y0) = helper y
helper n = (n `div` base, n `mod` base)
ub = 10000
只要我检查的数字够大,比如20-30位数,这个算法就可以准确地工作,并且对于10-20位数字来说速度也足够快。然而,当处理100位甚至更大的数字时,它比正常情况下的*
慢很多。我该如何改进这个算法呢?
base =10^((length . show $ max x y)
div2)
不好。虽然 GHC 对于Integer
的Show
实例比 Java 的BigInteger.toString()
或 Python 的str
在处理大数时要快得多,但仍然相当慢(想想它必须做什么)。你应该在那里使用GHC.Float.integerLogBase
来获得一个不错的加速效果。如果你使用一个 2 的幂作为基数,那就更好了。 - Daniel Fischer