计算最接近的首选十进制结果的double值

时间:2013-05-23 20:09:48

标签: javascript floating-point double

令N(x)为最小有效数字的十进制数字的值 这样x是最接近数字值的double值。

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

E.g:

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

3 个答案:

答案 0 :(得分:2)

作为基线:在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总会产生预期的结果?

答案 1 :(得分:0)

你可以通过乘以然后除以10的幂来转换为'整数':

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

可以从数字的字符串表示中计算出10的适当幂。 @PatriciaShanahan建议寻找重复的0或9。

考虑使用诸如javascript-bignum之类的BigDecimal库。

答案 2 :(得分:0)

你也可以在你的请求翻译的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