比较Javascript中的大数字

时间:2017-11-04 06:32:00

标签: javascript math int comparison-operators

我有两个我要比较的数字。以下示例中的数字是在两个不同系统中计算的26^26的结果。其中一个是我的javascript代码。

然而,当比较这两个数字时,我最终会得到这样的结果:

AssertionError [ERR_ASSERTION]: 4.0329146112660565e+26 == 4.0329146112661e+26

他们显然不相等,但理论上他们应该这样。

在javascript中对大数字执行相等的正确方法是什么(即使它是近似值)?

4 个答案:

答案 0 :(得分:3)

如果您要做的是确定两个数字是否实际等效,那么您必须提出误差幅度。一种方法是计算数字之间的差异,然后确定这种差异是否显着。

因此,从之前的数字中,我们可以通过减法来评估这些数字之间的差异。既然我们并不真正关心这种差异的迹象,我会继续前进并获得差异的绝对值。

Math.abs(4.0329146112660565e+26 - 4.0329146112661e+26) === 4329327034368

(旁注:现在不是解释原因的时候,但JavaScript中的==运算符会产生令人困惑且容易出错的行为,当你想要比较值时使用===。)

这个差异是一个巨大的数字,但与我们的数字在多大程度上相关,它是相当微不足道的。直觉上,我很想将差异除以原始数字中最小的一个,如下所示:

4329327034368 / 4.0329146112660565e+26 === 1.0734983136696987e-14

这看起来很小。使用一堆值重复相同的操作,您应该能够确定您想要的误差范围。然后,您所要做的就是使用任意数字执行相同的操作,并查看该差异比率"对你来说足够小。

function similar(a, b) {
  let diff = Math.abs(a - b);
  let smallest = Math.min(Math.abs(a), Math.abs(b));
  let ratio = diff / smallest;
  return ratio < MARGIN_OF_ERROR;
}

现在我想出了确定两个数字之间差异的重要性的方法。它可能不是一种非常聪明的计算方法,它可能适用于某些情况而不适用于其他情况。但一般的想法是,你必须制作一个函数来确定两个值是否足够接近你自己的定义&#34; close&#34;。

请注意,JavaScript是您可以进行数学运算的最差语言之一。当它们超出Number.MAX_SAFE_INT(根据Chrome浏览器似乎是9007199254740991,并不确定浏览器之间是否有所不同,或者如果它们不同,整数变得不精确)那是一个标准化的常数。

答案 1 :(得分:1)

var a = 4.0329146112660565e + 26;

var b = 4.0329146112661e + 26;

a = Math.round(a / 10e + 20)* 10e + 20

b = Math.round(b / 10e + 20)* 10e + 20

a == b;

答案 2 :(得分:1)

更新:如果您的目标引擎为es2020或更高版本,则可以使用新的BigInt javascript原语来获取大于Number.MAX_SAFE_INTEGER

BigInt(4.0329146112660565e+26) === BigInt(4.0329146112661e+26)
//false

See more information in MDN

答案 3 :(得分:0)

我建议使用大数字库之一:

  1. big.js(https://www.npmjs.com/package/big.js

示例:

var x = new Big('4.0329146112660565e+26');

var y = new Big('4.0329146112661e+26');

// Should print false
console.log('Comparision result' + x.eq(y));
  1. 大数(https://www.npmjs.com/package/big-numbers

示例:

var x = bn.of('4.0329146112660565e+26');
var y = bn.of('4.0329146112661e+26');

// Should print false
console.log('Comparision result' + x.equals(y));