中易网

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

答案:4  悬赏:50  
解决时间 2021-02-03 21:10
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个字节的情况,因此计算结果相同,这个就不介绍了,相信你应该明白了。

好了,现在相信你应该明白了
全部回答
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而已 具体代码意思上面几位已经讲得很清楚了;楼主不用太去在意,代码意思很简单 不要想多了
因为int是32位的,一个double为64位,当强制转换时,会直接将高位截掉。 你先将一个double写成二进制,然后将高32位截掉,剩下的32位你转换为int就知道了。
首先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。
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
都兰县国家重点公益林夏日哈管护站怎么去啊,
播音员主持人是干什么的
为什么小草到了春天会是绿的?
2011年护士首次注册时间第二次是多久?
如何区别气体溶解度,像易溶、可溶什么的……
图里的踏板该怎么踩?是一直踩着么?求解..
把花插在水瓶中能或多长时间?
兴业银行漪汾支行怎么去啊,有知道地址的么
大众朗逸1,6自动档速度传感器在哪个位置
广州民航职业技术学院怎样
水上公园菜市场我想知道这个在什么地方
tokyo 247 新希マヤ
五菱面包车怎么可以合法拉货
上海医保卡如何入账?
有没有文笔与笛安很像的小说或者作者?
推荐资讯
现在台式机玩游戏,显卡用N卡还是A卡
太平鸟风尚男装地址有知道的么?有点事想过去
福建省鑫诚基投资有限责任公司地址有知道的么
裕安区六安真善美幼儿园在什么地方啊,我要过
金氏电器我想知道这个在什么地方
我的小兔子很老实也大一点了,能给它洗澡吗?
虚渊玄常被称为什么
我在网上兼职提交了身份证正反面照和银行卡还
思政类博士点学校
we are dedicated to bring best products to
血糖高辟谷期间能吃大红枣吗
MFC的单文档应用程序和对话框应用程序可以相
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?