Respuestas:
Todavía puede obtener valores que no sean un número (NaN) a partir de aritmética simple que involucra inf:
>>> 0 * float("inf")
nan
Tenga en cuenta que normalmente no obtendrá un infvalor a través de los cálculos aritméticos habituales:
>>> 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')
El infvalor se considera un valor muy especial con una semántica inusual, por lo que es mejor saber de OverflowErrorinmediato a través de una excepción, en lugar de tener un infvalor silenciosamente inyectado en sus cálculos.
**parece un poco defectuoso. Cuando se desborda con números reales, arroja un error, pero cuando cualquiera de sus operandos es info -inf, devuelve 0.0o inf. Por lo que hace el trabajo correctamente cuando la entrada es inifinty, pero no cuando el resultado debe ser infinito.
La implementación de Python sigue el estándar IEEE-754 bastante bien, que puede usar como guía, pero se basa en el sistema subyacente en el que se compiló, por lo que pueden producirse diferencias de plataforma . Recientemente¹, se ha aplicado una solución que permite "infinito" así como "inf" , pero aquí es de menor importancia.
Las siguientes secciones se aplican igualmente a cualquier lenguaje que implemente la aritmética de coma flotante IEEE correctamente, no es específico solo de Python.
Cuando se trata >de <operadores infinitos y mayores o menores que , lo siguiente cuenta:
+infes mayor que-inf-infes inferior a+inf +infno es ni más alto ni más bajo que+inf-inf no es ni más alto ni más bajo que -infNaNes falsa ( infno es mayor ni menor que NaN)Cuando se compara para igualdad, +infy +infson iguales, como son -infy -inf. Este es un tema muy debatido y puede sonar controvertido para usted, pero está en el estándar IEEE y Python se comporta así.
Por supuesto, +infes desigual -infy todo, incluido él NaNmismo, es desigual NaN.
La mayoría de los cálculos con infinito producirán infinito, a menos que ambos operandos sean infinitos, cuando la división o módulo de operación, o con multiplicación con cero, hay algunas reglas especiales a tener en cuenta:
NaN0.0o -0.0².NaN.inf - inf, el resultado es indefinido: NaN;inf - -inf, el resultado es inf;-inf - inf, el resultado es -inf;-inf - -inf, el resultado es indefinido: NaN.inf + inf, el resultado es inf;inf + -inf, el resultado es indefinido: NaN;-inf + inf, el resultado es indefinido: NaN;-inf + -inf, el resultado es -inf.math.pow, powo **es complicado, ya que no se comporta como debería. Lanza una excepción de desbordamiento cuando el resultado con dos números reales es demasiado alto para ajustarse a un flotador de doble precisión (debería devolver infinito), pero cuando la entrada es info -inf, se comporta correctamente y devuelve info 0.0. Cuando el segundo argumento es NaN, regresa NaN, a menos que el primer argumento sea 1.0. Hay más problemas, no todos cubiertos en los documentos .math.expsufre los mismos problemas que math.pow. Una solución para solucionar esto por desbordamiento es usar un código similar a este:
try:
res = math.exp(420000)
except OverflowError:
res = float('inf')Nota 1: como advertencia adicional, según lo definido por el estándar IEEE, si el resultado de su cálculo se desborda o desborda, el resultado no será un error de desbordamiento o desbordamiento, sino infinito positivo o negativo: 1e308 * 10.0rendimientos inf.
Nota 2: debido a que cualquier cálculo con NaNretornos NaNy cualquier comparación con NaN, incluido él NaNmismo false, debe usar la math.isnanfunción para determinar si un número es realmente NaN.
Nota 3: aunque Python admite la escritura float('-NaN'), el signo se ignora porque no existe ningún signo NaNinterno. Si divide -inf / +inf, el resultado es que NaNno -NaN(no existe tal cosa).
Nota 4: tenga cuidado de confiar en cualquiera de los anteriores, ya que Python se basa en la biblioteca C o Java para la que fue compilada y no todos los sistemas subyacentes implementan todo este comportamiento correctamente. Si quieres estar seguro, prueba el infinito antes de hacer tus cálculos.
¹) Recientemente significa desde la versión 3.2 .
²) Los puntos flotantes admiten cero positivo y negativo, por lo tanto: x / float('inf')mantiene su signo y -1 / float('inf')rendimientos -0.0, 1 / float(-inf)rendimientos -0.0, 1 / float('inf')rendimientos 0.0y -1/ float(-inf)rendimientos 0.0. Además, 0.0 == -0.0es necesariotrue verificar manualmente el signo si no desea que sea cierto.
-1 * float('infinity') == -inf
También lo hace C99 .
La representación de coma flotante IEEE 754 utilizada por todos los procesadores modernos tiene varios patrones de bits especiales reservados para infinito positivo (signo = 0, exp = ~ 0, frac = 0), infinito negativo (signo = 1, exp = ~ 0, frac = 0 ) y muchos NaN (no es un número: exp = ~ 0, frac ≠ 0).
Todo de lo que debe preocuparse: algunas operaciones aritméticas pueden causar excepciones / trampas de coma flotante, pero estas no se limitan solo a estas constantes "interesantes".
OverflowError.
Encontré una advertencia que nadie hasta ahora ha mencionado. No sé si se presentará a menudo en situaciones prácticas, pero aquí es en aras de la integridad.
Por lo general, el cálculo de un número de módulo de infinito se devuelve como flotante, pero una fracción de módulo de infinito se devuelve nan(no un número). Aquí hay un ejemplo:
>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan
Archivé un problema en el rastreador de errores de Python. Se puede ver en https://bugs.python.org/issue32968 .
Actualización: esto se solucionará en Python 3.8 .
UNA CUEVA MUY MALA: División por cero
en una 1/xfracción, hasta x = 1e-323que es infpero cuando x = 1e-324o poco arrojaZeroDivisionError
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
así que ten cuidado!
1e309se interpretará como+infy-1e309se interpretará como-inf.