最近对Haskell感到好奇,我开始做一些阅读。 Integer
让我大吃一惊。
当我们说Integer
可以任意大时,这是否意味着我的意思(即Integer
的大小不受操作系统地址宽度的限制)?< / p>
假设我有足够的RAM可用于存储具有十亿个值的数字。 Haskell能够使用这个数字吗?
任何人都可以向我描述一下这是怎么回事?
答案 0 :(得分:5)
假设我有足够的RAM可用于存储具有十亿个值的数字。 Haskell能够使用这个数字吗?
Prelude> length . show $ 10^1000000000
1000000001
当然,它确实占用了相当多的内存
但是如果你考虑一下 - 一个字节实际上可以存储高达256> 100的数字,即你可以在每个字节中存储两个以上的十进制数字。因此,具有十亿个数字的数字应该少于500 MB来存储......好吧,显然这里有一些开销需要乘法(当我show
时,数字I生成一个低效列表-string)但没什么戏剧性的。
但是可以在Haskell中自己轻松实现这样的类型。例如。为简单起见,建议使用†
的十进制数字列表newtype DecDigit = DD { getDecDig :: Int }
instance Num [DecDigit] where
fromInteger n | n < 10 = [DD $ fromInteger n]
| otherwise = let (cs,ls) = n`divMod`10
in DD $ fromInteger ls : fromInteger cs
n + [] = n
[] + n = n
(DD n₀ : n) + (DD m₀ : m)
| s₀<10 = DD s₀ : n+m
| otherwise = DD (s₀-10) : n+m+[DD 1]
where s₀ = n₀+m₀
...
乘法有点困难,但基本上,就像罗伯特哈维所说,它都像你用笔和纸计算。
† 这是非常低效的!实际实现不使用十进制数字,而是充分利用机器大小的单词(可能使用现代处理器的128位甚至256位基本操作)。
答案 1 :(得分:4)
Haskell的Integer
类型通俗地称为bignum类型。它的工作方式与手动执行数学计算的方式大致相同:处理数字而不是固定精度二进制字。
Bignum库通常将数字存储为数字集合。算术的工作方式与手动执行相同;通过操纵数字。