Tenga en cuenta que la constante 1e309se interpretará como +infy -1e309se interpretará como -inf.
Chris Taylor
Respuestas:
97
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**24.0>>> _**216.0>>> _**2256.0>>> _**265536.0>>> _**24294967296.0>>> _**21.8446744073709552e+19>>> _**23.4028236692093846e+38>>> _**21.157920892373162e+77>>> _**21.3407807929942597e+154>>> _**2Traceback(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.
Sin embargo, una simple adición de flotador, multiplicación, etc. producirá inf: f = 1.3407807929942597e + 154; f * f => inf. Parece más bien una excepción de ** para generar un OverflowError.
eregon
@eregon, en realidad, **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.
Abel
2
@Abel Eso no tiene errores. Desbordarse significa que el número es muy grande. Demasiado grande para representarlo, pero aún más pequeño que el infinito. Poner el infinito en tal lugar puede ser útil para el controlador de excepciones de su lógica de aplicación particular, pero sería incorrecto para Python en general.
Lutz Prechelt
66
@Lutz si aparece como multiplicación, entonces todavía es un comportamiento inconsistente. Ciertamente, big * big tampoco es infinito.
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.
Comparación por desigualdad
Cuando se trata >de <operadores infinitos y mayores o menores que , lo siguiente cuenta:
cualquier comparación que implique NaNes falsa ( infno es mayor ni menor que NaN)
Comparación por igualdad
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.
Cálculos con infinito.
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:
cuando se multiplica por cero, para lo cual el resultado no está definido, produce NaN
al dividir cualquier número (excepto el infinito) por infinito, lo que produce 0.0o -0.0².
al dividir (incluido el módulo) infinito positivo o negativo por infinito positivo o negativo, el resultado es indefinido, entonces NaN.
cuando se hace inf - inf, el resultado es indefinido: NaN;
al hacer inf - -inf, el resultado es inf;
al hacer -inf - inf, el resultado es -inf;
cuando se hace -inf - -inf, el resultado es indefinido: NaN.
al agregar, también puede ser igualmente sorprendente:
al hacer inf + inf, el resultado es inf;
cuando se hace inf + -inf, el resultado es indefinido: NaN;
cuando se hace -inf + inf, el resultado es indefinido: NaN;
al hacer -inf + -inf, el resultado es -inf.
usando 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)exceptOverflowError:
res = float('inf')
Notas
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.
Un pequeño detalle: no todos los cálculos con infinito rinden infinito:-1 * float('infinity') == -inf
Evan Krall
44
Por eso dije que era una pequeña trampa. Me preocupó por un minuto que esa señal se ignoraría totalmente cuando se trabaja con infinito, y quería aclarar para otras personas.
Evan Krall
12
Bueno, casi: 1 / float ('infinito') == 0.0
Phil
3
@ Phil: Aunque estoy bastante seguro de que solo estabas tratando de demostrar que no todos los cálculos con inf resultan en inf o NaN, solo quería dejar en claro a otros que pueden estar leyendo los comentarios, que 1 / float ('infinito ') == 0.0 es verdadero; porque, a medida que se acerca al infinito, el resultado de la división se aproxima a 0. Sé que es solo un cálculo básico, pero quería asegurarme de que los que leen entiendan, o al menos tengan una idea de por qué, el resultado es lo que es.
Anthony Pace
1
Tengo la sensación de que esta respuesta es mucho mejor que la respuesta aceptada.
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".
Entonces, si mi aritmética es demasiado grande, ¿podría convertirse en un inf?
Casebash
@Casebash No, causará un OverflowError.
wizzwizz4
2
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 importFraction>>>from math import inf
>>>3% inf
3.0>>>3.5% inf
3.5>>>Fraction('1/3')% inf
nan
1e309
se interpretará como+inf
y-1e309
se interpretará como-inf
.Respuestas:
Todavía puede obtener valores que no sean un número (NaN) a partir de aritmética simple que involucra
inf
:Tenga en cuenta que normalmente no obtendrá un
inf
valor a través de los cálculos aritméticos habituales:El
inf
valor se considera un valor muy especial con una semántica inusual, por lo que es mejor saber deOverflowError
inmediato a través de una excepción, en lugar de tener uninf
valor silenciosamente inyectado en sus cálculos.fuente
**
parece un poco defectuoso. Cuando se desborda con números reales, arroja un error, pero cuando cualquiera de sus operandos esinf
o-inf
, devuelve0.0
oinf
. 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.
Comparación por desigualdad
Cuando se trata
>
de<
operadores infinitos y mayores o menores que , lo siguiente cuenta:+inf
es mayor que-inf
-inf
es inferior a+inf
+inf
no es ni más alto ni más bajo que+inf
-inf
no es ni más alto ni más bajo que-inf
NaN
es falsa (inf
no es mayor ni menor queNaN
)Comparación por igualdad
Cuando se compara para igualdad,
+inf
y+inf
son iguales, como son-inf
y-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,
+inf
es desigual-inf
y todo, incluido élNaN
mismo, es desigualNaN
.Cálculos con infinito.
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:
NaN
0.0
o-0.0
².NaN
.inf - inf
, el resultado es indefinido:NaN
;inf - -inf
, el resultado esinf
;-inf - inf
, el resultado es-inf
;-inf - -inf
, el resultado es indefinido:NaN
.inf + inf
, el resultado esinf
;inf + -inf
, el resultado es indefinido:NaN
;-inf + inf
, el resultado es indefinido:NaN
;-inf + -inf
, el resultado es-inf
.math.pow
,pow
o**
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 esinf
o-inf
, se comporta correctamente y devuelveinf
o0.0
. Cuando el segundo argumento esNaN
, regresaNaN
, a menos que el primer argumento sea1.0
. Hay más problemas, no todos cubiertos en los documentos .math.exp
sufre los mismos problemas quemath.pow
. Una solución para solucionar esto por desbordamiento es usar un código similar a este:Notas
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.0
rendimientosinf
.Nota 2: debido a que cualquier cálculo con
NaN
retornosNaN
y cualquier comparación conNaN
, incluido élNaN
mismofalse
, debe usar lamath.isnan
función para determinar si un número es realmenteNaN
.Nota 3: aunque Python admite la escritura
float('-NaN')
, el signo se ignora porque no existe ningún signoNaN
interno. Si divide-inf / +inf
, el resultado es queNaN
no-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')
rendimientos0.0
y-1/ float(-inf)
rendimientos0.0
. Además,0.0 == -0.0
es necesariotrue
verificar manualmente el signo si no desea que sea cierto.fuente
-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".
fuente
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: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 .
fuente
en una
1/x
fracción, hastax = 1e-323
que esinf
pero cuandox = 1e-324
o poco arrojaZeroDivisionError
así que ten cuidado!
fuente