Pergunta

Assim, Python tem infinito positivo e negativo:

float("inf"), float("-inf")

Isso só parece ser o tipo de recurso que tem que ter alguma ressalva. Existe algo que eu deveria estar ciente de?

Foi útil?

Solução

Você ainda pode obter valores não-um-número (NaN) de aritmética simples inf envolvendo:

>>> 0 * float("inf")
nan

Observe que você normalmente não obter um valor inf 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 valor inf é considerado um valor muito especial com a semântica incomuns, por isso é melhor saber sobre uma OverflowError imediatamente através de uma exceção, em vez de ter um valor de inf silenciosamente injetado em seus cálculos.

Outras dicas

do Python segue o IEEE-754 padrão muito bem, que você pode usar como uma orientação, mas depende do sistema subjacente ele foi compilado, por isso < a href = "http://www.python.org/dev/peps/pep-0754/" rel = "noreferrer"> diferenças de plataforma podem ocorrer. Recently¹, a correção foi aplicada que permite "infinito", bem como "inf" , mas isso é de menor importância aqui.

As seções a seguir igualmente bem se aplica a qualquer linguagem que implementa IEEE aritmética de ponto flutuante corretamente, ele não é específico para apenas Python.

Comparação de desigualdade

Ao lidar com o infinito e maior que > ou menos do que os operadores <, os seguintes aspectos:

Comparação por igualdade

Quando comparado por igualdade, +inf e +inf são iguais, como são -inf e -inf. Esta é uma questão muito debatida e pode soar controverso para você, mas é no padrão IEEE e Python se comporta assim.

Claro, +inf é desigual a -inf e tudo, incluindo a própria NaN, é desigual a NaN.

Cálculos com o infinito

A maioria dos cálculos com o infinito vai render o infinito, a menos que ambos os operandos são infinito, quando a divisão de operação ou modulo, ou com a multiplicação com zero, existem algumas regras especiais para manter em mente:

  • quando multiplicado por zero, para o qual o resultado é indefinido, ele produz NaN
  • quando dividindo qualquer número (excepto em si infinito) por infinito, o que produz 0.0 ou -0.0 ² .
  • quando dividindo (incluindo modulo) infinito positivo ou negativo pelo infinito positivo ou negativo, o resultado é indefinido, de modo NaN.
  • quando subtraindo, os resultados podem ser surpreendentes, mas siga matemática do senso comum :
    • ao fazer inf - inf, o resultado é indefinido: NaN;
    • ao fazer inf - -inf, o resultado é inf;
    • ao fazer -inf - inf, o resultado é -inf;
    • ao fazer -inf - -inf, o resultado é indefinido:. NaN
  • quando a adição, pode ser semelhante surpreendendo também:
    • ao fazer inf + inf, o resultado é inf;
    • ao fazer inf + -inf, o resultado é indefinido: NaN;
    • ao fazer -inf + inf, o resultado é indefinido: NaN;
    • ao fazer -inf + -inf, o resultado é -inf.
  • usando math.pow, pow ou ** é complicado, uma vez que 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 uma precisão de flutuação dupla (ele deve retornar infinity), mas quando a entrada é inf ou -inf, comporta-se correctamente e retornos quer inf ou 0.0. Quando o segundo argumento é NaN, ele retorna NaN, a menos que o primeiro argumento é 1.0. Há mais problemas, nem todos coberta nos docs .
  • math.exp sofre as mesmas questões que math.pow. A solução para corrigir isso para transbordamento é usar código semelhante a este:

    try:
        res = math.exp(420000)
    except OverflowError:
        res = float('inf')
    

Notas

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á um erro sub ou estouro, mas positiva ou infinito negativo:. yields 1e308 * 10.0 inf

Nota 2: , porque qualquer cálculo com NaN retornos NaN e qualquer comparação com NaN, incluindo a própria NaN é false, você deve usar o math.isnan função para determinar se um número é de fato NaN.

Nota 3: que Python suporta escrita float('-NaN'), o sinal é ignorado, porque não existe nenhum sinal na NaN internamente. Se você dividir -inf / +inf, o resultado é NaN, não -NaN (não existe tal coisa).

Nota 4: ter o cuidado de confiar em qualquer um dos acima, como Python depende da biblioteca C ou Java foi compilado para e nem todos subjacente sistemas de implementar todo esse comportamento corretamente. Se você quiser ter certeza, teste para o infinito antes de fazer seus cálculos.

¹) Recentemente meio desde versão 3.2 .
²) pontos flutuantes apoiar positivo e negativo zero, assim: x / float('inf') mantém seu sinal e -1 / float('inf') rendimentos -0.0, os rendimentos 1 / float(-inf) -0.0, os rendimentos 1 / float('inf') 0.0 e rendimentos -1/ float(-inf) 0.0. Além disso, 0.0 == -0.0 é true , você tem que verificar manualmente o sinal, se você não quer que seja verdade.

O mesmo acontece com C99 .

A representação de ponto flutuante IEEE 754 utilizado por todos os processadores modernos tem vários padrões de bits especial reservado para o infinito positivo (sinal = 0, exp = ~ 0, frac = 0), infinito negativo (sinal = 1, exp = ~ 0, frac = 0), e muitos NaN (Not a Number:. exp = ~ 0, frac ? 0)

Tudo que você precisa se preocupar: um pouco de aritmética pode causar flutuante exceções de ponto / armadilhas, mas aqueles não estão limitados a apenas essas constantes "interessantes"

.

Eu encontrei uma ressalva de que ninguém até agora tem mencionado. Eu não sei se ele vai vir para cima, muitas vezes em situações práticas, mas aqui é para o bem da integralidade.

Normalmente, o cálculo de um infinito número de módulo retorna a si mesmo um float, mas uma fração modulo infinito retornos 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

Eu arquivei um problema no rastreador de bug do Python. Pode ser visto em https://bugs.python.org/issue32968 .

Update: este será fixo em Python 3.8

.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top