IEEE中“double”的精确文本表示

7

我需要以人类可读的文本形式表示IEEE 754-1985双精度(64位)浮点数,并确保文本形式可以解析回完全相同(按位)的数字。

如果不仅仅是打印原始字节,是否可能/实用?如果是,则非常感谢提供此代码。


1
语言很重要。你在用什么编程语言?如果问题中没有提到具体的编程语言,那么提供代码就有点不可能了。 - S.Lott
我没有提到语言(D)是因为它相对较少使用,所以我计划将任何语言编写的算法重写为D。 - Vladimir Panteleev
NaN、-0.0、inf、-inf 怎么处理?目前的答案似乎没有考虑到这些。 - Frans Lundberg
4个回答

12

最佳选项:使用 C99 十六进制浮点数格式:

printf("%a", someDouble);

使用这种方式生成的字符串可以通过C99标准下的strtod()函数,以及scanf()函数转换回double类型。其他一些编程语言也支持此格式。以下是一些示例:

decimal number    %a format     meaning
--------------------------------------------
2.0               0x1.0p1       1.0 * 2^1
0.75              0x1.8p-1      1.5 * 2^-1

十六进制格式的优点在于所有表示都是准确的。 因此,即使有人更改了转换执行时使用的舍入模式,将字符串转换回浮点数也始终会给出原始数字。 对于不精确的格式,这并不正确。

如果由于某种原因您不想使用十六进制格式,并且愿意假设舍入模式始终为四舍五入(默认值),则可以将数据格式化为至少具有 17 个有效数字的十进制数。 如果您拥有一个正确舍入的转换例程(大多数 - 不是所有 - 平台都有),则这将保证您可以进行从双精度到字符串再到双精度的完整转换而不会失去精度。


6

看起来你需要 Burger算法(PDF):

在自由格式模式下,该算法生成最短的正确舍入输出字符串,无论读者在四舍五入时如何打破平局,该字符串都可以转换为相同的数字。

示例源代码(使用C和Scheme编写)也可用。

这是Python 3.x中用于确保float可以在不丢失精度的情况下转换为字符串并返回的算法。在Python 2.x中,float始终使用17个有效数字进行表示,因为:

repr(float) 生成17个有效数字,因为在大多数机器上,这足以使得对于所有有限浮点数xeval(repr(x)) == x完全成立,但是将其四舍五入到16位小数不足以使其成立。 (来源:http://docs.python.org/tutorial/floatingpoint.html


3
.NET框架有一个往返格式来实现这个功能:
string formatted = myDouble.ToString("r");

从文档中可以得到以下信息:

往返格式说明符保证将数字值转换为字符串后,能够被解析回同一数字值。当使用此说明符格式化数字值时,首先会使用常规格式进行测试,对于 Double 类型,精度为 15 个空格,对于 Single 类型,精度为 7 个空格。如果成功将值解析回相同的数字值,则使用常规格式说明符对其进行格式化。但是,如果无法成功将值解析回相同的数字值,则使用 Double 类型的 17 位数字精度和 Single 类型的 9 位数字精度来格式化该值。

当然,这种方法在大多数语言中都可以实现。


1

是的,可以做到,但实现取决于语言。基本想法只是使用足够的精度将其打印出来。

请注意,反之则不然:一些在十进制中可以精确表示的数字,在二进制中可能无法表示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接