标准 ML 是否有 Java BigInt 等价物?正常的 int 类型在溢出时会抛出异常。
5 回答
是的,请参阅IntInf结构。
官方 SML'97 标准基础库引入了 Int、IntInf、Int32、Int64、LargeInt 等结构的动物园。
要在实践中实际使用它们以使事情按预期工作,并使它们有效地工作,您需要仔细研究手头的 SML 实现。
一个系列的实现模仿了 C 和 Java 的内存布局,因此 Int32 将是一个真正的 32 位机器字(但带有溢出检查),而 Int64 是一个 64 位的机器字。SML/NJ 就是一个显着的例子,它的小整数运算速度快,但它的大整数运算速度慢。
另一类实现来自符号计算(LISP 或计算机代数)的背景,其中 Poly/ML 是一个值得注意的例子。在这里,默认情况下您有 Int = IntInf = LargeInt,并且实现首先使用(部分)本机机器字作为近似值,直到它溢出,然后切换到在堆上分配的非常大的整数(作为装箱值)。Poly/ML 使用 GNU MP 库来完成大部分工作。
因此,只要您的应用程序是整数,而不是特定大小的机器字,Int/IntInf 就非常有效:由于需要额外的标记位,符号模型中的 Int32 不适合 32 位硬件上的单个字。所以一些实际上是关于字算术的算法会降级,例如 32 位硬件上的 SHA1。
另一方面,将short-than-wordsize int 隐式升级为堆分配的big int 给你比Java 中的BigInt 更好的东西,因为你不需要小值的全部对象开销:42 只是一点点寄存器中的模式(带有额外的标记位),但不是堆上的重框。
BigInt 等效项称为 LargeInt。请参阅这些讲义以了解有关如何在 int(又名 Int)和 LargeInt 之间转换的一些函数。
虽然这并不是您所要求的,但您实际上并不想要与 Java BigInt 类等效的东西。Java 的 BigInt 类实现了 O(n^2) 时间的乘法(本质上是乘以它在小学的教学方式),而不是 O(n log n),这是可能的。这非常重要,因为许多琐碎的 BigInt 编程根本不适用于 n^2 版本。
好吧, int 对诸如计算排列之类的东西施加了令人讨厌的限制。SML 需要使用更自然的大型数字数据类型。