编程语言如何处理大量算术运算

时间:2009-09-17 13:03:21

标签: math memory numbers integer

对于使用64位处理器的计算机,它可以处理的最大数字是2 64 = 18,446,744,073,709,551,616。编程语言(比如Java或C,C ++)如何处理高于此值的数字算法。任何登记册都不能作为一个整体。这个问题是如何解决的?

9 个答案:

答案 0 :(得分:5)

有许多专门的技术可以对大于寄存器大小的数字进行计算。其中一些内容在此维基百科文章arbitrary precision arithmetic

中列出

低级语言(如C和C ++)会将大量计算留给您选择的库。一个值得注意的是GNU Multi-Precision library。像Python这样的高级语言将其集成到语言的核心,因此正常数字和非常大的数字与程序员完​​全相同。

答案 1 :(得分:1)

你认为是错的。它可以在单个寄存器中处理的最大数字是64位数。但是,使用一些智能编程技术,您可以连续组合几十个这些64位数字来生成一个巨大的6400位数,并使用它来进行更多计算。它只是没有将数字放在一个寄存器中那么快。

即使是旧的8位和16位处理器也使用了这个技巧,他们只是让数字溢出到其他寄存器。它使数学更复杂,但它并没有结束可能性。

然而,这种高精度数学是非常不寻常的。即使您想计算美国的全部国债并将结果存储在津巴布韦元中,我认为64位整数仍然足够大。不过,它绝对足以容纳我的储蓄账户金额。

答案 2 :(得分:1)

Ada实际上支持这种本地,但仅限于它的无类型常量(“命名数字”)。对于实际变量,您需要找到任意长度的包。见Arbitrary length integer in Ada

答案 3 :(得分:1)

或多或少与的方式相同。在学校里,你记住了一位数的加法,乘法,减法和除法。然后,您学习了如何将多位数问题作为一系列单位数问题进行处理。

如果您愿意,您可以使用简单算法的知识和单位数时间表将两个二十位数字相乘。

答案 4 :(得分:1)

处理真正大量数字的编程语言使用超出针对32,64或128位CPU优化的正常操作的自定义数字原语。这些数字在计算机安全和数学研究中特别有用。

GNU Multiple Precision Library可能是这些方法中最完整的例子。

您可以使用数组处理更大的数字。在您的网络浏览器中试试这个。在Web浏览器的JavaScript控制台中键入以下代码:

JavaScript失败的时间

console.log(9999999999999998 + 1)
// expected 9999999999999999
// actual  10000000000000000  oops!

JavaScript不处理9999999999999998以上的普通整数。但是编写自己的数字原语是为了使这个计算工作变得足够简单。以下是使用a custom number adder class in JavaScript的示例。

使用自定义数字类传递测试

// Require a custom number primative class
const {Num} = require('./bases')

// Create a massive number that JavaScript will not add to (correctly)
const num = new Num(9999999999999998, 10)

// Add to the massive number
num.add(1)

// The result is correct (where plain JavaScript Math would fail)
console.log(num.val)  // 9999999999999999

工作原理

您可以查看class Num { ... }处的代码,了解正在发生的事情的详细信息;但这里是使用逻辑的基本概要:

类:

  • Num类包含单个Digit类的数组。
  • Digit类包含单个数字的值,以及处理Carry flag的逻辑

步骤:

  1. 所选号码变为字符串
  2. 每个数字都变成Digit类,并作为数字数组存储在Num类中
  3. Num递增时,它会被转移到数组中的第一个Digit(最右边的数字)
  4. 如果Digit值加上Carry flag等于Base,则调用左边的下一个Digit递增,当前的数字是重置为0
  5. ...一直重复到数组最左边的数字
  6. 从逻辑上讲,它与机器级别的情况非常相似,但在这里它是无限的。你可以read more about about how digits are carried here;这可以应用于任何基数。

答案 5 :(得分:0)

一般来说,语言本身不能处理高精度,高精度的大数字运算。编写的可能性更大,它使用备用数值方法来执行所需的操作。

例如(我现在正在进行此操作),这样的库可能会模拟您可能用来手动执行大量算术的实际技术。这些库通常比使用内置算法慢得多,但有时需要额外的精度和准确度。

答案 6 :(得分:0)

作为一个思想实验,想象一下存储为字符串的数字。使用函数来添加,乘以等这些任意长的数字。

实际上,这些数字可能以更节省空间的方式存储。

答案 7 :(得分:0)

将一个机器大小的数字视为一个数字,并将该算法应用于小学的多位数乘法。然后你不需要将整个数字保存在寄存器中,只需要处理它们的数字。

答案 8 :(得分:0)

大多数语言将它们存储为整数数组。如果你在这些大数字中加/减两个,那么库会分别在数组中添加/减去所有整数元素并处理进位/借位。 这就像在学校手动添加/减少,因为这是它在内部的工作方式。

有些语言使用真正的文本字符串而不是整数数组,效率较低但转换为文本表示形式更简单。