浮动的缩放比例总是精确的

时间:2013-05-23 09:37:35

标签: javascript floating-point scaling

将浮点值缩放10以在计算过程中保持精度始终是精确的吗?

此问题仅适用于 },Math.pow (2,53)

我希望这会清除一些要点

Math.pow (10,-15)

显然是不明智的

但是在缩放数字上进行减法

Math.pow (10,16 ) > Math.pow (2,53)

提供精确结果。

问题是,是否有任何浮点值,与上面提到的标准0.3 - 0.2 //0.09999999999999998相匹配,乘以10的幂(其中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 )< / em>,会导致f<Math.pow(10,-15) N(b)-N(a)?,当再次被相同的 10次幂分割时?

如上面的代码段所述。

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

因为误解而烦恼我在这个解释中并不好用

1 个答案:

答案 0 :(得分:1)

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

如果你有一些二进制浮点值a和b,你知道它们是非常接近带有几个数字的十进制数字,那么将这些值乘以10的幂,减去并除以10的幂通常不会提供比直接减去值更好的结果。乘法和除法中的每一个经常引入一些舍入误差,并且这些往往使得最终结果不如简单地直接减去a和b。因此,使用这种迂回方法没有任何好处。

由于a和b已经有一些舍入误差(它们不是它们附近的数字,并且它是你想要表示的那些数字),有时计算值b-a将不是浮点数最接近十进制数字差异的值(但最多只有一个ULP)。绕道计算中的舍入误差的组合很少会提供更接近该差异的结果,但这更多地是偶然事件(有效机会)而不是设计。

一旦你知道所涉及的10的力量p,你可以通过计算Math.round((b-a)*p)/p得到最好的结果,只要涉及的数字足够小,(b-a)*p中的舍入误差总是小于pow。 0.5。

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

关于Edit3:10个小于2 53 的所有非负幂都可以准确表示。正确的{{1}}实现会返回这些案例的确切结果。考虑一个双x,其中最低位集的值为2 -d 。当乘以该double时产生整数的10的最小幂是10 d 。如果10 d 小于2 53 且10 d •x小于2 53 ,那么两者都是完全可以代表。然后根据IEEE-754浮点运算规范,10 d 和x的乘积是精确的。