编译器之间的浮点二进制布局



我正在清理我们的一些网络代码,同时用更明确的类型(如int32_tuint16_t)替换各种整数类型(int, unsigned short,…),我想知道doublefloat在不同编译器之间的可移植性如何。我们发送的结构类似如下:

struct foo
{
   uint32_t id;
   double dbl;
};
...
// copy_packed() copies packed bytes of integral type and adheres 
// to network byte-ordering
copy_packed(int32_t data, char* buffer, char* end);
copy_packed(uint32_t data, char* buffer, char* end);
copy_packed(uint16_t data, char* buffer, char* end);
...
// overload for structure types calls overloads for its members
void copy_packed(foo &data, char* buffer, char* end)
{
    copy_packed(data.id, buffer); 
    copy_packed(data.id, buffer); 
};

到目前为止,只使用vc++编译的程序,但在GCC上使用该协议是计划的。

现在的问题是:doublefloat可以安全地通过电线发送,即使由不同的编译器解释?问题-据我所知-归结为GCC和vc++是否符合IEEE754。或者提供转换为符合标准的封装的功能?

关于这件事有什么提示吗?

不太好。IEEE没有定义字节顺序,也不是所有的系统都是IEEE。真正的问题是你要有多便携。IEEE基本上通用于现代Unix平台,以及Windows;如果你的可移植性仅限于这些,一般可以输入双关a float转换为uint32_t,将双精度类型转换为uint64_t,并处理输入和这样输出。如果您必须考虑大型机(和可能是嵌入式处理器(我对这些不太熟悉),你会有更多的工作要做;主修上的浮点数大型机甚至不是2进制。

您可以询问编译器:std::numeric_limits<T>::is_iec559将告诉您类型T是否是IEC559 (IEEE754)类型。

这是我见过的关于浮点算术的最好的文章之一。加入到当前IEEE 754实现

目前IEEE 754算法的实现可以分为两种根据他们支持的程度来区分的群体不同硬件中的浮点格式。Extended-based系统,以Intel x86系列处理器为例,提供完整的支持扩展的双精度格式,但只是部分支持支持单精度和双精度:它们提供指令加载或存储数据在单和双精度,转换它即时转换或从扩展的双重格式,他们提供特殊模式(非默认模式),其中算术结果操作被舍入为单精度或双精度,即使它们以扩展双格式保存在寄存器中。(摩托罗拉68000串行处理器将结果四舍五入到精度和范围这些模式中的单格式或双格式。Intel x86及兼容处理器将结果舍入到单精度或双精度格式,但保留与扩展的双格式相同的范围。)单/双系统,包括大多数RISC处理器,提供完整的支持单精度和双精度格式,但不支持ieee兼容扩展双精度格式。IBM POWER体系结构只提供对单精度的部分支持,但是出于本节的目的,我们将其分类为单/双类型系统。)

最新更新