Java中整数溢出的问题:int i=1000000;i*i为何等于-727379968,Java是如何处理溢出的?
2016-01-13 20:04
337 查看
原提问地址: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;
下面用一个十六进制表示的例子阐释这个问题
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());
1000000000000
D4A51000
问题:
读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);
FFFFFFFFD4A510001000000000000
D4A51000
-727379968
截取是非常直观的相关文章推荐
- JavaSE学习笔记--Item1 注解Annotation
- Myeclipse+hibernate
- java -jar
- An internal error occurred during: "reload maven project". eclipse 报错
- you must restart adb and eclipse的相关解决办法
- SpringMVC知识1:流程
- Java虚拟机之类文件结构
- The Java Programming Language4th读书笔记-第十四章 线程
- Java 反射的应用
- Java參数传递方式
- Spring读取外部的.properties文件内容并设置给bean的两种方法
- javaEE eclipse中连接mysql数据库 Driver中的D要大写!
- Java [Leetcode 198]House Robber
- java socket编程
- Java-JDK环境变量配置教程
- AjaxAnywhere+struts用法
- Java 数组
- New Relic for Java
- myeclipse使用常见问题
- 程序包javax.servlet.annotation不存在