看看这个溢出问题的结果会是什么样?

Shrewdcat 2003-12-01 02:11:17
TIJ中的一个例子,请各位猜猜结果会是什么,能说说为什么会这样吗?

public class Overflow {
public static void main(String[] args) {
int big = 0x7fffffff; // max int value

prt("big = " + big);
int bigger = big * 4;
prt("bigger = " + bigger);
}
static void prt(String s) {
System.out.println(s);
}
} ///:~
...全文
39 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaohaiz 2003-12-02
  • 打赏
  • 举报
回复
Shrewdcat(丧邦&灵猫&潇) :
呵呵,那你说等于多少?这多简单啊。

10000000000000000000000000000100 = 0x80000004
= 0x80000000 + 0x04 = -2147483644;

:)

BTW, 0x80000000 = Integer.MIN_VALUE
Shrewdcat 2003-12-02
  • 打赏
  • 举报
回复
To: xiaohaiz(老土进城,两眼通红)

11111111111111111111111111111100 = -4
那这个等于几:
10000000000000000000000000000100=?
xiaohaiz 2003-12-01
  • 打赏
  • 举报
回复
带符号二进制补码数乘2都是相当于左移,单元测试为证:
<<
public class TestMulti extends TestCase {
public TestMulti(String name) {super(name);}

public void testMulti() {
assertEquals(Byte.MIN_VALUE*2, Byte.MIN_VALUE<<1);
assertEquals(Byte.MAX_VALUE*2, Byte.MAX_VALUE<<1);
assertEquals((byte)0*2, (byte)0<<1);

assertEquals(Short.MIN_VALUE*2, Short.MIN_VALUE<<1);
assertEquals(Short.MAX_VALUE*2, Short.MAX_VALUE<<1);
assertEquals((short)0*2, (short)0<<1);

assertEquals(Integer.MIN_VALUE*2, Integer.MIN_VALUE<<1);
assertEquals(Integer.MAX_VALUE*2, Integer.MAX_VALUE<<1);
assertEquals(0*2, 0<<1);

assertEquals(Long.MIN_VALUE*2, Long.MIN_VALUE<<1);
assertEquals(Long.MAX_VALUE*2, Long.MAX_VALUE<<1);
assertEquals(0L*2, 0L<<1);
}
}
>>
说到这个问题,不禁想到josha bloch的一个问题,如何验证一个整数是2的幂:
n & (-n) == n
这个问题更有助于理解带符号的二进制补码数运算。
xiaohaiz 2003-12-01
  • 打赏
  • 举报
回复
lyjlee() 的例子也能说明问题。在jvm所支持的所有整数类型(byte,short,int,long)都是带符号的二进制补码数。二进制,所以乘以2就相当于左移一位:
int big = 0x7FFFFFFF;
big = big * 2; // big = big<<1;
big = 0xFFFFFFE;
big = big * 2; // big = big<<1;
big = 0xFFFFFFC = -4;
xiaohaiz 2003-12-01
  • 打赏
  • 举报
回复
0x7FFFFFFF
+0x7FFFFFFF
------------
0xFFFFFFFE
+0x7FFFFFFF
------------
0x7FFFFFFD
+0x7FFFFFFF
------------
0xFFFFFFFC = 11111111111111111111111111111100 = -4

Java虚拟机的整数运算是“二进制补码运算”。jvm中出现整数运算的溢出并不导致异常,其结果被截短以符合数据类型。
lyjlee 2003-12-01
  • 打赏
  • 举报
回复
看下面:
import com.wizesoft.util.*;
//这里我导入一个打印为二进制的函数BP.rint();
/*
import java.util.*;
public class BP{
public static void rint(int i){
for(int j=31;j>-1;j--){
if (((1<<j)&i)!=0)
System.out.print("1");
else
System.out.print("0");
if (j%8==0&&j!=0)System.out.print(",");
}
}
public static void rint(long i){
for(int j=63;j>-1;j--){
if (((1<<j)&i)!=0)
System.out.print("1");
else
System.out.print("0");
if (j%8==0&&j!=0)System.out.print(",");
}
}
}
*/


public class Overflow {
public static void main(String[] args) {
int big = 0x7fffffff; // max int value

System.out.println("big = " + big);
BP.rint(big);
prt("\n");
int bigger = big * 4;
prt("bigger = " + bigger);
BP.rint(bigger);
prt("\n");
long biggest=big*4;
prt("biggest = " + biggest);
BP.rint(biggest);
}
static void prt(String s) {
System.out.println(s);
}
} ///:~

运行结果为:

---------- Run Java Program ----------
big = 2147483647
01111111,11111111,11111111,11111111

bigger = -4
11111111,11111111,11111111,11111100

biggest = -4
11111111,11111111,11111111,11111100,11111111,11111111,11111111,11111100
Output completed (0 sec consumed) - Normal Termination

说明:
bigger=big*4,即相当于big左移2位,右边用00补齐
bluesmile979 2003-12-01
  • 打赏
  • 举报
回复
-4都被你算出来了,厉害:)
ddbean 2003-12-01
  • 打赏
  • 举报
回复
bigger=-4;
因为int型最大为2147483647,超出则改变符合位了

62,614

社区成员

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

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