IEEE“双”的精确文本表示

时间:2010-03-19 21:48:10

标签: floating-point floating-accuracy ieee-754

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

这是否可行/实用而不仅仅打印原始字节? 如果是的话,我们非常感谢能够做到这一点的代码。

4 个答案:

答案 0 :(得分:11)

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

printf("%a", someDouble);

以这种方式生成的字符串可以使用C99 double函数以及strtod( )函数转换回scanf( )。其他几种语言也支持这种格式。一些例子:

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

十六进制格式的优点是所有表示都是完全。因此,将字符串转换回浮点将始终给出原始数字,即使有人更改了执行转换的舍入模式。对于不精确的格式,情况并非如此。

如果您不想出于任何原因使用十六进制格式,并且愿意假设舍入模式将始终舍入到最接近(默认值),那么您可以将数据格式化为小数至少17位有效数字。如果你有一个正确的舍入转换例程(大多数 - 不是所有 - 平台都这样做),这将保证你可以从双线到回线进行往返,而不会有任何精度损失。

答案 1 :(得分:5)

听起来像你想要Burger's algorithm(PDF):

  

在自由格式模式下,算法会生成   转换为的最短正确舍入的输出字符串   无论如何回读时读取相同的数字   读者在四舍五入时打破了关系。

Sample source code(在C和Scheme中)也可用。

这是Python 3.x中使用的算法,以确保float可以转换为字符串并返回而不会丢失任何准确性。在Python 2.x中,float s始终用17位有效数字表示,因为:

  

repr(float)产生17位有效数字,因为事实证明它足够(在大多数机器上),因此eval(repr(x)) == x完全适用于所有有限浮点数x,但舍入到16位数不足以说实话。   (来源:http://docs.python.org/tutorial/floatingpoint.html

答案 2 :(得分:2)

.NET框架具有以下格式的往返格式:

string formatted = myDouble.ToString("r");

来自文档:

  

在   往返说明符保证a   数值转换为字符串   将被解析回相同的   数值。当数值是   使用此说明符格式化,它是   首先使用一般格式测试,   有15个精度空间   双精度和7精度空间   单。如果值成功   解析回相同的数值,   它使用常规格式化   格式说明符。但是,如果   值未成功解析回来   到相同的数值,然后   使用17位数格式化值   双精度和9位数的精度   单精度。

这种方法当然可以用大多数语言重新创建。

答案 3 :(得分:1)

是的,它可以完成,但实现取决于语言。基本思路就是以足够的精度打印出来。

请注意,反向为真:一些可以精确用十进制表示的数字根本无法用二进制表示。