Haskell mod malfunction?



这是我的Haskell函数从列表中删除2::Int5::Int:

remPrimesFactors25 :: [Int] -> [Int]
remPrimesFactors25 [] = []
remPrimesFactors25 (x:xs)
| x == 2                  = remPrimesFactors25 xs
| x == 5                  = remPrimesFactors25 xs
| otherwise           = x : remPrimesFactors25 xs
λ>  remPrimesFactors25 [2,5,23]
[23]
λ>  remPrimesFactors25 [2,5,23] == [23]
True
λ>  product (remPrimesFactors25 [2,5,23])
23
λ>  product [23]
23
λ>  product (remPrimesFactors25 [2,5,23]) == product [23]
True

这是我的问题为什么会发生这种情况?

λ>  mod (10^22) (product (remPrimesFactors25 [2,5,23]) )
15
λ>  mod (10^22) (product [23])
1

remPrimesFactors总是返回Int值的列表,而不是Integer值。由于mod要求两个参数具有相同的类型,因此10^22也被视为Int,后者没有精确处理大数的精度。

Prelude> 10^22 :: Integer
10000000000000000000000
Prelude> 10^22 :: Int
1864712049423024128

您正在使用Int。aInt使用固定位数,并且至少可以表示-229到229-1范围内的所有值。通常在32位机器上,取值范围是-231到231-1,在64位机器上,取值范围是-263到263-1。然而,10^22大于这些范围。这意味着Int对应的10^22将在64位机器上表示为1'864'712'049'423'024'128。

如果您使用Integer,它可以表示任意大小的值,那么就没有这样的问题。如果这样将函数重写为:

remPrimesFactors25 :: [Integer] -> [Integer]
remPrimesFactors25 = filter (x -> x != 2 && x != 5)

10^22将被解释为Integer,因此10^22将取值为10'000'000'000'000'000'000'000 '000'000'000'000。

你不需要计算10^22。你可以使用像powerMod :: (Integral a, Integral b) => a -> b -> a -> a这样的算法arithmoi包。

相关内容

  • 没有找到相关文章

最新更新