比较Javascript中的大数字

问题描述 投票:3回答:3

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

但是,在比较这两个数字时,我最终会得到这样的结果:

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

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

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

javascript math int comparison-operators
3个回答
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;
}

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

请注意,JavaScript是你可以进行数学运算的最糟糕的语言之一。当它们超出Number.MAX_SAFE_INT(根据Chrome看起来似乎是9007199254740991,不确定浏览器之间是否有所不同或者是否标准化)时,整数变得不精确不变)。


1
投票

var a = 4.0329146112660565e + 26;

是b = 4.0329146112661e + 26;

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

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

a == b;


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));
© www.soinside.com 2019 - 2024. All rights reserved.