这是我的Haskell函数从列表中删除2::Int
和5::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
包。