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

时间:2022-07-02 08:40:50

I just got a question that I can't answer.

我有一个问题我不能回答。

Suppose you have this loop definition in Java:

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

while (i == i) ;

What is the type of i and the value of i if the loop is not an infinite loop and the program is using only one thread?

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

12 个解决方案

#1


126  

double i = Double.NaN;

The API for Double.equals() spells out the answer: "Double.NaN==Double.NaN has the value false". This is elaborated in the Java Language Specification under "Floating-Point Types, Formats, and Values":

Double.equals()的API表明:“Double.NaN==Double”。NaN的值是假的。这是在“浮点类型、格式和值”下的Java语言规范中阐述的:

NaN is unordered, so the numerical comparison operators <, <=, >, and >= return false if either or both operands are NaN. The equality operator == returns false if either operand is NaN, and the inequality operator != returns true if either operand is NaN. In particular, x!=x is true if and only if x is NaN, and (x<y) == !(x>=y) will be false if x or y is NaN.

NaN是无序的,所以数值比较运算符<,<=,>,>=如果其中一个或两个操作数都是NaN,则返回false。等式运算符==如果任一操作数为NaN,则返回false;如果任一操作数为NaN,则不等运算符!=返回true。特别是,x !=x为真且仅当x为NaN时为真,(x =y)当x或y为NaN时为假。 )>

#2


30  

The value of i is then Invalid. "Not a Number".

此时i的值无效。“不是很多”。

After some googling, i found out that you CAN have NaN ( Not a Number ) in Java! So, a Float Pointing number is the Data Type and the Value is NaN. See here

在google了一番之后,我发现在Java中可以有NaN(不是数字)!所以,浮点数是数据类型,值是NaN。在这里看到的

#3


12  

double i = Double.NaN;

NaN is not equal to anything, including itself.

NaN不等于任何东西,包括它自己。

#4


10  

float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");

#5


8  

I'm not sure, but I believe (i == i) is not atomic operation in multithreaded process, so if i value will be changed by other thread between pushes of it's value to stack on thread executing the loop, then that condition can be false.

我不确定,但我相信(I == I)在多线程进程中不是原子操作,所以如果我的值在执行循环的线程上推值到堆栈之间被其他线程更改,那么这个条件可能是假的。

#6


8  

Since others said it's NaN I got curious about the official (JDK 6) implementation of Double.isNaN, and behold:

由于其他人说这是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);
}

#7


2  

Think of Nan as the equivalent of exception but uses a magic value within a calculation. Because a calculation failed - eg square root of a negative, divide by zero etc - it makes no sense in comparing them against anything else. After all if divide by zero is a nan is it equivalent to the square root of -2 or square root of -3 ?

把Nan看作是一个例外,但是在计算中使用了一个神奇的值。因为计算失败了——例如负数的平方根,除以0等等——把它们和其他东西作比较是没有意义的。毕竟,如果除以0是nan它等于-2的平方根还是-3的平方根?

