与python相比,为什么Javascript不能为科学计算提供准确的结果

D4t*_*ech 3 javascript python

我尝试在Javascript中执行Modular Exponentiation来验证算法,并且发现Javascript与Python相比没有给出准确的结果感到震惊,为什么会如此.我认为它与Javascript处理数据类型的方式有关(如Text),但我想了解更多关于它的信息,我知道为什么两个langs都被设计的目的.

.js和.py中的模块化指数结果比较

pok*_*oke 10

当您在模运算之前查看中间结果时,它会更清晰一些:

> Math.pow(17, 22)
1.1745628765211486e+27
Run Code Online (Sandbox Code Playgroud)
>>> pow(17, 22)
1174562876521148458974062689
Run Code Online (Sandbox Code Playgroud)

如您所见,Python结果的数字比JavaScript结果多得多.这是由于每种语言如何处理数字或整数.

Python有一种int类型,它基本上是无限的:"这些类型代表无限范围内的数字,仅受可用(虚拟)内存的限制."因此,只要您有可用的内存,可以使用此类型表示的整数可以是你想要的大 - 没有任何精度损失.

输入JavaScript和ECMA标准.与Python和其他语言不同,我们只有一种类型负责所有数字类型:Number.这种类型保持整数和小数,没有任何区别.它们在内部表示为双精度浮点数.因此,它们受到这些限制,只允许大数量的精确度.因此,您可以获得的最好17^22结果是上述结果,其余精度在此过程中丢失.


如果你不是太专注于性能,你可以编写自己的pow函数,另外需要第三个参数来对结果应用模运算,类似于Python的pow工作方式.

function modpow (base, exponent, modulo) {
    var result = base;
    while (exponent > 1 ) {
        result = (result * base) % modulo;
        exponent--;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

当然,这比内部效率低得多pow,只适用于整数指数,但至少它可以正确解决你的工作:

> modpow(17, 22, 21)
4
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 7

Python中pow()函数返回整数输入的整数结果:

>>> pow(17, 22)
1174562876521148458974062689L
Run Code Online (Sandbox Code Playgroud)

这是不一样的功能,因为什么Math.pow()给你,它采用浮点结果:

> Math.pow(17, 22)
  1.1745628765211486e+27
Run Code Online (Sandbox Code Playgroud)

Python中的等效函数是math.pow():

>>> import math
>>> math.pow(17, 22)
1.1745628765211484e+27
Run Code Online (Sandbox Code Playgroud)

并且受到相同的限制,尽管实际结果略有不同:

>>> math.pow(17, 22) % 21
3.0
Run Code Online (Sandbox Code Playgroud)

JavaScript只有Number类型,它总是将JS算法限制为浮点精度,而Python对内存限制的整数类型的支持为它提供了更多的精度范围.