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代码请大家解释~
答案:4 悬赏:50
解决时间 2021-02-03 21:10
- 提问者网友:时间却是纷扰
- 2021-02-03 17:41
最佳答案
- 二级知识专家网友:何必打扰
- 2021-02-03 19:09
原理很简单,因为在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、表达式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楼网友:情窦初殇
- 2021-02-03 22:24
public void testsetlog() throws exception
{
logmanagerimpl lmi=util_con.createlmi(); //创建日志管理器对象
lmi.setlog(4, "admin", "admin", "320400000000");//设置日志内容,具体内部看实现方式
boolean flag = false;//声明一个标记,初始值为假
if(flag){ //通过此处可以知道你的日志是不是处理成功
system.out.println("添加日志成功!"); //输出语句,提示你日志操作成功
}else{
system.out.println("添加日志失败!");}//这条会打印出来
assert.assertequals("添加日志成功!","添加日志成功!");//直接比较两个相同内容的string
对于楼上的解释完全正确,补充一点你的追问,设置 boolean flag = false初始为假,是为了方便知道你的记录是不是成功,如果成功,日志类会返回一个真。如果处理失败或出现异常都会返回假
再补充一个 刚刚你提问说为什么初始flag要设置为false 因为一般习惯都是先默认为false 然后通过一系列if判断看是否能符合要求,符合则修改为false 最后return flag 避免了直接设置为真 然后忘记做处理 然后就直接通过了的错误情况出现,因为它默认是false的;
我觉得这段代码应该就是一个单元测试的小例子 只是示范一下assert而已 具体代码意思上面几位已经讲得很清楚了;楼主不用太去在意,代码意思很简单 不要想多了
- 2楼网友:最后战士
- 2021-02-03 20:55
因为int是32位的,一个double为64位,当强制转换时,会直接将高位截掉。
你先将一个double写成二进制,然后将高32位截掉,剩下的32位你转换为int就知道了。
- 3楼网友:啵啵桃汀
- 2021-02-03 20:36
首先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。
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯
• 手机登qq时,显示手机磁盘不足,清理后重新登 |
• 刺客的套装怎么选啊? |