【问题标题】:How does an environment (e.g. Ruby) handle massive integers?环境(例如 Ruby)如何处理大量整数?
【发布时间】:2010-12-07 16:03:45
【问题描述】:

我在 Ruby (MRI) 中的整数拒绝溢出。我注意到类从 fixnum 更改为 bignum,但我想知道这是如何建模的,以及 ruby​​ 使用哪种进程对这些大量整数执行算术。我在 SCHEME 以及其他环境中都看到过这种行为。

我问是因为我想在 C 程序中实现类似的东西,并且想知道 bignum + bignum 如何简化为原始操作。

任何指针?

【问题讨论】:

标签: memory integer abstraction math computation


【解决方案1】:

Python 也这样做。

基本上,它不是将数字视为自然适合硬件架构的一串位(例如 32 位),而是将数字视为一串 32 位数字,然后实现所有算术运算来处理进位从一个 32 位数字到另一个。这还涉及随着数字的增长分配额外的 32 位数字。这比看起来容易。

例如,99 * 99 小于 100 * 100 即 10,000,因此可以假设将两个 2 位数字相乘将产生不超过 4 位的结果。当每个数字都是 32 位字时,同样适用。

您可能想尝试在 Ruby 中实现这一点,只是为了好玩,使用一些允许固定二进制数量的类型。我相信 FixNum 类会起作用。

【讨论】:

  • "当每个数字都是 32 位字时,同样适用。"换句话说,算术是在基数 4294967295 中完成的,两个值的乘积将始终适合这些值的组合长度。非常好!
【解决方案2】:

请参阅《C 的数值食谱》中的第 20.6 节:http://www.nrbook.com/a/bookcpdf.php

这是任意精度数学的绝佳实现。如果你想变得花哨,你会创建一个重载运算符然后实现这些函数的 C++ 类。或者你可以直接打电话给他们。

【讨论】:

  • 多么棒的资源!谢谢你和 +1 :-)
【解决方案3】:

Erlang 也是这样做的。您可以查看 erl_interface 模块中的源代码(C 语言)。

【讨论】:

  • 确实如此,我很快就会查看源代码(对于 Ruby,我希望如此。)但是,如果我已经对这个过程的工作方式有一个合理的了解,那么我会为那一天做好准备。
【解决方案4】:

基本上,它归结为长加法/乘法/除法/减法。可以从那里进行很多优化(duh),因此不建议您自己进行优化。我建议查看 GMP(gnu 多精度)项目,该项目静态或动态链接到您的应用程序。它不难使用,但有一些 C++ 和其他包装器可以让您更简单地使用它。如果您正在处理浮点数,请获取 MPFR,它可以正确处理舍入。

【讨论】:

  • 谢谢,但我想自己动手并优化它:-) 这是一个私人项目,我想学习。完成后,如果我的尝试失败,我可能会切换到一个做得更好的库。我也会检查 GMP。
  • 我把“它归结为长加法”误解为长整数加法,仍然留下检测溢出的问题。大多数小学生都会指出长加法实际上是他们在课堂上学到的一种算法,从而使我直截了当:-)
猜你喜欢
  • 2014-07-10
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 2017-02-21
  • 2023-03-22
相关资源
最近更新 更多