二进制浮点数 (IEEE 754) 如何转换为十进制(即字符串)?

How are binary floating points (IEEE 754) converted to decimal (i.e. to string)?

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

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

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

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

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

  1. 每个二进制浮点数代表一组以它为中心的"real"个数字,这个区间的大小取决于值本身。 (一般来说,值越大代表的区间越大。)"correct"转换通常定义为在这个集合中选取一个元素,其中会包含很多小数浮点数。

  2. 在 "correct" 选项中,通常需要 "optimal" 输出,即小数位数最少的字符串。

因此,对于任何浮点数,即使是像这样看似无伤大雅的问题,兔子洞也会变得很深。一个好的算法在上述意义上既是正确的又是最优的;这使得设计一个同样高效的产品变得棘手。

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

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

how can I write my own toString/dtoa function (?)

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

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

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