确保 C++ 双精度数是 64 位
在我的 C++ 程序中,我需要从外部字节序列中提取 64 位浮点数。 有什么方法可以确保在编译时双精度数是 64 位吗? 我应该使用其他类型来存储数据吗?
编辑:如果您正在阅读本文,并且实际上正在寻找一种确保以 IEEE 754 格式存储的方法,请查看下面 Adam Rosenfield 的答案。
In my C++ program, I need to pull a 64 bit float from an external byte sequence. Is there some way to ensure, at compile-time, that doubles are 64 bits? Is there some other type I should use to store the data instead?
Edit: If you're reading this and actually looking for a way to ensure storage in the IEEE 754 format, have a look at Adam Rosenfield's answer below.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
在 C99 中,您只需检查预处理器符号 __STDC_IEC_559__ 是否已定义。 如果是,则可以保证
double
将是用 IEEE 754(也称为 IEC 60559)格式表示的 8 字节值。 请参阅 C99 标准,附录 F。不过,我不确定这个符号在 C++ 中是否可用。或者,您可以检查预定义常量
__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++ 风格中都可用。In C99, you can just check if the preprocessor symbol
__STDC_IEC_559__
is defined. If it is, then you are guaranteed that adouble
will be an 8-byte value represented with IEEE 754 (also known as IEC 60559) format. See the C99 standard, Annex F. I'm not sure if this symbol is available in C++, though.Alternatively, you can check the predefined constants
__DBL_DIG__
(should be 15),__DBL_MANT_DIG__
(should be 53),__DBL_MAX_10_EXP__
(should be 308),__DBL_MAX_EXP__
(should be 1024),__DBL_MIN_10_EXP__
(should be -307), and__DBL_MIN_EXP__
(should be -1021). These should be available in all flavors of C and C++.检查 std::numeric_limits
std::numeric_limits< double >::is_iec559
如果您需要知道您的 C++ 实现是否支持标准双精度。 这不仅保证了总位数为 64,而且还保证了 double 内所有字段的大小和位置。Check
std::numeric_limits< double >::is_iec559
if you need to know whether your C++ implementation supports standard doubles. This guarantees not only that the total number of bits is 64, but also the size and position of all fields inside the double.对其他答案的改进(假设字符是 8 位,标准不保证这一点..)。 会像这样:
或者
您可以在
或
中找到定义的 CHAR_BIT。An improvement on the other answers (which assume a char is 8-bits, the standard does not guarantee this..). Would be like this:
or
You can find CHAR_BIT defined in
<limits.h>
or<climits>
.我认为您不应该关注双精度数的“原始大小”(通常是 80 位,而不是 64 位),而应该关注其精度。
感谢 numeric_limits::digits10 这相当容易。
I don't think you should focus on the "raw size" of your double (which is generally 80 bit, not 64 bit), but rather on its precision.
Thanks to numeric_limits::digits10 this is fairly easy.
没有 boost 的解决方案是这样定义数组:
如果 double 不是 64 位,则代码看起来像是
编译时错误。 只需在此说明附近添加适当的注释即可。
The solution without boost is to define the array like so
If the double is not 64 bits then the code will looks like
which is an compile time error. Just put the appropriate comment near this instruction.
您可以使用 Boost 静态断言 来执行此操作。 查看在命名空间范围内使用例子。
You can use the Boost static assertions to do this. Look at the Use at namespace scope example.
请参阅这篇文章了解类似的问题和一个名为CCASSERT。
See this post for a similar problem and a non-boost compile time assertion called CCASSERT.
对于支持 C11 或 C++11 的编译器,我使用类似于 @EvanTeran 的东西:
在 C++11 或更高版本中,
static_assert
是一个关键字。For compilers supporting C11 or C++11, I use something similar to @EvanTeran's:
In C++11 or later,
static_assert
is a keyword.C++23 中缺少固定宽度浮点类型的问题已通过
stdfloat
得到解决:请参阅参考文献 此处。 最新的 GCC 支持此功能。
The lack of fixed-width floating point types has been resolved in C++23 with
stdfloat
:See the reference here. The latest GCC supports this feature.