Java中整数溢出的问题:int i=1000000;i*i为何等于-727379968,Java是如何处理溢出的?

heart5 2003-10-10 11:01:38
读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、对于溢出是否先类型提升运算后再考虑精度问题?
...全文
1204 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
heart5 2003-12-09
  • 打赏
  • 举报
回复
to kypfos:
交个朋友,送30分你

Yanbin_Q 2003-12-09
  • 打赏
  • 举报
回复
你自己不是说完了吗?
我觉得没什么可补充了。
heart5 2003-12-09
  • 打赏
  • 举报
回复
看了《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
---------------------------------------------------

截取是非常直观的


哪位朋友稍微再补充一下我就给分!!!(没办法,我不能给自己分又想结帖)
heart5 2003-10-17
  • 打赏
  • 举报
回复
我是想了解Java是如何处理此类溢出的???
playboyxp 2003-10-11
  • 打赏
  • 举报
回复
溢出
用long int
heart5 2003-10-10
  • 打赏
  • 举报
回复
Java语言说明书第60页有关缩短转换(Narrowing Conversion)的文章,有点了解了,但还不是很清除。
溢出处理好像是在编译器内部完成的???

以下是翻译
浮点数向整数的缩短转换分两步进行:
1、第一步,如果目标类型T是long就转换为long;如果是byte、short、char和int就转换为int,遵循如下规则:
浮点数是NaN,第一步转换的结果就是int类型或者long类型的0。
否则,如果浮点数不是无穷,就舍入为整数类型的V。舍入方式采取IEEE 745向零舍入的方式。然后分为两种情况:
如果T是long,这个整数值可以做为long表示,那第一步转换的结果就是long类型的V。
否则,如果这个整数可以做为int表示,那第一步转换的结果就是int类型的V。
否则,肯定存在下面两种情况之一:
数值要么非常小(非常大的负数或者负无穷),那第一步转换的结果就是long或者int类型的最小值。
数值要么就非常大(非常大的整数或者正无穷),那第一步转换的结果就是long或者int类型的最大值。
2、第二步:
如果T是int或者long,那结果就是第一步转换的结果。
如果T是byte、char或者short,那结果就是第一步转换结果对类型T做缩短转换。

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