3

在计算期间将浮点值缩放十以保持精度总是精确的吗?

这个问题只适用于任何小于Math.pow (2,53)和大于Math.pow (10,-15),因为Math.pow (10,16 ) > Math.pow (2,53)

我希望这可以清除一些问题

0.3 - 0.2 //0.09999999999999998

明显不精确

但是对比例数字进行减法

var a = 0.3;
var b = 0.2;

var l = Math.max ("".split.call(a,".")[1].length,"".split.call(b,".")[1].length);

var c;

a *= Math.pow (10,l);
b *= Math.pow (10,l);

c = a-b;

c /= Math.pow(10,l);

console.log(c); //0.1

给出一个 精确的 结果。

问题是,是否有任何浮点值符合上述标准f<Math.pow(10,-15),当乘以十的幂(其中Math.pow ( 10 , n<16)<Math.pow(2,53)时,不会导致double value nearestN(b)-N(a)?再次除以相同的值10的幂?

就像上面的片段中描述的那样。

这只是一个感兴趣的问题,而不是用于实际计算,我只是好奇

对不起,我不擅长这个解释的东西

4

1 回答 1

1

我认为这个问题的意图是错误的。

如果您有一些二进制浮点值 a 和 b,您知道它们非常接近十进制数字,只有几位数字,那么将这些值乘以 10 的幂、减去并除以 10 的幂通常不会提供更好的结果比简单地直接减去值。每次乘法和除法通常都会引入一些舍入误差,这些往往会使最终结果不如简单地直接减去 a 和 b 准确。因此,使用这种迂回方法没有任何收获。

由于 a 和 b 已经有一些舍入误差(它们并不完全是它们接近的数字,而是您想要表示的那些数字),因此有时计算的值b-a不会是最接近差值的浮点值十进制数字(但它最多只有一个 ULP)。迂回计算中舍入误差的组合很少会提供更接近该差异的结果,但这更多是偶然(实际上是机会)而不是设计问题。

一旦您知道所涉及的 10 的幂 p,您可以通过计算 得到这个可能的最佳结果Math.round((b-a)*p)/p,前提是所涉及的数字足够小,以至于舍入误差(b-a)*p始终小于 0.5。

无论如何,这两种方法都不是设计计算的好方法。

关于 Edit3:所有小于 2 53的 10 的非负幂都可以精确表示。正确的pow实现会为这些情况返回准确的结果。考虑一个 double x,其中最低位集的值为 2 –d。乘以这个 double 时产生整数的十的最小幂是 10 d。如果 10 d小于 2 53并且 10 d •x 小于 2 53,那么两者都是完全可表示的。然后通过浮点运算的 IEEE-754 规范,10 d和 x 的乘积是精确的。

于 2013-05-23T18:01:02.060 回答