我有一个我无法回答的问题。
假设您在Java中具有以下循环定义:
while (i == i) ;
如果循环不是无限循环并且程序仅使用一个线程,则的类型i和值是什么?i
我有一个我无法回答的问题。
假设您在Java中具有以下循环定义:
while (i == i) ;
如果循环不是无限循环并且程序仅使用一个线程,则的类型i和值是什么?i
Answers:
double i = Double.NaN;
Double.equals()的API 给出了答案:“ Double.NaN == Double.NaN的值为false”。Java语言规范中“ 浮点类型,格式和值 ” 下对此进行了详细说明:
NaN是无序的,所以数值比较运算<,<=,>,和>=返回false如果任一或两个操作数都NaN。等于运算符==返回false如果操作数是NaN和不平等运营商!=的回报true,如果一个操作数的NaN。尤其x!=x是true当且仅当xISNaN,而(x<y) == !(x>=y)将是false,如果x或yisNaN。
x == x应该永远是对的。为什么有什么不等于自身?
null=null为空。NULL IS NULL是1
float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");
由于其他人说这是NaN,所以我对的正式(JDK 6)实现感到好奇Double.isNaN,请注意:
/**
* Returns <code>true</code> if the specified number is a
* Not-a-Number (NaN) value, <code>false</code> otherwise.
*
* @param v the value to be tested.
* @return <code>true</code> if the value of the argument is NaN;
* <code>false</code> otherwise.
*/
static public boolean isNaN(double v) {
return (v != v);
}
将Nan视为异常的等效项,但在计算中使用魔术值。由于计算失败-例如负数的平方根,零除等,因此将它们与其他任何内容进行比较都没有意义。毕竟,如果被零除是一个nan,它等于-2的平方根还是-3的平方根?
Nan允许进行的计算包括返回无效答案的步骤以完成操作而不会引入额外的异常。要验证答案是否有价值,只需通过Float.isNan()o等效项测试非nandness(如果我不打包它就是这个词)。
我会补充
float i = Float.NaN;
以及
double i = Double.NaN;
在这类问题中,一个常见的技巧是假设您将i设为int。其他常见的假设可能是s是一个字符串,x,y是一个双精度型,ch是一个字符,b是一个字节,等等。如果您看到类似这样的问题,您可以打赌'i'不是它的期望类型。
一个类似的问题是;这永远不会循环,什么是“ x”
while(x == x && x != x + 0) { }
我很喜欢的另一个问题是:这个循环是一个无限循环,x的可能值是多少。(:我数了十二个:)
while(x != 0 && x == -x) { }
我知道这是一个Java问题,但是考虑其他语言的问题很有趣。
在C语言中,如果将“ i”声明为volatile,则诸如“ int”之类的简单类型可能表现出“在宇宙变冷之前终止”的行为(因此,编译器将被迫对每次迭代进行两次“ i”的读取)如果“ i”实际上在内存中,则可能有其他因素影响它。然后,当一次迭代的两次读取之间的“ i”发生变化时,循环将终止。(添加:一个可能的地方-在微型计算机中,'i'实际上位于I / O端口的地址上,也许连接到位置传感器。如果'i'是指针变量(可能更合理(指向易失性内存的指针),并且该语句为' while (*i == *i);'。)
正如其他答案所证明的那样,在C ++中,如果i是用户定义的类,则用户可以提供'=='运算符,因此一切皆有可能。
就像NaN一样,在基于SQL的语言中,如果i的值为NULL,则循环不会是无限的。但是,任何非NULL值都会使循环无限。这就像Java,其中任何数字(与NaN相对)使循环无限。
我看不到该构造有任何实际用途,但这是一个有趣的琐事问题。
我很惊讶没有看到这个解决方案:
while (sin(x) == sin(x)) //probably won't eval to true
为了回应评论,请尝试运行以下命令:
double x = 10.5f;
assert (x == asin(sin(x)));
从理论上讲,x应始终等于反正弦(sin(x)),但实际上并非如此。
x,这将产生具有完全相同的准确性的完全相同的结果。Arcsin不能将带有浮点数的sin的结果取反,因为传递给的值将asin()不完全准确。因此,的结果asin()将是不准确的,从而导致x == asin(sin(x))错误。另外,arcsin不一定会“撤消” sin操作-sin函数可以为x的多个值给出相同的结果,这就是为什么asin()仅返回-π/ 2和π/ 2之间的数字的原因。
i == i不是原子的。通过这样的程序证明:
static volatile boolean i = true;
public static void main(String[] args) throws InterruptedException
{
new Thread() {
@Override
public void run() {
while (true) {
i = !i;
}
}
}.start();
while (i == i) ;
System.out.println("Not atomic! i: " + i);
}
更新 这是非无限循环的另一个示例(不创建新线程)。
public class NoNewThreads {
public static void main(String[] args) {
new NoNewThreads();
System.gc();
int i = 500;
System.out.println("Still Running");
while (i == i) ;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
Thread.sleep(1000);
System.exit(0);
}
}
while (i == i);不会执行。