Javascript 浮点数按10的比例缩放是否总是精确的

Javascript 浮点数按10的比例缩放是否总是精确的,javascript,floating-point,scaling,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.09999999998 这显然是不精确的 但是在一个有刻度的数字上做减法 var a = 0.3; var b = 0.2; var l = Math.max ("".split.call(a,".")[1].length,"".spl

在计算过程中,将浮点值缩放10以保持精度是否总是精确的

此问题仅适用于小于
Math.pow(2,53)
且大于
Math.pow(10,-15)
的任何数字,如
Math.pow(10,16)>Math.pow(2,53)

我希望这能澄清一些问题

0.3-0.2//0.09999999998

这显然是不精确的

但是在一个有刻度的数字上做减法

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我认为问题的意图是错误的

如果你有一些二进制浮点值a和b,你知道它们是非常接近十进制数的几个数字,那么将这些值乘以十的幂,然后减去,再除以十的幂,通常不会提供比直接减去这些值更好的结果。每一次乘法和除法通常都会引入一些舍入误差,这往往会使最终结果不如直接减去a和b准确。因此,使用这种迂回的方法一无所获

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

一旦你知道所涉及的10的幂,p,你可以通过计算
Math.round((b-a)*p)/p来得到最好的结果,前提是所涉及的数字足够小,以至于
(b-a)*p
中的舍入误差总是小于.5

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


关于Edit3:小于253的10的所有非负幂都是可精确表示的。适当的
pow
实现会为这些情况返回准确的结果。考虑一个双X,其中最低的位集具有值2席。当乘以这个双精度时,产生整数的最小十次方是10d。如果10d小于253,10d•x小于253,则两者都是可精确表示的。然后根据IEEE-754浮点运算规范,10d和x的乘积是精确的。

为什么不运行它?只有9007199254740992次迭代:)@mplungjan只有当
b
始终是相同的数字=)Lol。数学从来都不是我的强项-+1,因为有趣的字符串转换和随后的十进制长度计数可能会有人说得更好,并且理解我想问的问题,可以将其中的一部分重新措辞以避免误解?=)关于Edit3:小于253的10的所有非负幂都是可精确表示的。适当的
pow
实现会为这些情况返回准确的结果。考虑一个<代码>双席,其中最低的位集值为2 **-d。当乘以此
double
时,产生整数的最小十次幂为10d。如果10d小于253,10d•x小于253,则两者都是可精确表示的。然后根据IEEE-754浮点运算规范,10**d和x的乘积是精确的。谢谢你的评论,答案=)关于你的评论,我更新了问题。但要么我把你的答案搞错了,要么你把我的问题问错了,因为这仍然不能回答我的问题,我的意思是,有没有任何浮点值,与前面提到的标准相匹配,
fIt`snot,我实际上不想用它进行计算。这是一个好奇的问题:)@C5H8NNaO4:我在评论中回答了Edit3。然而,对于您描述的目的来说,这基本上是无用的。为了“乘以10直到得到一个整数”,必须乘以从2**–1位到最小值集位的位数。这通常不同于可能与数字相关联的小数位数。例如,对于“1.15”,它需要1051,而不是102。谢谢你的评论,回答了我的问题=),我将问题简化为上面的评论。