第二十九题:循环者的新娘
要实现i!=i为true
public static void main(String[] args) {
double i = 0.0/0.0;
double d = Double.NaN;
System.out.println(i != i);
System.out.println(ChapterUtil.getIEE754FromDouble(i));
System.out.println(ChapterUtil.getIEE754FromDouble(d));
}
//控制台输出
//true
//7ff8000000000000
//7ff8000000000000
Double.NaN表示一个非数字(Not a Number),在内存存储为0x7ff8000000000000,维基百科IEE754 NaN,符号位为0或1,指数位全为1,尾数不全为0。NaN与任何都不相等,包括自己。
第三十题:循环者的爱子
要实现i!=i+0为true,i不能为浮点数。
public static void main(String[] args) {
String i = "";
System.out.println(i!=i+0);
}
//控制台输出:
//true
i不是一个数字,使用字符串重载,可以实现上面的表达式为true;
第三十一题:循环者的鬼魂
public static void main(String[] args) {
short i = -1;
while(i!=0) {
i>>>=1;
}
}
无符号右移>>>,与右移>>的区别是:>>>会将包括符号位的所有比特位整体右移,舍掉超出部分,左边补零;而>>右移不包括符号位,符号位不动,且左边用符号位填充。以-1右移2位为例:
public static void main(String[] args) {
System.out.println(ChapterUtil.getFromInt(-1));
System.out.println(ChapterUtil.getFromInt(-1>>2));
System.out.println(ChapterUtil.getFromInt(-1>>>2));
}
//控制台输出:
//ffffffff
//ffffffff
//3fffffff
还当执行>>>=这种复合赋值操作符时,会将short提升为int,0xffff提升为0xffffffff,无符号右移1位,得到0x7fffffff,会转化为short,接着强制把高位给截掉,然后又得到0xffff,最终无限循环。
得到的经验教训是不要在byte,char,short变量上使用+=这种复合赋值操作符。
第三十二题:循环者的诅咒
public static void main(String[] args) {
Integer i = new Integer(0);
Integer j = new Integer(0);
System.out.println(i <= j && i >= j && i != j);
}
//控制台输出:
//true
如何实现i<=j&&i>=j,好像只能i==j,但是题目中又要求i!=j。在jdk1.5后,有了自动装箱与自动拆箱,Integer对象i和j进行<=和>=比较时,进行拆箱,将值比较,而==与!=是对象引用的比较,比较i和j是否指向同一个对象,显然不是,所以符合以上所有条件。