【问题标题】:Compute the double value nearest preferred decimal result计算最接近首选十进制结果的双精度值
【发布时间】:2013-05-23 20:09:47
【问题描述】:

令 N(x) 为有效数字最少的十进制数字的值 使得 x 是最接近数字值的double 值。

给定 double 值 a 和 b,我们如何计算最接近 N(b)-N(a) 的 double 值?

例如:

  • 如果 a 和 b 是最接近 .2 和 .3 的 double 值,
    • 所需的结果是最接近 0.1 的 double 值,
      • 0.1000000000000000055511151231257827021181583404541015625,
    • 而不是直接将a和b相减的结果,
      • 0.09999999999999997779553950749686919152736663818359375。

【问题讨论】:

  • 通过乘以除以 10 的幂转换为“整数”:(10*.3 - 10*.2) / 10 == 0.1
  • @tom: 十的哪个幂?具体来说,给定 a 和 b,你如何计算使用 10 的哪个幂?
  • @EricPostpischil 也许转换为字符串并寻找最长的连续9或0序列???

标签: javascript floating-point double


【解决方案1】:

作为基线:在 Java 中,Double.toString() 提供了问题中描述的 N(x) 函数,将其值作为数字返回。可以取 a 和 b 的字符串,用小学方法减去它们,然后将结果字符串转换为 double

这表明使用现有的库例程解决问题是非常可行的。这留下了改进解决方案的任务。我建议探索:

  • 是否有函数 D(x) 可以返回 N(x) 中描述的数字的小数位后有效位数?如果是这样,我们能否将 a 和 b 乘以由 D(a) 和 D(b) 确定的 10 次方,根据需要四舍五入以产生正确的整数结果(对于它们可表示为 double 值的情况),减去并除以十次方?
  • 我们能否建立标准,让b-a 或一些简单的表达式可以快速四舍五入到接近十进制的数字,绕过更难的情况所需的代码?例如,我们能否证明对于一定范围内的数字,(round(10000*b)-round(10000*a))/10000 总是产生期望的结果?

【讨论】:

    【解决方案2】:

    您可以通过乘以再除以十的幂来转换为“整数”:

    (10*.3 - 10*.2)/10 == 0.1000000000000000055511151231257827021181583404541015625
    

    也许可以从数字的字符串表示中算出适当的十次方。 @PatriciaShanahan 建议寻找重复的 0 或 9。

    考虑改用 javascript-bignum 等 BigDecimal 库。

    【讨论】:

    • 大多数接近数字的double 值(例如 3.14)的位设置在有效数字的低位或附近,因此在遇到舍入错误之前,它们不能乘以超过 10 的小幂。例如,10*3.14 的值不是3.14 的十倍。
    • 您可以使用Math.pow(10,Math.max ("".split.call(a,".")[1].length,"".split.call(b,".")[1].length)) 来获得所需的 10 次方。关键是,是否有证据证明这总是会产生所需的结果,或者是否存在 任何 2个值,其中不适用?
    【解决方案3】:

    您也可以在 Smalltalk Pharo 2.0 中查询您的请求在哪里翻译:

    ^(b asMinimalDecimalFraction - a asMinimalDecimalFraction) asFloat
    

    可以在 code.google.com/p/pharo/issues 找到问题 4957 的附件 - 唉,死链接,而且新的 bugtracker 需要登录...

    https://pharo.fogbugz.com/f/cases/5000/Let-asScaledDecimal-use-the-right-number-of-decimals

    源码也在github上,目前:

    https://github.com/pharo-project/pharo-core/blob/6.0/Kernel.package/Float.class/instance/printing/asMinimalDecimalFraction.st

    算法基于:

    Robert G. Burger 和 R. Kent Dybvig
    快速准确地打印浮点数
    ACM SIGPLAN 1996 编程语言设计与实现会议
    1996 年 6 月。
    http://www.cs.indiana.edu/~dyb/pubs/FP-Printing-PLDI96.pdf

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多