我有兴趣了解 C++ 在基于 Intel 的系统上使用的单类型或双类型的二进制格式。
在数据可能需要由另一个系统(即文件或网络)读取或写入的情况下,我避免使用浮点数。我确实意识到我可以使用定点数,并且定点更准确,但我有兴趣了解浮点格式。
我有兴趣了解 C++ 在基于 Intel 的系统上使用的单类型或双类型的二进制格式。
在数据可能需要由另一个系统(即文件或网络)读取或写入的情况下,我避免使用浮点数。我确实意识到我可以使用定点数,并且定点更准确,但我有兴趣了解浮点格式。
维基百科有一个合理的总结——见http://en.wikipedia.org/wiki/IEEE_754。
Burt 如果你想在系统之间传输数字,你应该避免以二进制格式进行。要么使用 CORBA(只是开玩笑,伙计们)、Tibco 等中间件,要么使用旧的最喜欢的文本表示。
这应该可以帮助您入门:http ://docs.sun.com/source/806-3568/ncg_goldberg.html 。(:
英特尔的表示符合 IEEE 754。您可以在http://download.intel.com/technology/itj/q41999/pdf/ia64fpbf.pdf找到详细信息。
浮点格式由处理器决定,而不是语言或编译器。如今,几乎所有处理器(包括所有英特尔台式机)要么没有浮点单元,要么有一个符合 IEEE 754 的浮点单元。你会得到两种或三种不同的大小(带有 SSE 的英特尔提供 32、64 和 80 位),每个一个有符号位、指数和有效数。表示的数字通常由以下公式给出:
sign * (2**(E-k)) * (1 + S / (2**k'))
其中 k' 是有效数字中的位数, k 是指数中间范围附近的常数。零(正负零)以及无穷大和其他“非数字”(NaN)值有特殊的表示。
有明确的怪癖;例如,分数 1/10 不能完全表示为二进制 IEEE 标准浮点数。出于这个原因,IEEE 标准也提供了十进制表示,但这主要用于手持计算器而不是通用计算机。
推荐阅读:David Golberg 的What Every Computer Scientist Should Know About Floating-Point Arithmetic
正如其他海报所指出的,有大量关于每个现代处理器使用的 IEEE 格式的信息,但这不是您的问题会出现的地方。
您可以依赖任何使用 IEEE 格式的现代系统,但您需要注意字节顺序。在 Wikipedia(或其他地方)上查找“endianness”。英特尔系统是小端的,很多 RISC 处理器都是大端的。两者之间的交换是微不足道的,但你需要知道你有什么类型。
传统上,人们使用大端格式进行传输。有时人们会包含一个标头,指示他们正在使用的字节顺序。
如果您想要绝对的可移植性,最简单的方法是使用文本表示。但是,如果您想捕获完整的精度,这对于浮点数可能会变得非常冗长。0.1234567890123456e+123。
请注意,十进制浮点常量可能会在不同系统上转换为不同的浮点二进制值(即使在同一系统上使用不同的编译器)。差异会很小——对于双倍来说可能只有 2^-54 大——但仍然是一个差异。
如果您想在任何平台上保证相同的浮点二进制值,请使用十六进制常量。