Nan allows a calculation that includes a step that returns an invalid answer to complete without introducing extra exceptions. To verify the answer is value simply test for non nandness ( is that's word if not I bags it) via Float.isNan() o equivalent.

Nan允许计算包含一个步骤,该步骤返回无效的答案以完成,而不引入额外的异常。要验证答案是value,只需通过Float.isNan() o等价测试非无意义性(如果不是我包的话,就是这个词)。

#8


2  

I would add

我想补充

float i = Float.NaN;

as well as

以及

double i = Double.NaN;

A common trick in these sort of questions it in the assumption you make that i is an int. Other common assumptions might be s is a String, x,y are a double, ch is a char, b is a byte etc. If you see a question like this you can bet that 'i' is not its expect type.

一种常见的把戏在这些问题在假设你让我是一个int。其他常见的假设可能是一个字符串,x,y是一个双,ch是一个char,b是一个字节等。如果你看到这样的一个问题,你可以打赌,“我”并不是期望类型。

A similar question is; This never loops, what is 'x'

类似的问题;它不会循环,什么是x

while(x == x && x != x + 0) { }

Another question I quite like is; This loop is an infinite loop, what are the possible values of x. (: I count twelve of them :)

我喜欢的另一个问题是;这个循环是一个无限循环,x的可能值是多少?

while(x != 0 && x == -x) { }

#9


0  

I know this is a Java question, but considering the question for other languages is intriguing.

我知道这是一个Java问题,但是考虑其他语言的问题是很有趣的。

In C, a simple type such as 'int' could exhibit 'terminate before the universe grows cold' behaviour if 'i' was declared as a volatile (so the compiler would be forced to do two reads of 'i' for each iteration) and if 'i' was actually in memory where something else could affect it. Then the loop would terminate when 'i' changed between the two reads of a single iteration. (Added: a possible place - in a micro-computer where 'i' is actually located at the address of an I/O port, perhaps connected to a position sensor. It would be more plausible if 'i' was a pointer variable (a pointer to volatile memory) and the statement was 'while (*i == *i);'.)

在C语言中,一个简单的类型,如“int”展览在宇宙变冷之前终止的行为如果宣布“我”作为挥发性(编译器将*做两个读取每个迭代)的“我”,如果“我”实际上是在内存中,其他可能影响它。当一个迭代的两个读取之间的“i”发生变化时,循环就会终止。(补充:一个可能的位置——在微型计算机中,“i”实际上位于i /O端口的地址,可能连接到位置传感器。如果'i'是一个指针变量(指向易失性内存的指针),语句是'while (*i = *i);

As evidenced by other answers, in C++, the '==' operator can be supplied by the user if i is of a user-defined class, so anything might be possible.

从其他答案可以看出,在c++中,“==”操作符可以由用户提供,如果我是用户定义的类,那么任何事情都是可能的。

Rather like NaN, in an SQL-based language, the loop would not be infinite if the value of i was NULL; however, any non-NULL value would make the loop infinite. This is rather like Java, where any number (as opposed to NaN) makes the loop infinite.

与NaN类似,在基于sql的语言中,如果i的值为空,则循环将不是无限的;然而,任何非空值都会使循环成为无限的。这很像Java,任何数字(与NaN相反)都使循环为无穷大。

I do not see the construct having any practical use, but it is an interesting trivia question.

我不认为这个结构有任何实际用途,但它是一个有趣的琐事问题。

#10


0  

I was surprised to not see this solution:

我很惊讶没有看到这样的解决方案:

while (sin(x) == sin(x)) //probably won't eval to true

In response to a comment, try running this:

回复评论时,试着运行以下语句:

double x = 10.5f;
assert (x == asin(sin(x)));

x should always equal the arcsine(sin(x)) in theory, but in practice it doesn't.

x在理论上应该总是等于arcsin (x),但在实践中却不是。

#11


0  

Not infinite loop, one thread :)

不是无限循环,一个线程:)

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);
    }
}

#12


-1  

i == i is not atomic. Proved by such program:

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);
}

Update Here is one more example of not-infinite loop (no new threads are created).

这里的Update是一个非无限循环的例子(没有创建新的线程)。

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);
    }
}

#1


126  

double i = Double.NaN;

The API for Double.equals() spells out the answer: "Double.NaN==Double.NaN has the value false". This is elaborated in the Java Language Specification under "Floating-Point Types, Formats, and Values":

Double.equals()的API表明:“Double.NaN==Double”。NaN的值是假的。这是在“浮点类型、格式和值”下的Java语言规范中阐述的:

NaN is unordered, so the numerical comparison operators <, <=, >, and >= return false if either or both operands are NaN. The equality operator == returns false if either operand is NaN, and the inequality operator != returns true if either operand is NaN. In particular, x!=x is true if and only if x is NaN, and (x<y) == !(x>=y) will be false if x or y is NaN.

NaN是无序的,所以数值比较运算符<,<=,>,>=如果其中一个或两个操作数都是NaN,则返回false。等式运算符==如果任一操作数为NaN,则返回false;如果任一操作数为NaN,则不等运算符!=返回true。特别是,x !=x为真且仅当x为NaN时为真,(x =y)当x或y为NaN时为假。 )>

#2


30  

The value of i is then Invalid. "Not a Number".

此时i的值无效。“不是很多”。

After some googling, i found out that you CAN have NaN ( Not a Number ) in Java! So, a Float Pointing number is the Data Type and the Value is NaN. See here

在google了一番之后,我发现在Java中可以有NaN(不是数字)!所以,浮点数是数据类型,值是NaN。在这里看到的

#3


12  

double i = Double.NaN;

NaN is not equal to anything, including itself.

NaN不等于任何东西,包括它自己。

#4


10  

float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");

#5


8  

I'm not sure, but I believe (i == i) is not atomic operation in multithreaded process, so if i value will be changed by other thread between pushes of it's value to stack on thread executing the loop, then that condition can be false.

我不确定,但我相信(I == I)在多线程进程中不是原子操作,所以如果我的值在执行循环的线程上推值到堆栈之间被其他线程更改,那么这个条件可能是假的。

#6


8  

Since others said it's NaN I got curious about the official (JDK 6) implementation of Double.isNaN, and behold:

由于其他人说这是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);
}

#7


2  

