【发布时间】:2014-05-01 05:16:07
【问题描述】:
在 JavaScript 中,没有可用的原生 cbrt 方法。理论上,你可以使用这样的方法:
function cbrt(x) {
return Math.pow(x, 1 / 3);
}
但是,这失败了,因为数学中的恒等式不一定适用于浮点运算。例如,1/3 不能用二进制浮点格式准确表示。
失败的例子如下:
cbrt(Math.pow(4, 3)); // 3.9999999999999996
随着数量的增加,情况会变得更糟:
cbrt(Math.pow(165140, 3)); // 165139.99999999988
是否有任何算法能够在几个 ULP(如果可能的话,最好是 1 个 ULP)内计算立方根值?
这个问题类似于Computing a correctly rounded / an almost correctly rounded floating-point cubic root,但请记住,JavaScript 没有任何更高精度的数字类型可以使用(JavaScript 中只有一种数字类型),也没有内置的 @ 987654327@ 函数开头。
【问题讨论】:
-
您的问题与stackoverflow.com/questions/18063755/… 非常接近。我只能重申我在思考时发现的技巧,虽然 1/3 不能表示为双精度,但 3 是,所以你可以
pow(candidate, 3)并检查原始值(假设pow()很好质量)(理想情况下,您应该有一个正确舍入的pow_ru()和一点额外的精度)。 -
@PascalCuoq:确实相当接近。关于这个问题的唯一问题是它似乎与 C99 相关,如果我没记错的话,它具有诸如长双精度数之类的选项,以便能够获得更高的精度。 JS 的问题在于,由于它的单一数字类型,它没有那么额外的精度,这使得事情变得更加困难。
标签: javascript algorithm floating-point