我刚才有一个我无法回答的问题。
假设您在Java中有这个循环定义:
while (i == i) ;
如果循环不是无限循环且程序只使用一个线程,i
的类型和i
的值是什么?
答案 0 :(得分:126)
double i = Double.NaN;
Double.equals()的API解释了答案:“Double.NaN == Double.NaN的值为false”。这在Java语言规范“Floating-Point Types, Formats, and Values”下详细阐述:
NaN
是无序的,所以数字 比较运算符<
,<=
,>
和>=
如果其中之一或两者都返回false
操作数为NaN
。该 等于运算符==
返回false
if 操作数是NaN
,而操作数是!=
不等式运算符true
返回NaN
if 两个操作数都是x!=x
。的在 特别是,true
当前是x
如果NaN
为(x<y) == !(x>=y)
,则false
会 如果x
或y
为NaN
,则为{{1}}。
答案 1 :(得分:30)
i
的值无效。 “不是数字”。
经过一些谷歌搜索,我发现你在Java中可以拥有NaN(非数字)!因此,浮点数是数据类型,值是NaN。见here
答案 2 :(得分:12)
double i = Double.NaN;
NaN不等于任何东西,包括它自己。
答案 3 :(得分:10)
float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");
答案 4 :(得分:8)
我不确定,但我相信(i == i)在多线程进程中不是原子操作,所以如果我的值会被其他线程在推送它的值之间改变,在执行循环的线程上堆栈,那么这种情况可能是错误的。
答案 5 :(得分:8)
由于其他人说它是NaN,我对Double.isNaN
的官方(JDK 6)实施感到好奇,并且看到:
/**
* 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);
}
答案 6 :(得分:2)
将Nan视为异常的等价物,但在计算中使用魔术值。因为计算失败 - 例如负的平方根,除以零等 - 将它们与其他任何东西进行比较是没有意义的。毕竟如果除以零是一个纳米,则它相当于-2的平方根或-3的平方根
Nan允许计算包括一个返回无效答案的步骤,而不会引入额外的异常。要验证答案是值,只需通过Float.isNan()o等效测试非nandness(如果不是我的话就是这个词)。
答案 7 :(得分:2)
我会添加
float i = Float.NaN;
以及
double i = Double.NaN;
这些问题中的一个常见技巧是假设你使我成为一个int。其他常见的假设可能是s是String,x,y是double,ch是char,b是字节等。 如果你看到这样的问题,你可以打赌'我'不是它的期望类型。
类似的问题是;这永远不会循环,什么是'x'
while(x == x && x != x + 0) { }
我非常喜欢的另一个问题是;这个循环是一个无限循环,x的可能值是什么。 (:我算了十二个:)
while(x != 0 && x == -x) { }
答案 8 :(得分:0)
我知道这是一个Java问题,但考虑到其他语言的问题很有趣。
在C中,如果'i'被声明为volatile,那么像'int'这样的简单类型可以表现出'在宇宙变冷之前终止'行为(因此编译器将被强制执行两次'i'读取每次迭代)如果'i'实际上在内存中,其他东西可能会影响它。然后,当'i'在单次迭代的两次读取之间发生变化时,循环将终止。 (添加:一个可能的地方 - 在微型计算机中,'i'实际上位于I / O端口的地址,可能连接到位置传感器。如果',那将更合理。我是一个指针变量(指向易失性存储器的指针),语句为'while (*i == *i);
'。)
正如其他答案所证明的那样,在C ++中,如果我是用户定义的类,那么'=='运算符可以由用户提供,因此任何事情都是可能的。
与NaN一样,在基于SQL的语言中,如果i的值为NULL,则循环不会是无限的;但是,任何非NULL值都会使循环无限。这与Java类似,其中任何数字(与NaN相对)使循环无限。
我没有看到这个结构有任何实际用途,但这是一个有趣的琐事问题。
答案 9 :(得分:0)
我很惊讶没有看到这个解决方案:
while (sin(x) == sin(x)) //probably won't eval to true
在回复评论时,请尝试运行:
double x = 10.5f;
assert (x == asin(sin(x)));
理论上,x应始终等于反正弦(sin(x)),但实际上并非如此。
答案 10 :(得分:0)
不是无限循环,一个线程:)
import static B.*;
public class A {
public static void main(String[] args) {
System.out.println("Still Running");
while (i == i) ;
}
}
public class B {
public static int i;
static {
System.exit(0);
}
}
答案 11 :(得分:-1)
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);
}
}