Щойно у мене виникло питання, на яке я не можу відповісти.
Припустимо, у вас є таке визначення циклу на 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тоді і тільки тоді , колиxISNaN, і(x<y) == !(x>=y)будеfalseчиxабоyцеNaN.
x == xзавжди має бути правдою. Чому щось не має собі рівних?
null=nullнемає. NULL IS NULLє 1.
Значення iтоді недійсне. "Не число".
Після деякого гуглінгу я дізнався, що ви можете мати NaN (не число) на Java! Отже, число плаваючої точки - це тип даних, а значення - 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 () o еквівалент.
Я додам
float i = Float.NaN;
так само, як
double i = Double.NaN;
Загальна хитрість у подібних питаннях, якщо ви вважаєте, що я є цілим. Іншими поширеними припущеннями можуть бути s - це String, x, y - це подвійний, ch - char, b - байт і т.д.
Подібне питання є; Це ніколи не циклічно, що таке "х"
while(x == x && x != x + 0) { }
Ще одне питання, яке мені дуже подобається, це; Ця петля - це нескінченний цикл, які можливі значення х. (: Я їх нараховую дванадцять :)
while(x != 0 && x == -x) { }
Я знаю, що це питання Java, але розгляд питання для інших мов інтригує.
У C такий простий тип, як "int", може виявити "закінчуватись до того, як Всесвіт стає холодною", якщо "i" було оголошено мінливим (тому компілятор буде змушений робити два читання "i" для кожної ітерації) і якщо "я" насправді був у пам'яті, де щось інше могло би вплинути на це. Тоді цикл закінчується, коли 'я' змінюється між двома читаннями однієї ітерації. ( Додано : можливе місце - в мікрокомп'ютері, де фактично розташований "i" за адресою порту вводу / виводу, можливо, підключений до датчика позиції. Це було б більш правдоподібно, якби "i" була змінною вказівника ( вказівник на мінливу пам'ять), а висловлювання було " while (*i == *i);".)
Як свідчать інші відповіді, в C ++ оператор '==' може бути наданий користувачем, якщо я є визначеним користувачем класом, тому все може бути можливим.
Замість 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);звичаю ніколи не виконується.