【发布时间】:2011-12-31 10:27:31
【问题描述】:
在对大数进行模数计算时,您会遇到巨大的性能损失,例如mod (123456789^987654321) n。相反,您必须使用您自己的 ^ 内部计算 mod n 也用于中间计算。
当然,我可以轻松实现自己的功能,但是我必须为每个操作明确地说“mod n”。取而代之的是,可以构建一棵数值表达式树并推迟实际计算,并且最终状态只取模一次。 (见下面我的代码)
我从这个开始是为了清楚地表明我的意思,但我想知道是否已经存在这个实现,它似乎很有用,所以应该有人实现它。
module Modulo where
data Expr =
V Integer
| Plus Expr Expr
| Mult Expr Expr
deriving (Eq, Show)
instance Num Expr where
(+) = Plus
(*) = Mult
fromInteger = V
eval :: Integer -> Expr -> Integer
eval m (V i) = i `mod` m
eval m (Plus e1 e2) = (eval m e1 + eval m e2) `mod` m
eval m (Mult e1 e2) = (eval m e1 * eval m e2) `mod` m
fifteen :: Expr
fifteen = 10 + 5
test = eval 13 fifteen
【问题讨论】:
-
您需要
mod m中的m在运行时更改,还是在编译时将其固定就足够了?如果编译时间足够的话,你可以简单地为一些新类型的Integer定义一个模算术Num-instance... -
我希望它在运行时可以更改。对不起,我应该提到它。