2

Let N(x) be the value of the decimal numeral with the fewest significant digits such that x is the double value nearest the value of the numeral.

Given double values a and b, how can we compute the double value nearest N(b)-N(a)?

E.g.:

  • If a and b are the double values nearest .2 and .3,
    • the desired result is the double value nearest .1,
      • 0.1000000000000000055511151231257827021181583404541015625,
    • rather than than the result of directly subtracting a and b,
      • 0.09999999999999997779553950749686919152736663818359375.
4

3 回答 3

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总是会产生预期的结果?
于 2013-05-24T00:55:13.197 回答
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

于 2013-05-26T17:53:53.623 回答
0

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

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

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

考虑使用 BigDecimal 库,例如javascript-bignum

于 2013-05-23T21:33:19.077 回答