Как можно "while (i == i)"; быть бесконечным циклом в однопоточном приложении?

У меня только вопрос, на который я не могу ответить.

Предположим, что у вас есть это определение цикла в Java:

while (i == i) ;

Каков тип i и значение i, если цикл не является бесконечным циклом, а программа использует только один поток?

Ответ 1

double i = Double.NaN;

API для Double.equals() объясняет ответ: "Double.NaN == Double.NaN имеет значение false". Это описано в Спецификации языка Java в разделе " Типы, форматы и значения с плавающей запятой:

NaN неупорядочен, поэтому числовое операторы сравнения <, <=, > и >=return false, если один или оба операнды NaN. оператор равенства == возвращает false, если либо операнд NaN, и оператор неравенства != возвращает true, если либо операнд NaN. В в частности, x!=x есть true, если и только если x - NaN, а (x<y) == !(x>=y) будет be false, если x или y NaN.

Ответ 2

Тогда значение i недействительно. "Не номер".

После некоторого поиска в Google я узнал, что у вас может быть NaN (не номер) на Java! Таким образом, число точек с плавающей точкой - это тип данных, а значение - NaN. См. здесь

Ответ 3

double i = Double.NaN;

NaN не равно ничему, включая себя.

Ответ 4

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

Ответ 5

Я не уверен, но я верю (i == i) не является атомарной операцией в многопоточном процессе, поэтому, если значение я будет изменено другим потоком между нажатиями этого значения на стек в потоке, выполняющем цикл, тогда это условие может быть ложным.

Ответ 6

Так как другие сказали, что это 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

Подумайте, что Nan является эквивалентом исключения, но использует волшебное значение в вычислении. Поскольку расчет не выполнен - ​​например, квадратный корень отрицательного, делим на ноль и т.д. - нет смысла сравнивать их с чем-либо еще. В конце концов, если деление на ноль является наном, оно эквивалентно квадратному корню из -2 или квадратного корня из -3?

Nan позволяет вычислять, который включает в себя шаг, который возвращает недействительный ответ для завершения без введения дополнительных исключений. Для проверки ответа значение просто проверяется на отсутствие nandness (это слово, если не я его суммирую) через Float.isNan() o эквивалентно.

Ответ 8

Я бы добавил

float i = Float.NaN;

а также

double i = Double.NaN;

Общим трюком в подобных вопросах он в предположении, что вы делаете i, является int. Другими распространенными предположениями могут быть s - String, x, y - double, ch - char, b - байт и т.д. Если вы увидите такой вопрос, вы можете сделать ставку, что "i" не является его ожидаемым типом.

Аналогичный вопрос: Это никогда не зацикливается, что такое "x"

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

Еще один вопрос, который мне очень нравится; Этот цикл представляет собой бесконечный цикл, каковы возможные значения x. (: Я считаю двенадцать из них:)

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

Ответ 9

Я знаю, что это вопрос Java, но рассмотрение вопроса для других языков является интригующим.

В C простой тип, такой как "int", может проявлять "прекращение до того, как вселенная становится холодным", если "i" объявлен как изменчивый (поэтому компилятор будет вынужден делать два чтения "i" для каждая итерация), и если "i" фактически находится в памяти, где что-то еще может повлиять на нее. Тогда цикл завершится, когда "i" изменится между двумя чтениями одной итерации. (Добавлено: возможное место - на микрокомпьютере, где "i" фактически находится по адресу порта ввода-вывода, возможно, подключен к датчику положения. Было бы более правдоподобным, если "i" была переменной указателя ( указатель на энергозависимую память), и выражение было < while (*i == *i);.)

Как видно из других ответов, в С++ оператор "==" может быть предоставлен пользователем, если я является определяемым пользователем классом, поэтому все может быть возможно.

Скорее, как NaN, на языке на основе SQL цикл не будет бесконечным, если значение я равно NULL; однако любое значение, отличное от NULL, сделает цикл бесконечным. Это скорее похоже на Java, где любое число (в отличие от NaN) делает цикл бесконечным.

Я не вижу конструкцию, имеющую какое-либо практическое применение, но это интересный мелочи.

Ответ 10

Я был удивлен, увидев это решение:

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

В ответ на комментарий попробуйте запустить это:

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

x всегда должно равняться арксине (sin (x)) в теории, но на практике это не так.

Ответ 11

Не бесконечный цикл, один поток:)

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

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