У меня есть вопрос, на который я не могу ответить.
Предположим, у вас есть это определение цикла в 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является неупорядоченным, поэтому численные операторы сравнения<,<=,>и>=возврат ,falseесли один или оба операндаNaN. Оператор равенства==возвращает значение,falseесли один из операндов равенNaN, а оператор неравенства!=возвращает значение,trueесли какой-либо из операндов равенNaN. В частности,x!=xесть,trueесли и только еслиxестьNaN, и(x<y) == !(x>=y)будет,falseеслиxилиyестьNaN.
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!");
Поскольку другие говорили, что это 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.
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);никогда не будет выполнен.