IEEE“双精度”的精确文本表示

发布于 2024-08-25 15:45:58 字数 136 浏览 2 评论 0原文

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

如果不打印原始字节,这是否可能/实用? 如果是,那么执行此操作的代码将不胜感激。

I need to represent an IEEE 754-1985 double (64-bit) floating point number in a human-readable textual form, with the condition that the textual form can be parsed back into exactly the same (bit-wise) number.

Is this possible/practical to do without just printing the raw bytes?
If yes, code to do this would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

帅气尐潴 2024-09-01 15:45:58

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

printf("%a", someDouble);

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

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

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

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

Best option: Use the C99 hexadecimal floating point format:

printf("%a", someDouble);

Strings produced this way can be converted back into double with the C99 strtod( ) function, and also with the scanf( ) functions. Several other languages also support this format. Some examples:

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

The hexadecimal format has the advantage that all representations are exact. Thus, converting the string back into floating-point will always give the original number, even if someone changes the rounding mode in which the conversion is performed. This is not true for inexact formats.

If you don't want to use the hexadecimal format for whatever reason, and are willing to assume that the rounding mode will always be round to nearest (the default), then you can get away with formatting your data as decimals with at least 17 significant digits. If you have a correctly rounded conversion routine (most -- not all -- platforms do), this will guarantee that you can do a round trip from double to string and back without any loss of accuracy.

冷月断魂刀 2024-09-01 15:45:58

听起来像你想要的 Burger 算法(PDF):

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

示例源代码(在 C 和Scheme 中)也可用。

这是 Python 3.x 中使用的算法,用于确保浮点型可以在字符串和字符串之间相互转换,而不会损失任何准确性。在 Python 2.x 中,float 始终用 17 位有效数字表示,因为:

repr(float) 产生 17 个有效数字,因为事实证明这已经足够了(在大多数机器上),因此 eval(repr(x)) == x 恰好适用于所有有限浮点数 x,但四舍五入到 16 位不足以证明这一点。
(来源:http://docs.python.org/tutorial/floatingpoint.html

Sound like you want Burger's algorithm (PDF):

In free-format mode the algorithm generates the
shortest correctly rounded output string that converts to
the same number when read back in regardless of how the
reader breaks ties when rounding.

Sample source code (in C and Scheme) is available as well.

This is the algorithm used in Python 3.x to ensure floats can be converted to strings and back without any loss of accuracy. In Python 2.x, floats were always represented with 17 significant digits because:

repr(float) produces 17 significant digits because it turns out that’s enough (on most machines) so that eval(repr(x)) == x exactly for all finite floats x, but rounding to 16 digits is not enough to make that true.
(Source: http://docs.python.org/tutorial/floatingpoint.html)

仙女山的月亮 2024-09-01 15:45:58

.NET 框架对此有一个往返格式:

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

来自文档:


往返说明符保证
数值转换为字符串
将被解析回相同的
数值。当一个数值是
使用此说明符格式化,它是
首先使用通用格式进行测试,
精度为 15 个空格
双精度和 7 个空格的精度
单身的。如果取值成功
解析回相同的数值,
它使用通用格式
格式说明符。然而,如果
值未成功解析回来
为相同的数值,则
值的格式使用 17 位数字
Double 和 9 位数字的精度
单精度。

当然可以用大多数任何语言重新创建该方法。

The .NET framework has a round-trip format for this:

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

From the documentation:

The
round-trip specifier guarantees that a
numeric value converted to a string
will be parsed back into the same
numeric value. When a numeric value is
formatted using this specifier, it is
first tested using the general format,
with 15 spaces of precision for a
Double and 7 spaces of precision for a
Single. If the value is successfully
parsed back to the same numeric value,
it is formatted using the general
format specifier. However, if the
value is not successfully parsed back
to the same numeric value, then the
value is formatted using 17 digits of
precision for a Double and 9 digits of
precision for a Single.

This method could of course be recreated in most any language.

佼人 2024-09-01 15:45:58

是的,这是可以做到的,尽管实现取决于语言。基本思想就是以足够的精度打印出来。

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

Yes, it can be done, though the implementation depends on the language. The basic idea is simply to print it out with sufficient precision.

Note that the reverse is not true though: some numbers that can be represented precisely in decimal simply cannot be represented in binary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文