我需要以人类可读的文本形式表示 IEEE 754-1985 双(64 位)浮点数,条件是可以将文本形式解析回完全相同的(按位)数字。
如果不只打印原始字节,这可能/实用吗?如果是,将不胜感激执行此操作的代码。
我需要以人类可读的文本形式表示 IEEE 754-1985 双(64 位)浮点数,条件是可以将文本形式解析回完全相同的(按位)数字。
如果不只打印原始字节,这可能/实用吗?如果是,将不胜感激执行此操作的代码。
最佳选择:使用 C99 十六进制浮点格式:
printf("%a", someDouble);
double
以这种方式生成的字符串可以用 C99函数转换回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 的小数有效数字。如果您有一个正确舍入的转换例程(大多数 - 不是所有 - 平台都有),这将保证您可以从 double 到 string 来回往返而不会损失任何准确性。
听起来你想要Burger 的算法(PDF):
在自由格式模式下,该算法生成最短的正确舍入输出字符串,该字符串在读回时转换为相同的数字,而不管阅读器在舍入时如何打破平局。
示例源代码(C 和 Scheme)也可用。
这是 Python 3.x 中使用的算法,用于确保float
s 可以在不损失任何准确性的情况下转换为字符串并返回。在 Python 2.x 中,float
s 总是用 17 位有效数字表示,因为:
repr(float)
产生 17 位有效数字,因为事实证明这已经足够了(在大多数机器上),因此eval(repr(x)) == x
对于所有有限浮点数而言x
,但四舍五入到 16 位不足以实现这一点。(来源:http ://docs.python.org/tutorial/floatingpoint.html )
.NET 框架为此提供了往返格式:
string formatted = myDouble.ToString("r");
从文档中:
往返说明符保证转换为字符串的数值将被解析回相同的数值。当使用此说明符格式化数值时,首先使用通用格式对其进行测试,Double 精度为 15 个空格,Single 精度为 7 个空格。如果该值成功解析回相同的数值,则使用通用格式说明符对其进行格式化。但是,如果该值未成功解析回相同的数值,则使用 17 位精度的 Double 和 9 位精度的 Single 来格式化该值。
这种方法当然可以用几乎任何语言重新创建。
是的,它可以完成,尽管实现取决于语言。基本思想只是以足够的精度打印出来。
请注意,相反的情况并非如此:某些可以用十进制精确表示的数字根本无法用二进制表示。