移位后浮点数的位布局如何为我提供某些值?
出于好奇并想了解有关浮点的更多信息,我运行了以下 C 代码:
#include <stdio.h>
int main() {
float a = 1.0 + ((float) (1 << 22));
float b = 1.0 + ((float) (1 << 23));
float c = 1.0 + ((float) (1 << 24));
printf("a = %.6fn", a);
printf("b = %.6fn", b);
printf("c = %.6f", c);
}
结果是:
a = 4194305.000000
b = 8388609.000000
c = 16777216.000000
我对为什么得到这些结果感到困惑。谁能解释为什么 a、b 和 c 的位布局会导致每个值都是它的样子?我是位移和浮点数的新手,如果有明确的解释,将不胜感激。谢谢你。
回答
(1 << 22)
是一个整数值,等于
2^22 = 4194304
然后你通过这样做将它转换为浮点数,(float) (1 << 22)这会给你相同的值
4194304.0
然后你加上 1.0 得到结果 4194305.0
这同样适用于其他情况。
所以这不是关于“浮点数布局”——而是关于整数布局和从整数到浮点数的转换。
但是,您使用的最后一种情况1 << 24有点有趣(并且与浮点格式有关)。
(1 << 24) is 16777216
并且可以转换为相同的浮点值,即
16777216.0
16777216.0
但是当你这样做时
1.0 + 16777216.0
你仍然得到
原因是浮点数的精度有限(即并非所有数字都可以以浮点格式表示)。值 16777217.0 无法以浮点格式显示,因此将 1.0 添加到 16777216.0 仍然会得到 16777216.0
顺便说一句:有几种舍入模式(参见例如https://en.wikipedia.org/wiki/Floating-point_arithmetic#Rounding_modes)所以当无法以浮点格式呈现精确结果时,您需要知道您的系统舍入模式来确定将使用哪个值而不是确切的结果。