【发布时间】:2015-04-21 22:00:42
【问题描述】:
IEEE 754 浮点格式是否跨平台定义良好?在位格式和字节序方面?
我愿意在我的代码中添加以下内容(对于初始版本):
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.
如果我以二进制格式编写我的 float/double/long double 可以在系统之间传输而无需进一步解释。即...
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 读/写为本地表示。但我想知道位/字节序是否定义得足够好,可以跨平台支持存储/传输。
【问题讨论】:
-
未指定字节顺序。因此,您需要将所有内容都转换为大端或小端。
-
@tmyklebu:你有我能读到的参考资料吗?我与之交谈的其他人都说是(尽管他们也没有向我展示标准)。
-
我很困惑。您想要一个说明另一个参考没有说明什么的参考?
-
@tmyklebu:很抱歉出现了错误(我也会犯“除非明确指定我们不能假设”的错误,所以目前我认为我必须考虑到这一点)。但是我想了解您为什么这么说(因为我一直听说字节序不是一个因素),这就是我问这个问题的原因。我想获得一些明确的参考,说明我如何期望在内存中看到这一点。如您所见,目前唯一的答案是暗示这不是问题(并且没有反对票,尽管 1 票赞成也不是响亮的支持)。
-
好吧,我这么说是因为在 SPARC 上打印出
double42.0的字节会得到40 45 00 00 00 00 00 00,而在 x86_64 机器上打印会得到00 00 00 00 00 00 45 40。这些是不同的,因为 SPARC 是 big-endian 而 x86_64 是 little-endian。
标签: c++ floating-point double ieee-754