Chrome和Firefox上Math.hypot()的不同结果

时间:2020-07-16 09:48:53

标签: javascript google-chrome firefox v8 hypotenuse

当我在下面运行简单计算时,Chrome和Firefox上的结果略有不同。

Chrome浏览器:56.1124478168614

Firefox:56.11244781686139

let x = -24.42;
let y = -50.519999999999925;
console.log(Math.hypot(x, y));

Math.hypot()的规范中是否存在漏洞?或者是其中一种浏览器以错误的方式实现了该错误?

编辑:在Firefox Math.hypot(x, y)中,结果与Math.sqrt(x*x, y*y)相同;在Chrome中,Math.hypot(x, y)中的结果略有不同。因此,我怀疑Firefox在正确地进行计算。

2 个答案:

答案 0 :(得分:1)

尽管Math.js在两个浏览器中都是相同的代码,但是不同的引擎具有不同的算法来执行基本算术。例如,计算平方根的方法有很多,并且两个不同的引擎不太可能共享完全相同的实现。
目前正在努力使各个发动机的精度标准化,但迄今为止还没有成功。例如,请参见this article
关于为什么Chrome中的Math.hypot会在同一引擎中手动执行计算时返回不同的值的原因,Math.hypot旨在作为一种有效的近似值-不仅仅是将工作包装成一个单一的巧妙方法功能。因此,根据实现方式,其结果可能与实际计算有所不同。您正确地说,在这种情况下,通过简单的测试即可证明Firefox具有更精确的数字实现。

答案 1 :(得分:1)

在Firefox中,Math.hypot(x, y)Math.sqrt(x*x, y*y)的结果相同

这使我们对Firefox如何实现Math.hypot:-)

充满信心。

在Chrome中,Math.hypot(x, y)的结果略有不同

这是Chrome的实现:

https://chromium.googlesource.com/v8/v8/+/master/src/builtins/math.tq#389

从第421行的注释中可以看到,Kahan求和用于避免/最小化舍入误差-因此显然,其目的是比简单的{{1} }实施。 (我已经尝试验证在这种情况下是否真的是结果,但是Wolfram Alpha只是四舍五入为sqrt(x*x + y*y),而且我不知道那里还有另一个方便的无穷精度浮点评估器,因此我可以不能肯定地说。)

正确进行计算

在有限的精度和舍入误差的情况下,很难定义“正确”的方式。例如,在某些情况下,(四舍五入!)表达式56.1124(a * b) / c由于舍入而产生不同的结果,而且,a,b,c的值决定了哪种计算方式结果接近(无限精度)理论结果,因此每个实现都可能是“幸运的”或“不幸的”。