Think of Nan as the equivalent of exception but uses a magic value within a calculation. Because a calculation failed - eg square root of a negative, divide by zero etc - it makes no sense in comparing them against anything else. After all if divide by zero is a nan is it equivalent to the square root of -2 or square root of -3 ?

把Nan看作是一个例外,但是在计算中使用了一个神奇的值。因为计算失败了——例如负数的平方根,除以0等等——把它们和其他东西作比较是没有意义的。毕竟,如果除以0是nan它等于-2的平方根还是-3的平方根?

Nan allows a calculation that includes a step that returns an invalid answer to complete without introducing extra exceptions. To verify the answer is value simply test for non nandness ( is that's word if not I bags it) via Float.isNan() o equivalent.

Nan允许计算包含一个步骤,该步骤返回无效的答案以完成,而不引入额外的异常。要验证答案是value,只需通过Float.isNan() o等价测试非无意义性(如果不是我包的话,就是这个词)。

#8


2  

I would add

我想补充

float i = Float.NaN;

as well as

以及

double i = Double.NaN;

A common trick in these sort of questions it in the assumption you make that i is an int. Other common assumptions might be s is a String, x,y are a double, ch is a char, b is a byte etc. If you see a question like this you can bet that 'i' is not its expect type.

一种常见的把戏在这些问题在假设你让我是一个int。其他常见的假设可能是一个字符串,x,y是一个双,ch是一个char,b是一个字节等。如果你看到这样的一个问题,你可以打赌,“我”并不是期望类型。

A similar question is; This never loops, what is 'x'

类似的问题;它不会循环,什么是x

while(x == x && x != x + 0) { }

Another question I quite like is; This loop is an infinite loop, what are the possible values of x. (: I count twelve of them :)

我喜欢的另一个问题是;这个循环是一个无限循环,x的可能值是多少?

while(x != 0 && x == -x) { }

#9


0  

I know this is a Java question, but considering the question for other languages is intriguing.

我知道这是一个Java问题,但是考虑其他语言的问题是很有趣的。

In C, a simple type such as 'int' could exhibit 'terminate before the universe grows cold' behaviour if 'i' was declared as a volatile (so the compiler would be forced to do two reads of 'i' for each iteration) and if 'i' was actually in memory where something else could affect it. Then the loop would terminate when 'i' changed between the two reads of a single iteration. (Added: a possible place - in a micro-computer where 'i' is actually located at the address of an I/O port, perhaps connected to a position sensor. It would be more plausible if 'i' was a pointer variable (a pointer to volatile memory) and the statement was 'while (*i == *i);'.)

在C语言中,一个简单的类型,如“int”展览在宇宙变冷之前终止的行为如果宣布“我”作为挥发性(编译器将*做两个读取每个迭代)的“我”,如果“我”实际上是在内存中,其他可能影响它。当一个迭代的两个读取之间的“i”发生变化时,循环就会终止。(补充:一个可能的位置——在微型计算机中,“i”实际上位于i /O端口的地址,可能连接到位置传感器。如果'i'是一个指针变量(指向易失性内存的指针),语句是'while (*i = *i);

As evidenced by other answers, in C++, the '==' operator can be supplied by the user if i is of a user-defined class, so anything might be possible.

从其他答案可以看出,在c++中,“==”操作符可以由用户提供,如果我是用户定义的类,那么任何事情都是可能的。

Rather like NaN, in an SQL-based language, the loop would not be infinite if the value of i was NULL; however, any non-NULL value would make the loop infinite. This is rather like Java, where any number (as opposed to NaN) makes the loop infinite.

与NaN类似,在基于sql的语言中,如果i的值为空,则循环将不是无限的;然而,任何非空值都会使循环成为无限的。这很像Java,任何数字(与NaN相反)都使循环为无穷大。

I do not see the construct having any practical use, but it is an interesting trivia question.

我不认为这个结构有任何实际用途,但它是一个有趣的琐事问题。

#10


0  

I was surprised to not see this solution:

我很惊讶没有看到这样的解决方案:

while (sin(x) == sin(x)) //probably won't eval to true

In response to a comment, try running this:

回复评论时,试着运行以下语句:

double x = 10.5f;
assert (x == asin(sin(x)));

x should always equal the arcsine(sin(x)) in theory, but in practice it doesn't.

x在理论上应该总是等于arcsin (x),但在实践中却不是。

#11


0  

Not infinite loop, one thread :)

不是无限循环,一个线程:)

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);
    }
}

#12


-1  

i == i is not atomic. Proved by such program:

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);
}

Update Here is one more example of not-infinite loop (no new threads are created).

这里的Update是一个非无限循环的例子(没有创建新的线程)。

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);
    }
}