Respostas:
Você ainda pode obter valores não-numéricos (NaN) a partir de aritmética simples, envolvendo inf:
>>> 0 * float("inf")
nan
Observe que você normalmente não obterá um infvalor através de cálculos aritméticos usuais:
>>> 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')
O infvalor é considerado um valor muito especial com semântica incomum; portanto, é melhor saber OverflowErrorimediatamente sobre uma exceção, em vez de ter um infvalor injetado silenciosamente em seus cálculos.
**parece um buggy. Quando transborda com números reais, gera um erro, mas quando qualquer um de seus operandos é infor -inf, ele retorna 0.0ou inf. Por isso, faz trabalho corretamente quando a entrada é inifinty, mas não quando o resultado deve ser infinito.
A implementação do Python segue muito bem o padrão IEEE-754 , que você pode usar como orientação, mas depende do sistema subjacente no qual foi compilado, para que possam ocorrer diferenças de plataforma . Recentemente¹, foi aplicada uma correção que permite "infinito" e "inf" , mas isso é de menor importância aqui.
As seções a seguir se aplicam igualmente a qualquer linguagem que implemente a aritmética de ponto flutuante IEEE corretamente, não sendo específica apenas para Python.
Ao lidar com operadores infinito e maior >ou menor que o <, o seguinte conta:
+infé maior que-inf-infé menor que+inf +infnão é maior nem menor que+inf-inf não é maior nem menor que -infNaNé falsa ( infnão é maior nem menor que NaN)Quando comparado por igualdade, +infe +infsão iguais, como são -infe -inf. Esse é um problema muito debatido e pode parecer controverso para você, mas está no padrão IEEE e o Python se comporta exatamente assim.
É claro que +infé desigual -infe tudo, inclusive NaNele próprio, é desigual NaN.
A maioria dos cálculos com infinito produzirá infinito, a menos que ambos os operandos sejam infinitos, quando a divisão ou módulo de operação ou com multiplicação com zero, existem algumas regras especiais a serem lembradas:
NaN0.0ou -0.0².NaN.inf - inf, o resultado é indefinido: NaN;inf - -inf, o resultado é inf;-inf - inf, o resultado é -inf;-inf - -inf, o resultado é indefinido: NaN.inf + inf, o resultado é inf;inf + -inf, o resultado é indefinido: NaN;-inf + inf, o resultado é indefinido: NaN;-inf + -inf, o resultado é -inf.math.pow, powou **é complicado, pois não se comporta como deveria. Ele lança uma exceção de estouro quando o resultado com dois números reais é muito alto para caber em uma flutuação de precisão dupla (deve retornar infinito), mas quando a entrada é infou -inf, ela se comporta corretamente e retorna infou 0.0. Quando o segundo argumento é NaN, ele retorna NaN, a menos que seja o primeiro argumento 1.0. Há mais problemas, nem todos abordados nos documentos .math.expsofre os mesmos problemas que math.pow. Uma solução para corrigir isso para o estouro é usar código semelhante a este:
try:
res = math.exp(420000)
except OverflowError:
res = float('inf')Nota 1: como uma advertência adicional, que, como definido pelo padrão IEEE, se o resultado do cálculo sub ou estouros, o resultado não será uma infinidade sub ou erro de excesso, mas positivo ou negativo: 1e308 * 10.0os rendimentos inf.
Nota 2: como qualquer cálculo com NaNretornos NaNe qualquer comparação com NaN, inclusive NaNele próprio false, você deve usar a math.isnanfunção para determinar se um número é realmente NaN.
Nota 3: embora o Python suporte a gravação float('-NaN'), o sinal é ignorado, porque não existe sinal NaNinternamente. Se você dividir -inf / +inf, o resultado será NaN, não -NaN(não existe).
Nota 4: tenha cuidado com qualquer uma das opções acima, pois o Python se baseia na biblioteca C ou Java para a qual foi compilado e nem todos os sistemas subjacentes implementam todo esse comportamento corretamente. Se você quiser ter certeza, teste o infinito antes de fazer seus cálculos.
Means) Significa recentemente desde a versão 3.2 .
²) Os pontos flutuantes suportam zero positivo e negativo, portanto: x / float('inf')mantém seu sinal e -1 / float('inf')produz -0.0, 1 / float(-inf)produz -0.0, 1 / float('inf')produz 0.0e -1/ float(-inf)produz 0.0. Além disso, 0.0 == -0.0étrue , você tem que verificar manualmente o sinal se você não quer que ele seja verdadeiro.
-1 * float('infinity') == -inf
O mesmo acontece com C99 .
A representação de ponto flutuante IEEE 754 usada por todos os processadores modernos possui vários padrões de bits especiais reservados para infinito positivo (sinal = 0, exp = ~ 0, frac = 0), infinito negativo (sinal = 1, exp = ~ 0, frac = 0 ) e muitos NaN (não é um número: exp = ~ 0, frac 0).
Tudo o que você precisa se preocupar: alguma aritmética pode causar exceções / interceptações de ponto flutuante, mas essas não se limitam apenas a essas constantes "interessantes".
OverflowError.
Eu encontrei uma ressalva que ninguém até agora mencionou. Não sei se isso ocorrerá frequentemente em situações práticas, mas aqui está por uma questão de perfeição.
Normalmente, o cálculo de um número infinito do módulo retorna como flutuador, mas uma fração do módulo infinito retorna nan(não um número). Aqui está um exemplo:
>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan
Arquivei um problema no rastreador de erros do Python. Pode ser visto em https://bugs.python.org/issue32968 .
Atualização: isso será corrigido no Python 3.8 .
UMA CAVEAT MUITO RUIM: Divisão por Zero
em uma 1/xfração, até x = 1e-323que seja, infmas quando x = 1e-324ou pouco ele lançaZeroDivisionError
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
então seja cauteloso!
1e309será interpretada como+infe-1e309será interpretada como-inf.