对一道C语言习题错误结果的分析
老婆最近在网上学C语言。晚上她跟我说有一章的习题她看不懂,让我帮忙看看。题目在这儿(http://c.biancheng.net/cpp/html/58.html)。
看了许久觉得不对劲,感觉代码有问题,可它的代码实际运行的结果确是和题目答案一致的。最后终于发现题目的代码连同答案本身都是错的。很多人都发现习题的答案是错的并留了评论,可是有没有想过题中错误的结果是如何得出的呢?
题中代码运算逻辑等价于factorial(10) * 10,即10^10 * 10,又即100000000000(1后面跟11个0)。可为什么程序跑出来的结果却是1215752192呢?
我们先来看factorial函数。由代码逻辑可得factorial(10)=10^10。可实际运行结果如下:
当i=1:
result=10
当i=2:
result=100
当i=3:
result=1000
…
当i=8:
result=100000000
当i=9:
result=1000000000
当i=10:
result=1410065408
为什么i=10时,result=1410065408呢? 因为10^10超出了long数据类型(占4字节内存空间)所能表达数字的范围,溢出了。
为了证实这一猜测,我们可以用程序员计算器查看10^10的二进制表示,即:10 0101 0100 0000 1011 1110 0100 0000 1000。取其后32位,即0101 0100 0000 1011 1110 0100 0000 1000,以十进制表示可得1410065408。由此证明,1410065408是10^10以long数据类型表示的结果。同样可以证明,题中代码运行结果1215752192也是10^11以long数据类型表示溢出后的结果。