这是一块非常简单的Java代码片段:

public class HelloWorld{

    public static void main(String []args){

        int product = 1;

        for (int i = 10; i <= 99; i++) {

            product *= i;

        }

        System.out.println(product);

    }

}

为什么得出的结果是0呢?

问题现象

蛋疼的同学可能会发现这个程序执行的规律:

1 * 10 = 10

10 * 11 = 110

110 * 12 = 1320

1320 * 13 = 17160

17160 * 14 = 240240

240240 * 15 = 3603600

3603600 * 16 = 57657600

57657600 * 17 = 980179200

……

-1342177280 * 40 = -2147483648

-2147483648 * 41 = -2147483648

-2147483648 * 42 = 0

0 * 43 = 0

0 * 44 = 0

……

0 * 97 = 0

0 * 98 = 0

程序从42开始就已经输出0,所以42以后的数字相乘的结果就显而易见了。从结果中发现,乘积的符号已一种难以理解的方式变换着,表明乘积已经溢出了,同时也说明Java并不会理会整数的上下溢出。

问题解答

请记住Java的int类型是32位的有符号二进制补码表示的数字类型(译者注:64为jdk同样如此)。这是每一步乘法在计算机内部所做的操作:



标注(1)是实际十进制结果。

标注(2)十六进制以及十进制的内部表示结果,int类型只会存储低32位的数据。

标注(3)是标注(2)的补码形式。

如果你好奇0从哪里来,请仔细看上方2进制表示的结果。细心的同学会注意到:

任何一个数与偶数相乘得偶数。

偶数与偶数相乘,会将2进制位整体左移,0从右边填补空位。

偶数与奇数相乘,不会改变最右方0的数量。

当乘法执行的足够多次时,右方的0位会越来越多。最终,连续乘到42时,乘积的2进制表示的低32位全是0,所以int将会是0。

问题扩展

既然知道了问题的原因,我们换一种变量来做同样的操作,以byte为例。

Java的byte变量是8位的有符号数,同样也是补码表示。从上方结果表格看出,连续从10乘到16时,2进制结果的低8位全都是0,所以此时的byte变量是0。而连续乘到15时,低8位是10010000,还记得怎么由补码求原码吗?很简单, 符号位不变,其余位取反加1,得出11110000,既-112,感兴趣的朋友请在自己机器上验证结果。有兴趣的同学可以加入技术讨论群:626267345

最新文章

  1. Kafka简介
  2. Java中长度为0的数组与null的区别
  3. PAT乙级 1008. 数组元素循环右移问题 (20)
  4. android 插件化 模块化开发
  5. cd /d %~dp0
  6. Apache Spark BlinkDB
  7. WinAPI——SetWindowsHookEx设置钩子说明
  8. 跑马灯js
  9. (2)入门指南——(2)jQuery可以做什么(What jQuery does)
  10. php基础知识掌握——四种界定符
  11. 如何实现一个malloc(转)
  12. js-刮刮卡效果,由jquery-eraser源码改的vue组件
  13. Python 限制线程的最大数量(Semaphore)
  14. linux 使用笔记1
  15. PCA(主成分分析)和LDA详解
  16. InnoDB 锁
  17. Python入门基础学习 二
  18. ACE中TASK架构简介及简单应用
  19. android studio Cannot resolve symbol &#39;@drawable/XXX&#39;等问题解决办法
  20. 学会Markdown,写博客不愁

热门文章

  1. PHP array_intersect_uassoc() 函数
  2. PHP array_diff_uassoc() 函数
  3. 朴素贝叶斯分类器基本代码 &amp;&amp; n折交叉优化
  4. JS 弹出框拖拽
  5. day25:魔术方法
  6. 学习Hibernate5这一篇就够了
  7. centos 8 安装和网络配置
  8. C#LeetCode刷题之#104-二叉树的最大深度​​​​​​​(Maximum Depth of Binary Tree)
  9. 如何为你的IDEA安装插件——几个实用插件推荐
  10. 听说同学你搞不懂Java的LinkedHashMap,可笑