一段有意思的java代码请大家解释~

0x7FFFFFFF == (int)(0x7FFFFFFF * 2.0)

在打印这个语句的时候,编译器给出的答案是true

System.out.println((int)(0x7FFFFFFF * 2.0) == (int)(0x7FFFFFFF * 2));
System.out.println((int)(0x7FFFFF * 2.0) == (int)(0x7FFFFF * 2));

而这两个语句java给出的分别为false和true。

我所知道的只是当double型等于或超过int的最大值,再做int处理后,就会等于最大值。但是具体的原因却不是很清楚,不知道各位大侠能不能从编译器的算法上给我一个解释?谢谢啦~

原理很简单,因为在java中,int是占4个字节大小,double占8个字节的大小,当你把某变量乘以2的时候,在计算机里面的处理方式是左移一位。当使用浮点数进行乘法运算时,若结果很大,会以科学计数法表示。

下面具体分析:

1、表达式0x7FFFFFFF == (int)(0x7FFFFFFF * 2.0)

0x7FFFFFFF 已经占了4个字节,也就是int型的最大范围,以二进制表示出来为01111111 11111111 11111111 11111111

0X7FFFFFFF*2.0 计算出来的结果为double型,那么结果将会以科学计数法来表示,也就是4.294967294E9, 以二进制表示为0 11111111 11111111 11111111 11111110,以16进制表示为0xFF FF FF FE,注意,这里的计算结果并没有超出double的范围8字节。

(int)(0x7FFFFFFF * 2.0) 在上面已经看到0x7FFFFFFFF的二进制表示为01111111 11111111 11111111 11111111乘以2就表示左移一位,结果为0 11111111 11111111 11111111 11111110 (注意,这个数并未超出8字节的范围)然后再把结果强制转换为int型,也就是从最高位开始向下取4个字节,因此最后一位的0被丢弃(取double的最大值,因此丢弃最低位),最后结果以二进制表示为01111111 11111111 11111111 11111111,以16进制表示为0x7F FF FF FF,可以看到与0x7FFFFFFFF的相同,因此第一个表达式0x7FFFFFFF == (int)(0x7FFFFFFF * 2.0)反回true。

2、表达式(int)(0x7FFFFFFF * 2.0) == (int)(0x7FFFFFFF * 2)

(int)(0x7FFFFFFF * 2.0)这部分的结果在上面介绍过了,这里就不用介绍了,结果还是为0x7F FF FF FF。

(int)(0x7FFFFFFF * 2) 其中0x7FFFFFFF*2表示把0x7FFFFFFF左移一位,其二进制结果为0 11111111 11111111 11111111 11111110,因为最后为int型,计算结果超出4个字节,因此最高位的0被丢弃(int型的计算是抛弃最高位),结果为11111111 11111111 11111111 11111110,以16进制表示为0xFF FF FF FE与0x7FFFFFFF不相同,因此结果为false。

要注意,在计算机中数值是以补码的形式表示的(包括以上的计算结果全都是以补码表示的),补码知识不作介绍,这里只要知道,正数的被码就为原来的正数,而负数的补码为符号位不变,其余各位按位取反再加1。因此0xFF FF FF FE除符号位不变(在java中int型最高位为符号位),其余各位取反再加1,结果为10000000 00000000 00000000 00000010最后结果为-2,以16进制表示为0x80 00 00 02,因此使用print输出该数,则为-2,并不为0xFF FF FF FE的十进制数值。

3、表达式0x7FFFFF * 2.0== (int)(0x7FFFFF * 2)

因为两个数字计算的结果都没有出现超出int型的4个字节的情况,因此计算结果相同,这个就不介绍了,相信你应该明白了。

好了,现在相信你应该明白了
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-02-03
因为int是32位的,一个double为64位,当强制转换时,会直接将高位截掉。
你先将一个double写成二进制,然后将高32位截掉,剩下的32位你转换为int就知道了。
第2个回答  2010-02-03
首先0x7FFFFFFF就是Java里面整形变量的最大值了,你可以看看Integer.MAX_VALUE,"0x7FFFFFFF * 2.0"是,Java会把结果当做double型,因为double型的数值范围比int大,所以得到的是数学上正确的结果,然后强制转换我int就是Integer.MAX_VALUE了,第一个表达式为true;第二个里面"0x7FFFFFFF * 2"会被认为是int型,因为0x7FFFFFFF和2都是合法的int,所以就是发生数值的溢出(int)(0x7FFFFFFF * 2)就被算成-2了,你如果把第二个的结果显式制定为double型,得到的结果也是true:
double d = 0x7FFFFFFFL * 2;//加L指定为long型
System.out.println((int)(0x7FFFFFFF * 2.0) == (int) d);
第三个因为数值比较小,所以是true。
第3个回答  2010-02-03
没明白!