Java中整数溢出的问题:int i=1000000;i*i为何等于-727379968,Java是如何处理溢出的?
来源:互联网 发布:lns是什么社交软件 编辑:程序博客网 时间:2024/03/29 22:58
原提问地址:http://bbs.csdn.net/topics/40216116
问题:
读Java语言说明书到34页的时候碰到了一个整数相乘溢出的问题,百思不得其解,诚请行家指点。
int i=1000000;i*i为何等于-727379968?
书中说乘法是安装32位精度计算的。-727379968是计算结果1000000000000的低32位的十进制表示,计算结果对int类型来说太大了。怕英文水平有限个人理解有误,将原文附在下面(The multiplication is performed in 32-bit precision, The value -727379968 is the decimal value of the low 32 bits of the mathematical result, 1000000000000, which is a value too large for type int.)
问题如下:
1、Java是如何处理整数相乘溢出的?
2、i*i的低32位是如何取值法?我后来用i*i>>32得到了-727379968。
3、对于溢出是否先类型提升运算后再考虑精度问题?
答案
看了《Java虚拟机说明书》中“Java语言编程概念”中对“基本数据类型的变窄转换”的介绍才算明白了。
对于
int i = 1000000;
System.out.println(i*i);
-727379968
的合理解释和过程应该是这样的:i设置为1000000,在乘方时Java发现结果(1000000000000)已经超出了int基本数据类型的最大范围(2147483647),于是作了默认的类型提升(type promotion),中间结果做为long类型存放,返回结果时目标数据类型int不能够容纳下结果,于是根据Java的基础类型的变窄转换(Narrowing primitive conversion)规则,把结果宽于int类型宽度的部分全部丢弃,也就是只取结果的低32位,于是就得到了上面的结果。
下面用一个十六进制表示的例子阐释这个问题
int i3 = 1000000;
System.out.println (Long.toHexString (i3*i3).toUpperCase());
System.out.println (Long.toHexString (i3*i3).toUpperCase());
System.out.println (Integer.toHexString (i3*i3).toUpperCase());
System.out.println ((int)i3*i3);
FFFFFFFFD4A51000
1000000000000
D4A51000
-727379968
截取是非常直观的
- Java中整数溢出的问题:int i=1000000;i*i为何等于-727379968,Java是如何处理溢出的?
- 关于java中i++,++i和i++ + ++i的问题
- java中i=i++的问题
- java中i=i++的问题
- i+1<i i-1>i java溢出问题;补码 反码 面试题
- java的i++问题
- JAVA i=i++的问题
- JAVA i=i++的问题
- JAVA i=i++的问题
- JAVA i=i++的问题
- Java中关于i++与++i的问题
- 关于java中i=i++的问题
- Java中i++ 和 ++i的区别
- java中i = i++的思考?
- java中i++与++i的区别
- java中i++与++i的区别
- java 中 i=i++ 的解释
- java中i++与++i的区别
- TSP
- 基于RTSP的流媒体播放器制作(2)
- jython使用入门
- Block的注意点
- Objective-C Runtime
- Java中整数溢出的问题:int i=1000000;i*i为何等于-727379968,Java是如何处理溢出的?
- Object-C--->Swift之(一)元组(tuple)类型
- IntelliJ IDEA,代码行宽度超出限制时设置自动换行
- LeetCode N-Queens II
- Runtime Method Swizzling
- HTML常见声明
- SparkMLlib之五:优化
- 5、阶段练习,两个快捷键,获取用户输入的信息
- valuestack,stackContext,ActionContext.之间的关系