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 float
classe 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.25
Linguagem 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.1
exatamente.
Internamente, Python só pode representar 0.1
aproximadamente.
Para ver como o Python representa 0.1
internamente, 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.1
não é exatamente, 0.1
mas0.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:
False
Linguagem de código: PHP ( php )
Internamente, Python não pode usar um número finito de dígitos para representar os números x
e y
:
print(format(x, '.20f'))
print(format(y, '.20f'))
Linguagem de código: PHP ( php )
Saída:
0.30000000000000004441
0.29999999999999998890
Linguagem 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:
True
Linguagem 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 math
módulo que retorna True
se 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:
True
Linguagem de código: PHP ( php )
Resumo
- Python usa
float
classe 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.