Відповіді:
Ви все ще можете отримати не-число (NaN) з простої арифметики, що включає inf:
>>> 0 * float("inf")
nan
Зауважте, що зазвичай ви не отримаєте infзначення за допомогою звичайних арифметичних обчислень:
>>> 2.0**2
4.0
>>> _**2
16.0
>>> _**2
256.0
>>> _**2
65536.0
>>> _**2
4294967296.0
>>> _**2
1.8446744073709552e+19
>>> _**2
3.4028236692093846e+38
>>> _**2
1.157920892373162e+77
>>> _**2
1.3407807929942597e+154
>>> _**2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')
infЗначення вважається дуже особливим значенням з незвичайною семантикою, так що краще знати про OverflowErrorодразу через виключення, а не має infзначення мовчки впорскується в свої розрахунки.
**здається, невдалий баггі. Коли він переповнюється з речовими числами, він видає помилку, але коли який - або з її операндів infабо -infвона повертає або 0.0або inf. Так що робить роботу правильно , коли вхід inifinty, але не тоді , коли результат повинен бути нескінченність.
Реалізація мови Python слід стандарту IEEE-754 , дуже добре, що ви можете використовувати в якості керівництва, але вона спирається на основній системі він був складений на, так відмінність платформи може статися. Останнім часом¹ було застосовано виправлення, яке дозволяє «нескінченність», а також «inf» , але це тут має незначне значення.
Наступні розділи однаково добре стосуються будь-якої мови, яка правильно реалізує арифметику з плаваючою точкою IEEE, вона не характерна лише для Python.
При роботі з нескінченністю та операторами, що перевищують більшу >чи меншу <кількість, враховується наступне:
+infперевищує-inf-inf, нижче+inf +infне є ні вищим, ні нижчим за+inf-inf не є ні вищим, ні нижчим за -infNaNпомилково ( infні вище, ні нижче , ніж NaN)Якщо порівнювати рівність, +infі +infвони рівні, як -infі -inf. Це дуже дискусійне питання і може здатися вам суперечливим, але це в стандарті IEEE і Python поводиться просто так.
Звичайно, +infвона нерівна -infі все, включаючи NaNсебе, нерівне NaN.
Більшість обчислень з нескінченністю дасть нескінченність, якщо тільки обидва операнди не є нескінченними, коли ділення операції або модуль, або при множенні на нуль, є деякі спеціальні правила, які слід пам’ятати:
NaN0.0або -0.0².NaN.inf - inf, то результат не визначений: NaN;inf - -inf, результат є inf;-inf - inf, результат є -inf;-inf - -inf, то результат не визначений: NaN.inf + inf, результат є inf;inf + -inf, то результат не визначений: NaN;-inf + inf, то результат не визначений: NaN;-inf + -inf, результат є -inf.math.pow, powабо **складно, так як вона не поводиться , як це повинно бути. Він кидає виняток переповнення , коли результат з двома числами занадто високий , щоб відповідати подвійної точності з плаваючою точкою (вона повинна повертати нескінченність), але коли вхід infабо -infвін веде себе правильно і повертає або infабо 0.0. Коли другий аргумент є NaN, він повертається NaN, якщо не є перший аргумент 1.0. Існує більше питань, не всі висвітлені в документах .math.expстраждає від тих же питань, що і math.pow. Рішенням, щоб виправити це для переповнення, є використання аналогічного цьому коду:
try:
res = math.exp(420000)
except OverflowError:
res = float('inf')Примітка 1: як додатковий застереження, що, як визначено стандартом IEEE, якщо результат обчислення є недостатнім або переливним, результат буде не помилкою перевантаження або переливу, а позитивною чи негативною нескінченністю: 1e308 * 10.0врожайність inf.
Примітка 2: оскільки будь-який обчислення із NaNповерненнями NaNта будь-яке порівняння NaN, включаючи NaNсаме себе false, слід скористатися math.isnanфункцією, щоб визначити, чи дійсно число NaN.
Примітка 3: хоча Python підтримує запис float('-NaN'), цей знак ігнорується, оскільки немає NaNвнутрішнього знаку . Якщо розділити -inf / +inf, результат є NaN, ні -NaN(немає такого).
Примітка 4: будьте обережні, покладайтеся на будь-що з вищезазначеного, оскільки Python покладається на бібліотеку C або Java, для якої вона була складена, і не всі базові системи правильно реалізують цю поведінку. Якщо ви хочете бути впевнені, протестуйте на нескінченність, перш ніж робити свої розрахунки.
¹) Останнім часом означає з версії 3.2 .
²) Плаваючі точки підтримують позитивний та негативний нуль, тому: x / float('inf')зберігає свій знак і -1 / float('inf')врожайність -0.0, 1 / float(-inf)врожайність -0.0, 1 / float('inf')урожайність 0.0та -1/ float(-inf)врожайність 0.0. Крім того, 0.0 == -0.0цеtrue , ви повинні вручну перевірити знак , якщо ви не хочете , щоб це було правдою.
-1 * float('infinity') == -inf
Так само і C99 .
Представлення IEEE 754 з плаваючою комою, яке використовується всіма сучасними процесорами, має кілька спеціальних бітових шаблонів, зарезервованих для позитивної нескінченності (знак = 0, exp = ~ 0, frac = 0), негативної нескінченності (знак = 1, exp = ~ 0, frac = 0 ), і багато NaN (не число: exp = ~ 0, frac ≠ 0).
Все, про що потрібно турбуватися: деякі арифметики можуть спричинити винятки / пастки з плаваючою комою, але вони не обмежуються лише цими "цікавими" константами.
OverflowError.
Я знайшов застереження, про яке ніхто досі не згадував. Я не знаю, чи часто це траплятиметься в практичних ситуаціях, але ось це заради повноти.
Зазвичай, обчислення числа модуля нескінченності повертає себе як поплавок, але частка модульної нескінченності повертається nan(не число). Ось приклад:
>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan
Я подав проблему на трекер помилок Python. Його можна побачити на https://bugs.python.org/issue32968 .
Оновлення: це буде виправлено в Python 3.8 .
ДУЖЕ БАГИЙ КАВАТ: Відділення за нулем
в 1/xчастці, до x = 1e-323цього є, infале коли x = 1e-324або мало він кидаєZeroDivisionError
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
так що будьте обережні!
1e309буде інтерпретуватися як+infі-1e309буде інтерпретуватися як-inf.