第一篇博文,写个简单的但是有点意思的——C语言中浮点数以整型输出会得到什么?

 https://zhidao.baidu.com/question/1801972543144214347

这是百度知道上的一个问题,链接在上面。问的是C语言中printf("%d, 4+4.2");为什么不是输出8?

刚看到这个问题的时候有点懵,总感觉应该是输出8。我是这样分析的:4+4.2结果是8.2,这是个double类型,然后以“%d”格式化输出时自动转换成整型也就是8。所以应该就是8啊。然后自己写了段代码测试了一下,结果。。。。。。。被打脸了。输出是这样的:

这个结果是怎么得到的?为什么8.2按%d的格式输出会得到一个这么数字?

仔细想了一下,应该和浮点数的存储方式有关。整型是以二进制补码的形式存储的,可以精确表示,存储的就是数值。但是浮点数不一样,浮点数是以编码的形式存储的,不是直接存储数值,而且有精度问题,浮点数是以“符号位+阶码+尾数”的形式存储。float类型符号位占1位,阶码占8位,尾数占23位,总共32位;double类型符号位占1位,阶码占11位,尾数占52位。所以说,如果printf在输出时,因为格式字符是“%d”,所以它会以整型的方式去解析浮点数的编码。将浮点数编码直接当做二进制补码来计算数值,就会出现上面的结果。

     既然确定了思路,那就朝这个方向来分析。首先将8.2以二进制编码表示出来:0 000 1000 0010 000 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0第1个”0“表示符号,在这里是正数。接下来的11位表示阶码,这里表示130(3+127)。后面的52位表示尾数。在这里我犯了一个错误,因为系统和编译器都是64位的,所以我以为int和double一样,也是占64位。所以如果double以整型输出,就是上面的二进制形式以整数补码形式,转换成10进制是1717986918吗?很遗憾,并不是,而是:585580541548848742

    这个值远比输出的要大的多。开始我以为是我手动计算的8.2的编码不对,又计算了几遍之后发现还是一样,而且专门去找了一个验证程序(可以输出变量值的二进制形式的一段代码)验证也没问题。那么问题在哪呢?然后意识到可能是int和double所占的位数不一样。用程序验证一下果然如此:

  

   由上图可知:int和float占4个字节即32位,double占8个字节即64位。如果double以int类型输出的话,会产生截断,只取低32位输出,即输出的是“011 0011 0011 0011 0011 0011 0011 0011 0”的值。这个二进制表示的值转换成十进制就是1717986918

原文地址:https://www.cnblogs.com/zhang-15-506/p/6973165.html