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



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

铬: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的计算是正确的。

尽管Math.js在两种浏览器中是相同的代码,但不同的引擎有不同的算法来执行基本运算。例如,有许多不同的计算平方根的方法,两个不同的引擎不太可能共享完全相同的实现
有人努力使发动机的精度标准化,但迄今为止尚未成功。例如,请参阅本文
至于为什么Chrome中的Math.hypot会返回不同的值来在同一个引擎中手动进行计算,Math.hypot是一种有效的近似值,而不仅仅是一种将工作打包为单个函数的巧妙方法。因此,根据实施方式,其结果可能与实际计算不同。您正确地指出,在这种情况下,Firefox具有更精确的数字实现,您的简单测试就证明了这一点。

在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求和用于避免/最小化舍入误差——因此,显然其目的是使比简单的sqrt(x*x + y*y)实现更准确。(我试图验证在这种情况下是否真的是这样的结果,但Wolfram Alpha只是四舍五入到56.1124,我不知道还有什么方便的无限精度浮点计算器,所以我不能肯定。(

正确计算

在存在有限精度和舍入误差的情况下;正确的";这种方式很难定义。例如,在某些情况下,(数学等效!(表达式(a * b) / ca * (b / c)由于舍入而产生不同的结果,更重要的是,其中a、b、c的值决定了计算结果的哪种方式更接近(无限精度(理论结果,因此每个实现都可以得到";幸运的";或";不幸";。

最新更新