怎么能“while(i == i);”在单线程应用程序中是一个非无限循环?

时间:2009-01-22 23:35:15

标签: java

我刚才有一个我无法回答的问题。

假设您在Java中有这个循环定义:

while (i == i) ;

如果循环不是无限循环且程序只使用一个线程i的类型和i的值是什么?

12 个答案:

答案 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会   如果xyNaN,则为{{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);
    }
}