A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 移动小坦克 中级黑马   /  2013-3-6 02:07  /  2222 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

下面这段代码,输出为什么会是  -1?

public class Exc {

        public static void main(String[] args)
        {
                int x=0,count=0;
                while(x<=100)
                {
                        count += count+1;
                        x++;
                }
                System.out.println(count);//这里竟然输出-1???
               
        }
}
想不明白,为什么。。。。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

4 个回复

倒序浏览
本帖最后由 李志卫 于 2013-3-6 04:34 编辑
  1. public static void main(String[] args)
  2.         {
  3.                 int x=0, count=0;
  4.                
  5.                 while(x<=100)
  6.                 {
  7.                         System.out.println("..X.."+x);
  8.                         count += count+1;
  9.                         System.out.println(count);
  10.                         x++;
  11.                 }
  12.                
  13.                 System.out.println(count);//这里竟然输出-1???
  14.                
  15.         }
复制代码
看代码的结果 你会发现当x=30的时候 count的值为2147483647,这个值就是带符号int的最大值
x=31时 count会超过int的最大值,相加后,硬盘上这个int地址的的四个字节二进制为1111....111111. 转为十进制就是count=-1。
剩下的循环继续  当count=-1, count+=count+1;  count恒等于-1.
所以最后count=-1.

点评

嗯,你说的有道理  发表于 2013-3-6 10:20

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

回复 使用道具 举报
李志卫 发表于 2013-3-6 02:43
看代码的结果 你会发现当x=30的时候 count的值为2147483647,这个值就是int的最大值
x=31时 count会超过int ...

全变为11111111吧,一共32位都是1吧?
-1的2进制是32个1呀
回复 使用道具 举报
韩松范 发表于 2013-3-6 03:43
全变为11111111吧,一共32位都是1吧?
-1的2进制是32个1呀

you are right
回复 使用道具 举报
本帖最后由 明锦添 于 2013-3-7 23:58 编辑

我把你的代码改了一下,得到的count的最后的值为:256065421246102339102334047485951 我想这才是你想要得到的结果。
public class Test2 {
        public static void main(String[] args) {
                int x = 0;
                BigInteger count = new BigInteger("0");
                while (x <= 100) {
                        count = count.add(count.add(new BigInteger("1")));
                        System.out.println(count.toString());
                        x++;
                }
                // System.out.println(count.bitLength());
                System.out.println(count.toString());
        }
}

输出结果:
1
3
7
15
31
63
127
255
511
1023
2047
4095
8191
16383
32767
65535
131071
...
...
...
2535301200456458802993406410751

在计算机内存中数据都只能以二进制的形式表示,int类型的数据表示形式为:符号位(最高位)+数值位(其它位),正数是原码的形式表示,负数以补码的形式表示,数据的正负,则是由最高位的符号位来确定,符号为1表示负数,符号位为0表示正数:
如十进制 5 用整型数据表示为: 0 0000000 00000000 00000000 00000101
十进制 -5 用整型数据表示为:   1 1111111 11111111 11111111 11111011 它的最高位为1,所以是负数,即补码存放,只需要原基础上把数值位的数字取反(反码)+1 就可以得到这个数的值,即为   1:0 0000000 00000000 00000000 00000101  原码为5,因其最高位为1(表示负数),所以它的值为 -5
你定义的的count的数据类型为整型(在java中整型只占四个字节:32个二进制位 数值的取值范围为:(-2147483648~2147483647
但你计算的这个数值:256065421246102339102334047485951  远远超过了32个二进制位所能存放的数字的范围,在存放时发了内存溢出。
这个数放在int类型的变量中全填满这四个字节的所有二进制位(包括符号位),结果显示在内存的二进制位应该是这样的:
1 1111111 11111111 11111111 11111111  在这里符号位为1,表示负数,再对它取反(反码)+1
0 0000000 00000000 00000000 00000001 就这样得到的结果就等于 -1 。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马