Flutuador Python

Resumo : neste tutorial, você aprenderá sobre o tipo float do Python, como o Python representa números de ponto flutuante e como testar a igualdade do número de ponto flutuante.

Introdução ao tipo float do Python

Python usa a floatclasse para representar números reais.

CPython implementa float usando tipo duplo C. O tipo duplo C geralmente implementa float binário de precisão dupla IEEE 754 , também chamado de binary64.

O float Python usa 8 bytes (ou 64 bits) para representar números reais. Ao contrário do tipo inteiro , o tipo float usa um número fixo de bytes.

Tecnicamente, Python usa 64 bits da seguinte forma:

  • 1 bit para sinal (positivo ou negativo)
  • 11 bits para o expoente 1,5e-5 1,5 x 10 -5 (o expoente é -5) o intervalo é [-1022, 1023].
  • 52 bits para dígitos significativos

Por uma questão de simplicidade, dígitos significativos são todos dígitos, exceto zeros à esquerda e à direita.

Por exemplo, 0,25 tem dois algarismos significativos, 0,125 tem três algarismos significativos e 12,25 tem quatro algarismos significativos.

(1,25) 10 = (1×2 0 + 0x2 -1 + 1×2 -2 ) 10 = (1,01) 2

Alguns números têm uma representação binária finita, mas outros não, por exemplo 0.1,. Está 01.0001100110011...em binário.

Por causa disso, Python só pode usar representações flutuantes aproximadas para esses números.

Classe flutuante Python

O float()retorna um número de ponto flutuante baseado em um número ou string. Por exemplo:

>>> float(0.1)
0.1
>>> float('1.25')
1.25Linguagem de código:  JavaScript  ( javascript )

Se você passar um objeto ( obj) para o float(obj), ele delegará para o obj.__float__(). Se o __float__()não estiver definido, ele voltará para __index__().

Se você não passar nenhum argumento para o float(), ele retornará0.0

Ao usar a print()função, você verá que o número 0.1é representado 0.1exatamente.

Internamente, Python só pode representar 0.1aproximadamente.

Para ver como o Python representa 0.1internamente, você pode usar a format()função.

O seguinte mostra como Python representa o número 0,1 usando 20 dígitos:

>>> format(0.1, '.20f')
'0.10000000000000000555'Linguagem de código:  JavaScript  ( javascript )

Como você pode ver, 0.1não é exatamente, 0.1mas0.10000000000000000555...

Como o Python pode representar alguns números flutuantes aproximadamente, ele causará muitos problemas quando você comparar dois números de ponto flutuante.

Teste de igualdade

Vejamos o seguinte exemplo:

x = 0.1 + 0.1 + 0.1
y = 0.3

print(x == y)Linguagem de código:  PHP  ( php )

Saída:

FalseLinguagem de código:  PHP  ( php )

Internamente, Python não pode usar um número finito de dígitos para representar os números xe y:

print(format(x, '.20f'))
print(format(y, '.20f'))Linguagem de código:  PHP  ( php )

Saída:

0.30000000000000004441
0.29999999999999998890Linguagem de código:  CSS  ( css )

Observe que o número de dígitos é infinito. Mostramos apenas os primeiros 20 dígitos.

Uma maneira de contornar esse problema é arredondar ambos os lados da expressão de igualdade para um número de dígitos significativos. Por exemplo:

x = 0.1 + 0.1 + 0.1
y = 0.3
print(round(x, 3) == round(y, 3))Linguagem de código:  PHP  ( php )

Saída:

TrueLinguagem de código:  PHP  ( php )

Esta solução alternativa não funciona em todos os casos.

O PEP485 fornece uma solução que corrige esse problema usando tolerâncias relativas e absolutas.

Ele fornece a isclose()função do mathmódulo que retorna Truese dois números estiverem relativamente próximos um do outro.

O seguinte mostra a isclose()assinatura da função:

isclose(a, b, rel_tol=1e-9, abs_tol=0.0)

Por exemplo:

from math import isclose

x = 0.1 + 0.1 + 0.1
y = 0.3

print(isclose(x,y))Linguagem de código:  JavaScript  ( javascript )

Saída:

TrueLinguagem de código:  PHP  ( php )

Resumo

  • Python usa floatclasse para representar números reais.
  • Python usa um número fixo de bytes (8 bytes) para representar flutuadores. Portanto, pode representar alguns números em binário aproximadamente.
  • Use a isclose()função do módulo matemático para testar a igualdade para números de ponto flutuante.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *