Porquê aplicações financeiras escritas em Python não devem utilizar números decimais?
Vou começar esse artigo pedindo para que vocês façam um teste no shell do python de vocês:
>>> 0.1 + 0.1 + 0.1 == 0.3
Talvez muitos de vocês fiquem surpresos ao perceber que o shell retorna False
ao invés de True
, e se você ficou surpreso, parabéns! esse artigo é pra você.
Entendendo problemas de precisão
Acho que todos nós em algum ponto da vida escolar já nos deparamos com essa operação:
1/3 = 0.333333...
O número 0.33333... é o que chamamos de dízima períodica, um número com infinitas casas decimais que se repetem seguindo um padrão. Mas na escola ninguém tem papel infinito, então o que fazemos na prática é arredondar o número pra 0.3, 0.33, 0.333 de acordo com o quão a precisão nossos cálculos devem ter.
Uma coisa interessante de observar é que a precisão depende do jeito que nós representamos os números:
Utilizando Frações:
1/3 + 2/3 = 1
Utilizando Decimais:
0.3 + 0.6 = 0.9
0.33 + 0.66 = 0.99
0.333 + 0.666 = 0.999
...
Computadores e representação binária
Nenhum computador moderno faz cálculos com números decimais, mas sim com números binários. Vamos observar o número 1/10, que em decimal é representado como 0.1, mas em binário fica:
0.0001100110011001100110011001100110011001100110011...
Então um número que era exato em base 10, não é mais exato quando escrito em base 2. Mas a memória dos computadores não são infinitas, assim como nosso papel do exemplo anterior. Então o computador também faz esse arredondamento em algum ponto. Entretanto esse arredondamento pode ser extremamente danoso em aplicações financeiras onde cada centavo é importante.
O que acontece é que muitos usuários do python não sabem que esse arredondamento acontece por baixo dos panos, porquê a própria linguagem já se encarrega de retornar um valor arredondado pra facilitar a visualização, mas que na verdade não é igual ao número que tá armazenado na memória.
Mas isso significa que não posso escrever nenhuma aplicação financeira em Python? Sendo bem curto e grosso a resposta é Não. Mas comentem aqui se vocês curtiram o conteúdo e eu volto com a solução para esse dilema.
Abraços pessoal!