Haskell整数;这到底是怎么回事?

Haskell整数;这到底是怎么回事?,haskell,biginteger,Haskell,Biginteger,最近我对哈斯克尔很好奇,于是开始阅读整数s让我神魂颠倒 当我们说一个整数可以任意大时,这是否意味着我认为它的意思(即整数的大小不受操作系统地址宽度的限制) 假设我有足够的内存来容纳一个10亿位的数字。哈斯克尔能用这个号码工作吗 有谁能向我描述一下引擎盖下发生了什么使这成为可能吗?Haskell的Integer类型通俗地称为类型。它的工作原理与您手动执行数学计算的方式大致相同:处理数字而不是固定精度的二进制字 Bignum库通常将数字存储为一组数字。算术的工作方式和你用手做的一样;通过操纵数字 假

最近我对哈斯克尔很好奇,于是开始阅读<代码>整数s让我神魂颠倒

当我们说一个
整数
可以任意大时,这是否意味着我认为它的意思(即
整数
的大小不受操作系统地址宽度的限制)

假设我有足够的内存来容纳一个10亿位的数字。哈斯克尔能用这个号码工作吗


有谁能向我描述一下引擎盖下发生了什么使这成为可能吗?

Haskell的
Integer
类型通俗地称为类型。它的工作原理与您手动执行数学计算的方式大致相同:处理数字而不是固定精度的二进制字

Bignum库通常将数字存储为一组数字。算术的工作方式和你用手做的一样;通过操纵数字

假设我有足够的内存来容纳一个10亿位的数字。哈斯克尔能用这个号码工作吗

当然,它确实占用了相当多的内存

但仔细想想,一个字节实际上可以存储256>100的数字,也就是说,每个字节可以存储两个以上的十进制数字。因此,一个10亿位数的数字需要少于500 MB的存储空间。。。很明显,这里需要的乘法有一些开销(同样是当我
显示我正在生成的无效列表字符串的数字时),但没有什么戏剧性的

顺便说一句,进行这些计算的不是Haskell/GHC,而是GHC使用的

但是您可以自己在Haskell中轻松实现这样的类型。例如,为简单起见,请按照您的建议提供十进制数字列表†

newtype decdigat=DD{getDecDig::Int}
实例编号[DecDigit]其中
fromInteger n | n<10=[DD$fromInteger n]
|否则=let(cs,ls)=n`divMod`10
在DD$fromInteger ls中:fromInteger cs
n+[]=n
[]n=n
(DD n)₀ : n) +(ddm₀ : m)

|₀提示:您在一张纸上所做的算术是否被任意限制为某些位数?请在ghci中尝试:
10^(10^6)
有一百万位值。这不是十亿,但是朋友之间的
10^(10^9-10^6)
的一个因素是什么呢?我的大脑!我是说。。。从技术上讲,我受到石墨或墨水的数量以及接受上述墨水/石墨的介质的总表面积的限制。但是如果有足够大的一张纸和墨水/石墨的数量,不。@handomegorilla使用
Integer
可以使用的数字同样受到内存总量的限制。啊,好的。这让我对它的工作原理有了更直观的了解。我可以把一个
整数
想象成一个字符数字列表,其中位置表示位置值吗?这是一种过度简化吗?是的,需要注意的是,一个数字不一定是十进制数字(以十为基数)。Bigint库可以而且经常使用其他一些基,如256(字节数字)或65536(16位字数字)。好的Bignum库将数字存储为机器字的集合,而不是数字。这使生活变得更简单,计算速度也更快。后者很重要,因为bignum通常不受硬件支持,因此比机器支持的bignum慢很多。许多语言会尽可能多地使用机器字/整数,并且只有当结果对于一个机器字来说太大时才会使用BigNums。
Prelude> length . show $ 10^1000000000
1000000001
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₀

  ...