Для какого значения i делает цикл while (i == i + 1) {} навсегда? - PullRequest
0 голосов
/ 28 ноября 2018

Я наткнулся на эту загадку из курса продвинутого программирования на экзамене в университете Великобритании .

Рассмотрим следующий цикл, в котором я до сих пор не объявлен:

while (i == i + 1) {}

Найдите определение i, предшествующее этому циклу, , такое, что цикл while продолжается вечно.

Следующий вопрос, который задавал тот же вопрос для этогофрагмент кода:

while (i != i) {}

был для меня очевиден.Конечно, в этой другой ситуации это NaN, но я действительно застрял в предыдущей.Это связано с переполнением?Что заставило бы такой цикл зацикливаться навсегда в Java?

Ответы [ 4 ]

0 голосов
/ 09 декабря 2018

double i = Double.POSITIVE_INFINITY;

0 голосов
/ 28 ноября 2018

Эти головоломки подробно описаны в книге Джошуа Блоха и Нила Гафтера "Java Puzzlers: ловушки, ловушки и угловые случаи".

double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}

или:

double i = 1.0e40;
while (i == i + 1) {}

оба приведут к бесконечному циклу, потому что добавление 1 к значению с плавающей точкой, которое является достаточно большим, не изменит значение, потому что оно не "соединит пробел" со своим преемником 1 .

Примечание о второй загадке (для будущих читателей):

double i = Double.NaN;
while (i != i) {}

также приводит к бесконечному циклу, поскольку NaN не равно ни одному значению с плавающей запятой,включая самого себя 2 .


1 - Java Puzzlers: ловушки, ловушки и угловые случаи (глава 4 - Loopy Puzzlers).

2 - JLS §15.21.1

0 голосов
/ 29 ноября 2018

Просто идея: как насчет логических значений?

bool i = TRUE;

Разве это не случай, когда i + 1 == i?

0 голосов
/ 28 ноября 2018

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

.Таких значений много:

Давайте начнем с «экзотических»:

double i = Double.POSITIVE_INFINITY;

или

double i =  Double.NEGATIVE_INFINITY;

Причина, по которой эти значения удовлетворяют i == i + 1, заключается вуказано в
JLS 15.18.2.Аддитивные операторы (+ и -) для числовых типов :

Сумма бесконечности и конечного значения равна бесконечному операнду.

Это не удивительно, поскольку добавление конечного значения к бесконечному значению должно привести к бесконечному значению.

Тем не менее, большинство значений i, которые удовлетворяют i == i + 1, являются просто большими double (или float) значениями:

Например:

double i = Double.MAX_VALUE;

или

double i = 1000000000000000000.0;

или

float i = 1000000000000000000.0f;

Типы double и float имеют ограниченную точность, поэтому, если вы берете достаточно большое значение double или float значение, добавление 1 к нему приведет к тому же значению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...