Що таке NaN у математиці
NaN все ще може трохи здивувати
Спочатку, я подумав, що це чергове питання з тих, які можуть задаватися на співбесіді. ні, на що можна спертися в міркуваннях. Але марно! вдається. У чому потрібно розбиратися, щоб він був знайдений?
Відповідь повинна бути NaN. Але чому я не впевнений у цьому? ZeroDivisionError.Сто відсотків NaN!
Вводжу вираз у комірку блокнота:
Справді?
>>> arange(5)**nan array([nan, 1., nan, nan, nan])
Тобто з якоїсь причини одиниця в ступені NaN — це одиниця, а ось нуль і всі інші числа в ступені NaN — це NaN.
Може, я просто через відсутність якоїсь практичної потреби в глибоких знаннях про NaN, просто про щось не підозрював?А може я знав, але забув?
Заходимо на Вікіпедію. Там це питання також позначене як проблема, але чому все саме так влаштовано, ніяк не пояснюється.
Що, погодьтеся, теж трохи дивно.
Гаразд, з Вікіпедії вирушаємо до C99 на 182 сторінку і нарешті отримуємо логічне пояснення, чому pow(x, 0) повертає 1 для будь-яких x, навіть для x рівного NaN:
Якщо функція зводиться в ступінь і при цьому прагне 0, то в результаті вийде 1 незалежно від того, яке значення має .
А якщо результат не залежить від числового значення функції , то 1 є підходящим результатом, навіть для NaN. Однак це, як і раніше, не пояснює, чому 1 у ступені NaN дорівнює 1.
Шукаємо ще один C99 і на 461 сторінці не бачимо жодних пояснень, просто вимога того, що pow(+1, y) має повертати 1 для всіх yнавіть рівних NaN. Усі.
З іншого боку, пояснення, чому pow (NaN, 0) = 1 є кращим, ніж pow(NaN, 0)=NaN все-таки наштовхує на думку про те, що NaN не варто сприймати буквально, як Not-a-Number. Допустимо, в результаті якихось обчислень ми отримали число, що перевищує розмір пам'яті, виділений під даний тип чисел, наприклад:
В результаті ми отримали inf, що саме це за число ми не знаємо, але все ж таки це якесь число. Потім ми знову щось вирахували і знову отримали надто велику кількість:
Різниця a і b поверне NaN:
Єдина причина, через яку ми можемо вважати c не числом, у тому, що ми використовували недостатньо точні обчислення. Однак, у c під NaN все ж таки ховається якесь значення. Про те, що це за значення, ми не знаємо. Але все ж таки це число, а раз це число, то немає нічого дивного в тому, що pow(1, NaN)=1.
Чому ж тоді pow(0, NaN) = NaN? Справа в тому, що якщо звести 0 у будь-який ступінь, то ми дійсно отримаємо нуль. Крім одного єдиного випадку - коли ступінь дорівнює 0:
Через що у виразі pow(0, NaN) з'являється невизначеність із конкретним значенням NaN. Звісно, ймовірність того, що під NaN може ховатися 0 — зникаюче мала і можна було б прийняти, що pow(0, NaN)=0. Але все ж таки краще перестрахуватися, чи мало до чого це може привести. Можливо, так міркували, коли створювалися стандарти.
Навіть не знаю, що сказати. якщо ви заздалегідь знали відповідь, то швидше за все вам можна позаздрити, адже сфери, де можуть стати в нагоді такі знання, напевно, переповнені цікавими завданнями. А може й навпаки. Напишіть про це у коментарях.
P.S. Оскільки NaN відноситься до числа з плаваючою точкою, воно може бути ключем словника: