将浮点值缩放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次幂分割时?
如上面的代码段所述。
这只是一个有趣的问题,而不是用于实际计算,我只是好奇
因为误解而烦恼我在这个解释中并不好用
答案 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的乘积是精确的。