IEEE 754浮点格式是跨平台定义的吗?在位格式和endianness方面?
我愿意在我的代码中添加以下内容(作为初始版本):
static_assert(std::numeric_limits<float>::is_iec559, "Only support IEC 559 (IEEE 754) float");
static_assert(sizeof(float) * CHAR_BIT == 32, "Only support float => Single Precision IEC 559 (IEEE 754)");
static_assert(std::numeric_limits<double>::is_iec559, "Only support IEC 559 (IEEE 754) double");
static_assert(sizeof(float) * CHAR_BIT == 64, "Only support double => Double Precision IEC 559 (IEEE 754)");
static_assert(std::numeric_limits<long double>::is_iec559, "Only support IEC 559 (IEEE 754) long double");
static_assert(sizeof(float) * CHAR_BIT == 128, "Only support long double => Exteneded Precision IEC 559 (IEEE 754)");
// More asserts if required.
// I noticed my current system has a sizeof(long double) => 128
// But numeric_limits<long double>::digits => 63
// So we are not storing quad precision floats only extended.如果我写我的浮点/双/长双二进制格式,这些可以在系统之间传输,而无需进一步解释。伊..。
void write(std::ostream& stream, double value)
{
stream.write(reinterpret_cast<char const*>(&value), 8);
}
....
double read(std::istream& stream)
{
double value;
stream.read(reinterpret_cast<char*>(&value), 8);
return value;
}还是我需要将整型组件分解为整数组件进行传输(正如this answer所建议的那样):
这里的区别是,我愿意将我支持的表示限制在IEEE-754上,这基本上解决了浮点值的二进制存储问题,还是需要采取进一步的步骤?
注意:对于不符合标准的平台(当我发现它们时),我愿意为代码设置特例,以便它们将IEEE-754读入本地表示。但是我想知道bit/endian是否有足够好的定义好的跨平台来支持存储/传输。
发布于 2015-02-20 20:00:46
位格式是很好的定义,但并不是所有的机器都是小终端.IEEE标准也不要求浮点数是特定的端点.您可以运行以下程序来查看double 42.0的字节模式
#include <stdio.h>
#include <numeric>
#include <limits>
using namespace std;
int main() {
double d = 42;
printf("%i\n", std::numeric_limits<double>::is_iec559);
for (char *c = (char *)&d; c != (char *)(&d+1); c++) {
printf("%02hhx ", *c);
}
printf("\n");
}在一台使用g++ 3.4.5的未维护的旧Sun机器上,这将打印
1
40 45 00 00 00 00 00 00在运行一个更新的g++的g++机器上:
1
00 00 00 00 00 00 45 40发布于 2015-02-20 09:36:36
首先,您可能需要更改代码,以便它正确地检查类型大小.
static_assert(std::numeric_limits<float>::is_iec559, "Only support IEC 559 (IEEE 754) float");
static_assert(sizeof(float) * CHAR_BIT == 32, "Only support float => Single Precision IEC 559 (IEEE 754)");
static_assert(std::numeric_limits<double>::is_iec559, "Only support IEC 559 (IEEE 754) double");
static_assert(sizeof(double) * CHAR_BIT == 64, "Only support double => Double Precision IEC 559 (IEEE 754)");
static_assert(std::numeric_limits<long double>::is_iec559, "Only support IEC 559 (IEEE 754) long double");
static_assert(sizeof(long double) * CHAR_BIT == 128, "Only support long double => Exteneded Precision IEC 559 (IEEE 754)");问题是,IEEE-754不需要长双128位长.根据编译器和平台的不同,这种类型的长度可能会有所不同。但是,它指定了binary128,编译器可能支持,也可能不支持,具体取决于平台和实现(gcc有一个非标准的__float128类型)。标准只要求长倍至少和双倍一样精确,通常是80位长(gcc)或64 (VS)。
如果将受支持的表示限制为IEEE-754,则不应遇到任何问题。
发布于 2016-08-27 05:36:49
若要读写IEEE 754可移植,请使用这些例程。如果平台不是IEEE 754,您可能会丢失几个比特,但仍然会得到最接近的表示。
https://stackoverflow.com/questions/28625340
复制相似问题