【问题标题】:Is scaling of floats by ten always precise浮动十倍的缩放总是精确的
【发布时间】:2013-05-23 09:37:34
【问题描述】:

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

这个问题只适用于任何涉及的数字小于小于Math.pow (2,53)大于大于Math.pow (10,-15),如@ 987654323@

我希望这能清除一些问题

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

给出"精确的"结果。

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

就像上面sn-p中描述的那样。

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

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

【问题讨论】:

  • 为什么不运行它?只有 9007199254740992 次迭代 :)
  • @mplungjan 仅当 b 始终是相同的数字 =)
  • 大声笑。数学从来都不是我的强项 - 有趣的字符串转换和随后的十进制长度计数 +1
  • 也许英语说得更好并且理解我想问的内容的人可以改写部分内容以避免误解? =)
  • 关于 Edit3:所有小于 253 的 10 的非负幂都可以精确表示。正确的pow 实现会为这些情况返回准确的结果。考虑一个double x,其中最低位集的值为 2**–d。乘以 double 时产生整数的十的最小幂是 10d。如果 10d 小于 253 且 10d•x 小于 253,则两者都是完全可表示的。那么按照 IEEE-754 浮点算术规范,10**d 和 x 的乘积是精确的。

标签: javascript floating-point scaling


【解决方案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:所有小于 253 的 10 的非负幂都是可以精确表示的。正确的pow 实现会为这些情况返回准确的结果。考虑一个双 x,其中最低位集的值为 2–d。乘以这个 double 时产生整数的十的最小幂是 10d。如果 10d 小于 253 且 10d•x 小于 253,那么两者都是完全可以代表。那么按照 IEEE-754 浮点运算规范,10d 和 x 的乘积是精确的。

【讨论】:

  • 感谢您的评论和答案 =) 关于您的评论,我更新了问题。但是要么我的答案错了,要么你的问题是我的问题,因为这仍然不能回答我的问题,我的意思是,是否有 any 浮点值,匹配问题中提到的标准 f<Math.pow(10,-15),乘以十的幂(其中Math.pow ( 10 , n<16)<Math.pow(2,53),得到数学正确值,(其中result<Math.pow(2,53) .我希望这次我得到了正确的解释。
  • 并不是我真的想用它来计算。这是一个好奇的问题:)
  • @C5H8NNaO4:我在评论中回答了 Edit3。但是,对于您所描述的目的,这基本上是无用的。为了“乘以 10 直到得到一个整数”,您必须乘以从 2**–1 位到最低值设置位的位数。这通常不同于可能与数字相关联的 十进制 位数。例如,对于“1.15”,它需要 1051,而不是 102。
  • 感谢您的评论,这回答了我的问题 =) 我将问题简化为上面的评论。
猜你喜欢
  • 2013-12-16
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 2013-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多