о, ради бога, будут ли люди иметь честь прокомментировать, почему они голосуют против? это помечено как загадка, в чем проблема ???
user54579
10
Я думаю, что некоторые люди не могут перестать голосовать ни за что.
FerranB
1
Ба, извините за причину этого: / Я действительно просто хотел получить ответ, и я не мог решить его для себя.
Zizzencs,
1
@nickolai, такова природа SO - к сожалению, отрицательное голосование стало реальностью, и идея запроса комментария была обсуждена и отвергнута. Но, похоже, «сообщество» все-таки поддерживает этот вопрос.
paxdiablo
1
Один из приемов такого рода вопросов заключается в том, что люди предполагают тип определенных имен переменных, то есть i - int, d - двойное, s - строка или короткое, ch - char, l - длинное, b для байт или логическое значение. Вы должны спросить себя, какой тип предлагается и что это может быть.
NaNявляется неупорядоченным, поэтому численные операторы сравнения <, <=, >и >=
возврат , falseесли один или оба операнда NaN. Оператор равенства ==возвращает значение, falseесли один из операндов равен NaN, а оператор неравенства !=возвращает значение, trueесли какой-либо из операндов равен NaN. В частности, x!=xесть, trueесли и только если xестьNaN , и (x<y) == !(x>=y)будет, falseесли xили yесть NaN.
это математически твердо, почему одно нереальное число должно равняться другому? 5/0! = Sqrt (-4)
Гордон Густафсон,
2
@CrazyJugglerDrummer: Возможно, но то же самое x == xвсегда должно быть правдой. Почему ничто не должно равняться самому себе?
Bart van Heukelom
1
Барт: потому что на самом деле неизвестное не всегда равно неизвестному. Иногда это полезно, поэтому базы данных имеют NULL ...
Konerak
2
@inovaovao: нет, в БД null=null- null. NULL IS NULLсоставляет 1.
Konerak
29
Тогда значение iнедопустимо. «Не число».
После некоторого поиска в Google я обнаружил, что в Java МОЖЕТ быть NaN (не число)! Итак, число с плавающей точкой - это тип данных, а значение - NaN. Смотрите здесь
Я вообще ненавижу людей, которые голосуют против без всякой причины ... Я был первым, кто сказал «Не число», но не думал, что java может справиться с этим, поскольку он не справляется ни с чем другим классным.
Я не уверен, но я считаю, что (i == i) не является атомарной операцией в многопоточном процессе, поэтому, если значение i будет изменено другим потоком между толчками его значения в стек в потоке, выполняющем цикл, тогда это условие может быть ложным.
Поскольку другие говорили, что это 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.
*/staticpublicbooleanisNaN(double v){
return (v != v);
}
Думайте о Nan как о эквиваленте исключения, но при вычислении использует магическое значение. Поскольку расчет не удался - например, квадратный корень из отрицательного числа, разделение на ноль и т.д. - нет смысла сравнивать их с чем-либо еще. В конце концов, если разделить на ноль - это нана, то это эквивалентно квадратному корню из -2 или квадратному корню из -3?
Nan допускает вычисление, которое включает шаг, возвращающий неверный ответ, для завершения без введения дополнительных исключений. Чтобы убедиться, что ответ - это значение, просто проверьте его на ненадежность (это слово, если я не упаковываю его) через эквивалент Float.isNan ().
Было бы легче думать об этом как об исключении, но если бы я действительно знал, что такое исключение :-).
paxdiablo
2
Я бы добавил
float i = Float.NaN;
также как и
double i = Double.NaN;
Обычный трюк в подобных вопросах - это предположение, что i - это int. Другими распространенными предположениями могут быть s - это String, x, y - двойные, ch - char, b - байтовые и т. Д. Если вы видите такой вопрос, вы можете поспорить, что «i» не является ожидаемым типом.
Аналогичный вопрос; Это никогда не зацикливается, что такое 'x'
while(x == x && x != x + 0) { }
Еще один вопрос, который мне очень нравится: Этот цикл представляет собой бесконечный цикл, каковы возможные значения x. (: Я насчитал их двенадцать :)
Я знаю, что это вопрос Java, но рассмотрение вопроса для других языков интригует.
В C простой тип, такой как 'int', может демонстрировать поведение 'завершиться до того, как вселенная остынет', если 'i' был объявлен как изменчивый (поэтому компилятор был бы вынужден выполнять два чтения 'i' для каждой итерации) и если «я» действительно было в памяти, на него могло повлиять что-то еще. Затем цикл завершился бы, когда «i» изменилось между двумя чтениями одной итерации. ( Добавлено : возможное место - в микрокомпьютере, где 'i' фактически находится по адресу порта ввода-вывода, возможно, подключенного к датчику положения. Было бы более правдоподобно, если бы 'i' было переменной-указателем ( указатель на энергозависимую память), а оператор был ' while (*i == *i);'.)
Как свидетельствуют другие ответы, в С ++ оператор '==' может быть предоставлен пользователем, если я принадлежит к пользовательскому классу, поэтому все может быть возможным.
Скорее, как NaN, в языке, основанном на SQL, цикл не был бы бесконечным, если бы значение i было NULL; однако любое значение, отличное от NULL, сделает цикл бесконечным. Это больше похоже на Java, где любое число (в отличие от NaN) делает цикл бесконечным.
Я не вижу практического применения этой конструкции, но это интересный вопрос, связанный с пустяками.
Почему нет? Вы выполняете точно такой же расчет на одних и тех же данных, оба результата будут содержать одну и ту же ошибку.
Loren Pechtel
Я не могу точно вспомнить, где я это читал, но в зависимости от вашей машины / реализации, sin (x) при одном вызове функции имеет минимальный шанс сравняться с sin (x) другого вызова. Это связано с точностью цифр с плавающей запятой (что-то особенное в функциях триггеров, из-за которых они не возвращают одно и то же значение дважды).
jkeys
Смотрите мое обновление. Арксинус «отменяет» грех x, поэтому они должны быть равны, но это не так.
jkeys
Это не одно и то же. Как сказала Лорен, вы выполняете ту же самую операцию x, которая должна дать точно такой же результат с той же неточностью. Arcsin не может отменить результат греха с числами с плавающей запятой, потому что переданное значение asin()не будет точно точным. Следовательно, результат asin()будет неточным, сделав x == asin(sin(x))ложным. Кроме того, arcsin не обязательно «отменяет» операцию sin - функция sin может дать тот же результат для нескольких значений x, поэтому asin()возвращает только числа от -π / 2 до π / 2.
hbw
2
Другими словами, arcsin не всегда может «отменить» функцию sin, потому что arcsin не может знать, каким был исходный угол. Например, грех как π / 2, так и 5π / 2 дает 1. Но что такое arcsin (1)? Очевидно, он не может вернуть оба, верно? Следовательно, результат arcsin должен быть ограничен диапазоном 2π радиан, что означает, что он не может фактически отменить результат функции sin, если исходный угол не находится между 0 и 2π, или, в случае C, -π / 2 и π / 2. (Действительно, arcsin (sin (5π / 2)) = π / 2.) В любом случае, это было действительно длинное объяснение, но я надеюсь, что это поможет прояснить любые заблуждения.
@Charles Goodwin То, что вы говорите о том, что нет возможности написать программу на Java с использованием одного потока :), поэтому все другие решения используют как минимум два потока (точно так же, как моя вторая программа в разделе «Обновление»).
Андрей
Это не тормозит петлю. Любой код после while (i == i);никогда не будет выполнен.
aalku
Finalize использует другой поток, но стоит отметить его. Это причина, по которой в исходном вопросе говорилось: «а программа использует только один поток» ... как бы явно заявляя, что это очевидный ответ, и они хотят, чтобы вы посмотрели дальше.
Ответы:
double i = Double.NaN;
API для Double.equals () дает ответ: «Double.NaN == Double.NaN имеет значение false». Это подробно описано в Спецификации языка Java в разделе « Типы, форматы и значения с плавающей запятой »:
источник
x == x
всегда должно быть правдой. Почему ничто не должно равняться самому себе?null=null
- null.NULL IS NULL
составляет 1.Тогда значение
i
недопустимо. «Не число».После некоторого поиска в Google я обнаружил, что в Java МОЖЕТ быть NaN (не число)! Итак, число с плавающей точкой - это тип данных, а значение - NaN. Смотрите здесь
источник
double i = Double.NaN;
NaN не равен чему-либо, в том числе самому себе.
источник
float i = Float.NaN; while(i == i) ; System.out.println("Not infinite!");
источник
Я не уверен, но я считаю, что (i == i) не является атомарной операцией в многопоточном процессе, поэтому, если значение i будет изменено другим потоком между толчками его значения в стек в потоке, выполняющем цикл, тогда это условие может быть ложным.
источник
Поскольку другие говорили, что это 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 как о эквиваленте исключения, но при вычислении использует магическое значение. Поскольку расчет не удался - например, квадратный корень из отрицательного числа, разделение на ноль и т.д. - нет смысла сравнивать их с чем-либо еще. В конце концов, если разделить на ноль - это нана, то это эквивалентно квадратному корню из -2 или квадратному корню из -3?
Nan допускает вычисление, которое включает шаг, возвращающий неверный ответ, для завершения без введения дополнительных исключений. Чтобы убедиться, что ответ - это значение, просто проверьте его на ненадежность (это слово, если я не упаковываю его) через эквивалент Float.isNan ().
источник
Я бы добавил
float i = Float.NaN;
также как и
double i = Double.NaN;
Обычный трюк в подобных вопросах - это предположение, что i - это int. Другими распространенными предположениями могут быть s - это String, x, y - двойные, ch - char, b - байтовые и т. Д. Если вы видите такой вопрос, вы можете поспорить, что «i» не является ожидаемым типом.
Аналогичный вопрос; Это никогда не зацикливается, что такое 'x'
while(x == x && x != x + 0) { }
Еще один вопрос, который мне очень нравится: Этот цикл представляет собой бесконечный цикл, каковы возможные значения x. (: Я насчитал их двенадцать :)
while(x != 0 && x == -x) { }
источник
Я знаю, что это вопрос Java, но рассмотрение вопроса для других языков интригует.
В C простой тип, такой как 'int', может демонстрировать поведение 'завершиться до того, как вселенная остынет', если 'i' был объявлен как изменчивый (поэтому компилятор был бы вынужден выполнять два чтения 'i' для каждой итерации) и если «я» действительно было в памяти, на него могло повлиять что-то еще. Затем цикл завершился бы, когда «i» изменилось между двумя чтениями одной итерации. ( Добавлено : возможное место - в микрокомпьютере, где 'i' фактически находится по адресу порта ввода-вывода, возможно, подключенного к датчику положения. Было бы более правдоподобно, если бы 'i' было переменной-указателем ( указатель на энергозависимую память), а оператор был '
while (*i == *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 не может отменить результат греха с числами с плавающей запятой, потому что переданное значениеasin()
не будет точно точным. Следовательно, результатasin()
будет неточным, сделавx == asin(sin(x))
ложным. Кроме того, arcsin не обязательно «отменяет» операцию sin - функция sin может дать тот же результат для нескольких значений x, поэтомуasin()
возвращает только числа от -π / 2 до π / 2.Не бесконечный цикл, один поток :)
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); } }
источник
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);
никогда не будет выполнен.