【问题标题】:How are binary floating points (IEEE 754) converted to decimal (i.e. to string)?二进制浮点(IEEE 754)如何转换为十进制(即字符串)?
【发布时间】:2019-12-01 19:52:23
【问题描述】:

这可能是一个非常愚蠢的问题,但我已经搜索了一整天,我无法得到答案......

假设我有一个双精度浮点文字:5.21。在 Java 中调用 Double.toString( 5.21 ) 会产生字符串 "5.21"

现在,假设我们有 Java,但没有 toStringvalueOf,我也不能使用 String.format 或仅通过连接对其进行格式化。假设我只有二进制表示,我如何将我的数字转换为字符串?

更具体地说,Double.toStringdtoa 究竟是如何工作的:我如何编写自己的 toString/dtoa 函数(假设我们正在处理 IEEE 754 双精度浮点数)?

【问题讨论】:

  • 这可能是重复的,但我在 StackOverflow 上的任何地方都找不到它...
  • "exactly" -- 这是一个巨大的要求。唯一的答案就是研究代码。
  • 我确实研究了代码,但它最终变成了一些反编译的、半模糊的代码,我试图理解但我无法...

标签: floating-point precision tostring ieee-754


【解决方案1】:

这是一个非常棘手的问题,尤其是要高效准确地完成。有两个主要问题:

  1. 每个二进制浮点数代表一组以它为中心的“实数”,这个区间的大小取决于值本身。 (一般情况下,值越大,代表的区间越大。)“正确”转换通常定义为在该集合中选择一个元素,其中将包含许多十进制浮点数。

  2. 在“正确”选项中,通常需要“最佳”输出,即十进制位数最少的字符串。

因此,与任何浮点数一样,即使对于像这样听起来无害的问题,兔子洞也会变得很深。一个好的算法在上述意义上是正确的和最优的;这使得设计一种高效的产品变得很棘手。

但你很幸运。这也是一个很好研究的问题:

令人惊讶的是,上面的第一篇论文和最后一篇论文相差 20 年,证明了问题的难度。如果您想出更好的技术,那肯定是可发布的结果。尽情享受吧!

【讨论】:

  • "并非 IEEE-754 中描述的每个二进制浮点数都有有限的十进制表示" - 我想不出那会是什么:两个的连续幂 (正或负)总是有有限的十进制表示(即使epsilonfinite),所以我看不出它们的组合如何不会。 (也许我错过了什么)
  • @WaiHaLee 好点。我应该反过来说:并非每个十进制浮点数都可以用二进制浮点数准确表示。 (0.1 是典型的例子。)当然这不是 OP 所要求的。编辑澄清并添加了另一个参考。
【解决方案2】:

如何编写自己的 toString/dtoa 函数 (?)

每个基于有限二进制的浮点数都有精确的十进制表示。考虑每个这样的浮点数是 2 的各种幂的总和,并且 2 的每个幂本身都是十进制的:例如:256、2、0.25、0.0625。

Function to print a double - exactly 通过仔细提取浮点的有效数字作为整数和指数进行转换。然后它是循环和 *2 或 /2 根据需要的简单情况。这提供了一个准确的答案。

通常四舍五入的结果是可以接受的。这变得更加复杂,但速度更快。

【讨论】:

  • 这会做一些事情,但我不认为这是解决问题的最佳和最佳解决方案......
  • @RgSW 这取决于编码目标。你想要一个精确的转换还是一个近似的转换?许多案例只需要一个近似值就足够了,有些则不然。
猜你喜欢
  • 2014-06-18
  • 2016-04-02
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 2017-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多