gpt4 book ai didi

haskell - 大数字在haskell中变成负数

转载 作者:行者123 更新时间:2023-12-04 22:43:59 26 4
gpt4 key购买 nike

(product (take 9 [1000,999..])) `div` (product (map (\j-> product [1..j]) (map (\j->length(j)) (group [2,2,2,2,2,2,2,2,2]))))

上面的代码是 X div Y 的形式,带有 X=product (take 9 [1000,999..]) & Y=(product (map (\j-> product [1..j]) (map (\j->length(j)) (group [2,2,2,2,2,2,2,2,2]))))
如果我将代码复制并粘贴到 ghci 中,它会给我 -12740133310672 作为答案,
但是如果我单独计算 X & Y ,我会得到 964541486381834014456320000 & 362880 ,然后将它们分开给我 2658017764500203964000 作为答案。

我认为这种不连贯可能是因为数字太大,但是由于计算机可以单独正确计算X和Y,为什么它也不能将它们组合起来呢?

最佳答案

Prelude Data.List> let x = product $ take 9 [1000,999..]

Prelude Data.List> x
964541486381834014456320000
Prelude Data.List> :t x
x :: (Enum a, Num a) => a

观察 x 具有通用数字的类型:您仅使用适用于任何数字类型的操作计算它。当您在 GHCi 中计算这样的数字时,它默认为“最安全”的具体类型,即 Integer ,这是一种对大数字没有问题的任意精度类型。但是,您可以强制使用任何其他数字类型完成计算:
Prelude Data.List> x :: Integer
964541486381834014456320000
Prelude Data.List> x :: Float
9.645414e26
Prelude Data.List> x :: Double
9.645414863818342e26
Prelude Data.List> x :: Int
-4623139575776374784

浮点版本不准确但仍然接近,而 Int(机器大小的固定精度数)只是溢出并提供完整的伪造。

通常这不会打扰您,因为默认情况下,大量计算是使用安全的 Integer 类型完成的。

也就是说,除非有其他事情阻止它。
Prelude Data.List> let y = product (map (\j-> product [1..j]) $ map length (group [2,2,2,2,2,2,2,2,2]))

Prelude Data.List> y
362880
Prelude Data.List> :t y
y :: Int

x 不同, y 的类型已经是具体的:它必须是 Int ,因为那是 length 的结果类型。 (基本原理是:一个列表太大以至于您无法使用 Int 测量其长度,无论如何也无法放入内存中。)

现在, div 与 Haskell 中的大多数数字函数一样,要求参数和结果都具有相同的类型。出于这个原因, x`div`y 将作为一个整体计算为 Int 而不是 Integer ,包括 x 。正如我们所见,将 x 计算为 Int 是假的。

OTOH,如果您使用 362880 作为文字,那么这与 length 无关。它只是一个通用数字,如 x ,因此 GHCi 将再次默认为安全 Integer ,即你得到
Prelude Data.List> x `div` 362880
2658017764500203964000

如果您只允许转换 y ,则可以获得相同的结果:
Prelude Data.List> x `div` fromIntegral y
2658017764500203964000

关于haskell - 大数字在haskell中变成负数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36355757/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com