http://yoyo08.iteye.com/blog/333800
http://yoyo08.iteye.com/blog/333800
首先需要说明的是,以下问题都是出自《Java解惑》,这里做一个整理,也加深一下印象。
下面所有的问题都是给出一个循环,给它加一个什么样的变量声明,使它作用于循环上时能够使循环无限循环下去(即变成一个无限循环)。
1.
- for (int i = start; i <= start + 1; i++) {}
这个问题还比较简单,只需要这样声明即可(注意:上面的是小于等于号):int start = Integer.MAX_VALUE - 1;
2.
- While (i == i + 1) {}
如果 i 在循环开始之前被初始化为无穷大,无穷大加 1 还是无穷大,那么终止条件测试(i == i + 1)就会被计算为 true,从而使循环永远都不会终止。这样声明即可:double i = Double.POSITIVE_INFINITY;
事实上,任何足够大的浮点数都可以实现这一目的,例如: double i = 1.0e40; 这样做之所以可以起作用,是因为一个浮点数值越大,它和其后继数值之间的间隔就越大。浮点数的这种分布是用固定数量的有效位来表示它们的必然结果。对一个足够大的浮点数加 1 不会改变它的值,因为 1 是不足以“填补它与其后继者之间的空隙”。
3.
- while (i != i) { }
IEEE 754 浮点算术保留了一个特殊的值用来表示一个不是数字的数量,这个值就是 NaN(“不是一个数字(Not a Number)”的缩写),对于所有没有良好的数字定义的浮点计算,例如 0.0/0.0,其值都是它。规范中描述道,NaN 不等于任何浮点数值,包括它自身在内。因此,如果 i 在循环开始之前被初始化为 NaN,那么终止条件测试(i != i)的计算结果就是 true,循环就永远不会终止。很奇怪但却是事实。 可以这样声明:double i = 0.0 / 0.0;
为了表达清晰,可以使用标准类库提供的常量: double i = Double.NaN;
为了表达清晰,可以使用标准类库提供的常量: double i = Double.NaN;
4.
- while (i != i + 0) { }
注意:此题不使用浮点数。
我们必然可以得出这样的结论,即 i 的类型必须是非数值类型的,并且这其中存在着解谜方案。唯一的 + 操作符有定义的非数值类型就是 String。+ 操作符被重载了:对于 String 类型,它执行的不是加法而是字符串连接。如果在连接中
的某个操作数具有非 String 的类型,那么这个操作书就会在连接之前转换成字符串。
的某个操作数具有非 String 的类型,那么这个操作书就会在连接之前转换成字符串。
事实上,i 可以被初始化为任何值,只要它是 String 类型的即可,例如:String i = "Hello";
5.
- while (i <= j && j <= i && i != j) { }
在Java5.0版本及以后,<=操作符在原始数字类型集上是反对称的,但是<=操作符在被包装的数字类型(Byte、Character、Short、Integer、Long、Float 和 Double)的操作数上不是反对称的,因为 Java 的判等操作符(==和!=)在作用于对象引用时,执行的是引用ID 的比较,而不是值的比较。
所以这样声明即可: Integer i = new Integer(0); Integer j = new Integer(0);
- public class Test4
- {
- public static void main(String[] args)
- {
- System.out.println(new Integer(0) == 0); //输出:true
- System.out.println(new Integer(0) == new Integer(0)); //输出:false
- }
- }
6.
- while (i != 0 && i == -i) { }
可以推断出 i 的类型必然是整数型的。总共存在偶数个 int 数值——准确地说有2的32次方个——其中一个用来表示 0,这样就剩些奇数个 int 数值来表示正整数和负整数,这意味着正的和负的 int 数值的数量必然不相等。这暗示着至少有一个 int数值,其负值不能正确地表示成为一个 int 数值。
事实上,恰恰就有一个这样的 int 数值,它就是 Integer.MIN_VALUE,十六进制表示是 0x80000000。其符号位为 1,其余所有的位都是 0。如果我们对这个值取负值,那么我们将得到 0x7fffffff+1,也就是 0x80000000,即
Integer.MIN_VALUE!因此,Integer.MIN_VALUE 是它自己的负值,Long.MIN_VALUE 也是一样。对这两个值取负值将会产生溢出,但是 Java 在整数计算中忽略了溢出。
Integer.MIN_VALUE!因此,Integer.MIN_VALUE 是它自己的负值,Long.MIN_VALUE 也是一样。对这两个值取负值将会产生溢出,但是 Java 在整数计算中忽略了溢出。
因此可以这样声明:int i = Integer.MIN_VALUE; 或者:long i = Long.MIN_VALUE;
- public class Test4
- {
- public static void main(String[] args)
- {
- int i = Integer.MIN_VALUE;
- long j = Long.MIN_VALUE;
- System.out.println(i == -i); //输出:true
- System.out.println(j == -j); //输出:true
- }
- }