У меня только вопрос, на который я не могу ответить.
Предположим, что у вас есть это определение цикла в Java:
while (i == i) ;
Каков тип i
и значение i
, если цикл не является бесконечным циклом, а программа использует только один поток?
У меня только вопрос, на который я не могу ответить.
Предположим, что у вас есть это определение цикла в Java:
while (i == i) ;
Каков тип i
и значение i
, если цикл не является бесконечным циклом, а программа использует только один поток?
double i = Double.NaN;
API для Double.equals() объясняет ответ: "Double.NaN == Double.NaN имеет значение false". Это описано в Спецификации языка Java в разделе " Типы, форматы и значения с плавающей запятой:
NaN
неупорядочен, поэтому числовое операторы сравнения<
,<=
,>
и>=
returnfalse
, если один или оба операндыNaN
. оператор равенства==
возвращаетfalse
, если либо операндNaN
, и оператор неравенства!=
возвращаетtrue
, если либо операндNaN
. В в частности,x!=x
естьtrue
, если и только еслиx
-NaN
, а(x<y) == !(x>=y)
будет befalse
, еслиx
илиy
NaN
.
Тогда значение i
недействительно. "Не номер".
После некоторого поиска в Google я узнал, что у вас может быть NaN (не номер) на Java! Таким образом, число точек с плавающей точкой - это тип данных, а значение - NaN. См. здесь
double i = Double.NaN;
NaN не равно ничему, включая себя.
float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");
Я не уверен, но я верю (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 позволяет вычислять, который включает в себя шаг, который возвращает недействительный ответ для завершения без введения дополнительных исключений. Для проверки ответа значение просто проверяется на отсутствие nandness (это слово, если не я его суммирую) через Float.isNan() o эквивалентно.
Я бы добавил
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) { }
Я знаю, что это вопрос Java, но рассмотрение вопроса для других языков является интригующим.
В C простой тип, такой как "int", может проявлять "прекращение до того, как вселенная становится холодным", если "i" объявлен как изменчивый (поэтому компилятор будет вынужден делать два чтения "i" для каждая итерация), и если "i" фактически находится в памяти, где что-то еще может повлиять на нее. Тогда цикл завершится, когда "i" изменится между двумя чтениями одной итерации. (Добавлено: возможное место - на микрокомпьютере, где "i" фактически находится по адресу порта ввода-вывода, возможно, подключен к датчику положения. Было бы более правдоподобным, если "i" была переменной указателя ( указатель на энергозависимую память), и выражение было < while (*i == *i);
.)
Как видно из других ответов, в С++ оператор "==" может быть предоставлен пользователем, если я является определяемым пользователем классом, поэтому все может быть возможно.
Скорее, как NaN, на языке на основе SQL цикл не будет бесконечным, если значение я равно 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)) в теории, но на практике это не так.
Не бесконечный цикл, один поток:)
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);
}
}