在我的C ++程序中,我需要从外部字节序列中提取64位浮点数。有没有办法在编译时确保double是64位?我还应该使用其他某种类型来存储数据吗?
编辑:如果您正在阅读此书,并且实际上正在寻找一种确保以IEEE 754格式存储的方法,请查看下面的亚当·罗森菲尔德的回答。
对其他答案的改进(假设一个char是8位,标准不保证这一点。)。会是这样的:
char a[sizeof(double) * CHAR_BIT == 64];
或
BOOST_STATIC_ASSERT(sizeof(double) * CHAR_BIT == 64);
您可以找到在<limits.h>
或<climits>
中定义的CHAR_BIT。
在C99中,您可以仅检查预处理器符号__STDC_IEC_559__
是否已定义。如果是这样,则可以保证double
将是一个以IEEE 754(也称为IEC 60559)格式表示的8字节值。请参阅C99标准附录F。不过,我不确定此符号是否在C ++中可用。
#ifndef __STDC_IEC_559__
#error "Requires IEEE 754 floating point!"
#endif
或者,您可以检查预定义常量__DBL_DIG__
(应为15),__DBL_MANT_DIG__
(应为53),__DBL_MAX_10_EXP__
(应为308),__DBL_MAX_EXP__
(应为1024),__DBL_MIN_10_EXP__
(应该是-307)和__DBL_MIN_EXP__
(应该是-1021)。这些应该可以使用C和C ++的所有版本。
如果需要了解C ++实现是否支持标准双精度,请检查std::numeric_limits< double >::is_iec559
。这不仅保证了总位数为64,而且还保证了double中所有字段的大小和位置。
我认为您不应该专注于双精度的“原始大小”(通常为80位,而不是64位),而是要关注其精度。
多亏了numeric_limits :: digits10,这非常容易。
您可以使用Boost static assertions执行此操作。查看Use at namespace scope示例。
没有提升的解决方案是像这样定义数组
char a[ 8 == sizeof(double) ];
如果双精度数不是64位,那么代码将看起来像
char a[0];
这是编译时错误。只需在此说明附近加上适当的注释即可。
有关类似问题和称为CCASSERT的非增强编译时断言,请参见this post。>>