DEV Community

loading...
Cover image for Trabalhando com dinheiro!

Trabalhando com dinheiro!

Victor Os贸rio
Since 2005 years working in highly challenging projects
銉3 min read

Ningu茅m nasce S锚nior, se torna S锚nior!

Se tornar um S锚nior 茅 um processo demorado, e requer muito suor. Como o mercado de computa莽茫o tem se expandido exponencialmente, resolvi come莽ar uma s茅rie de posts r谩pidos sobre tudo que um S锚nior deve saber. Vamos ao primeiro....

Como lidar com dinheiro?

Quando vamos modelar um Objeto ou qualquer outro dom铆nio, sempre imaginamos o tipo de dado antes mesmo de come莽ar a escrever o dado.

Sabemos que nome 茅 String, sobrenome 茅 String, data de nascimento 茅 um Date, data de ativa莽茫o ser谩 um long, ou Timestamp. Podemos at茅, em algumas linguagens ter d煤vida se usamos um Date ou Datetime. Mas tudo isso depende da linguagem escolhida, certo?

Errado!

Tudo depende da forma como o valor 茅 armazenado em bytes. Sim! Voc锚 acha que existe um valor inteiro? Ou string? N茫o, existem bytes! Somente bytes! E esses valores s茫o representados em bytes. Um inteiro por exemplo s茫o 4 bytes alinhados. Assim um inteiro 0 茅 00000000 00000000 00000000 00000000. Em Java um short 0 茅 00000000 00000000. F谩cil? Nem tanto...

Lembra dos conjuntos num茅ricos da matem谩tica? Pois bem, n煤meros inteiros s茫o f谩ceis, agora e os outros?

Quando eu preciso de um valor n茫o exato, um float por exemplo? Sabe como 茅 armazenado? Usando a nota莽茫o floating point.

Ent茫o qualquer valores de dinheiro devem ser guardados em Float, certo?

Errado!

Vamos olhar bem de perto algumas opera莽玫es do float ou double.

Alt Text

Entendeu porque 2.01 + 2.01 + 2.01 + 2.01 + 2.001 = 10.040999999999999? E n茫o 鈥10.041鈥? 馃檮馃檮馃檮

Float Point precision problem

Sim, esse 茅 um erro bastante conhecido. Voc锚 pode pesquisar por ele na internet. Ele aparece quando s茫o feitas v谩rias opera莽玫es com Floating Point.

J谩 vi ocorrer em sistemas em produ莽茫o. Era um sistema de controle de estoque e compras. Havia v谩rias ordem de compras, mas o valor vendido n茫o batia com o caixa. Esse erro se deu em uma conta simple com 5 valores. Agora e se tivessemos 5.000 valores?

Vamos ver... E se somassemos 5.000 vezes 2.01? Deveria dar 10.050.

Alt Text

Opa! Tivemos um erro de 0,676! 馃槷馃槷馃槷馃槷馃槷

Solu莽茫o em Java

Mas vamos com calma. Em Java esse problema foi resolvido com a cria莽茫o da classe BigDecimal.

Nenhuma opera莽茫o monet谩ria deve ser feita com float ou decimal em hipotese alguma. Esse valores devem ser lidos como BigDecimal.

Alt Text

Fique Atento

  1. Se esse valor for instanciado com um double ou float ir谩 herdar a imprecis茫o do valor original.
  2. Essa classe 茅 imut谩vel, ent茫o fique atento. Se voc锚 chamar os metodos, n茫o ir谩 alterar o valor da inst芒ncia, apenas criar uma nova!

Alt Text

Conclus茫o

Guarde pra vida toda. Nunca armazene valores monet谩rios em double ou float. N茫o importa a linguagem ou base de dados que voc锚 est谩 usando.

Caso n茫o saiba como resolver esse problema. N茫o se preocupe 茅 normal. Amanh茫 vai surgir uma linguagem nova ou uma base de dados nova e 99,99999% dos desenvolvedores n茫o sabaer茫o tamb茅m. Pesquise no Google.

Discussion (0)