在C中表示浮动
我试图用这个代码理解C中的浮点表示( float
和int
在我的机器上都是4个字节):
int x = 3; float y = *(float*) &x; printf("%d %e \n", x, y);
我们知道x的二进制表示如下
00000000000000000000000000000011
因此,我希望y表示如下
-
符号位(左起第一位)=
0
-
指数(左起第2-9位)=
0
-
尾数(位10-32):
1 + 2^(-22)+2^(-23)
导致y = (-1)^0 * 2^(0-127) * (1+2^(-22) + 2^(-23)) = 5.87747E-39
然而,我的程序打印出来
3 4.203895e-45
也就是说,y的值为4.203895e-45
而不是我预期的5.87747E-39
。 为什么会这样呢? 我究竟做错了什么?
PS我也直接从gdb打印了这些值,因此printf命令没有问题。
指数字段为全0的IEEE浮点数被“非规范化”。 这意味着尾数前面的隐含1不再有效。 这允许表示真正的小数字。 有关更多说明,请参阅此维基百科文章 。 在您的示例中,结果将是3 * 2 ^ -149
指数中的-127保留用于非规范化数字。 您的计算是针对标准化数字,而您的浮点数是非规范化浮点数。
非规范化数字使用类似方法计算,但是:
- 指数是-126
- 不再假设隐式前导位
所以这意味着计算是:
(-1)**0*2**(-126)*(2**(-22)+2**(-23)) = 4.2038953929744512e-45
以上是python,其中**
表示与^
相同
详细描述http://en.wikipedia.org/wiki/IEEE_754-2008该标准假设你移动左尾数直到隐藏第一个含义位(增加指数)。 在你的情况下,你有表达式1 + 2 ^( – 23) – 然后你得到正确答案4.9..E-32