Atualizado: 04/11/2024

Módulo Decimal - Python

Ao trabalhar com números de ponto flutuante (float), frequentemente enfrentamos o problema de obter resultados ligeiramente imprecisos em operações:

number = 0.1 + 0.1 + 0.1
print(number)       # 0.30000000000000004

Para resolver isso, uma alternativa é usar a função round(), que arredonda o número. Porém, existe uma abordagem mais precisa, que é o uso do módulo decimal.

O principal componente para lidar com números no módulo decimal é a classe Decimal. Para utilizá-la, é necessário criar um objeto desta classe usando o construtor, que recebe uma string representando o número:

from decimal import Decimal

number = Decimal("0.1")

Após isso, o objeto Decimal pode ser usado em operações aritméticas:

from decimal import Decimal

number = Decimal("0.1")
number = number + number + number
print(number)       # 0.3

Em operações com Decimal, é possível utilizar números inteiros:

number = Decimal("0.1")
number = number + 2

No entanto, não é permitido misturar números decimais float com Decimal:

number = Decimal("0.1")
number = number + 0.1   # isso levanta uma exceção

Usando casas decimais adicionais, é possível definir o número de dígitos na parte decimal:

number = Decimal("0.10")
number = 3 * number
print(number)       # 0.30

A string "0.10" especifica duas casas decimais, mesmo que os últimos dígitos representem zeros. Assim, "0.100" indica três casas decimais.

Arredondamento de Números

Objetos Decimal possuem o método quantize(), que permite arredondar números. Este método recebe como primeiro argumento um objeto Decimal que define o formato de arredondamento:

from decimal import Decimal

number = Decimal("0.444")
number = number.quantize(Decimal("1.00"))
print(number)       # 0.44

number = Decimal("0.555678")
print(number.quantize(Decimal("1.00")))       # 0.56

number = Decimal("0.999")
print(number.quantize(Decimal("1.00")))       # 1.00

A string "1.00" indica que o arredondamento ocorrerá até duas casas decimais.

Por padrão, o arredondamento é feito usando a constante ROUND_HALF_EVEN, onde o número é arredondado para o par mais próximo se a parte arredondada for igual a 5. Exemplo:

from decimal import Decimal, ROUND_HALF_EVEN

number = Decimal("10.025")      # 2 é o par mais próximo
print(number.quantize(Decimal("1.00"), ROUND_HALF_EVEN))       # 10.02

number = Decimal("10.035")      # 4 é o par mais próximo
print(number.quantize(Decimal("1.00"), ROUND_HALF_EVEN))       # 10.04

A estratégia de arredondamento é passada como segundo parâmetro no quantize.

No primeiro caso, com "10.025", o segundo dígito é 2, um número par, então ele não é arredondado para cima, apesar do próximo número ser 5. No segundo caso, "10.035", o segundo dígito é 3, um número ímpar, então é arredondado para o próximo par, resultando em 10.04.

Esse comportamento pode não ser desejável para todos, e é possível substituí-lo usando uma das seguintes constantes:

  • ROUND_HALF_UP: arredonda para cima se o próximo dígito for 5 ou maior.

  • ROUND_HALF_DOWN: arredonda para cima se o próximo dígito for maior que 5.

    number = Decimal("10.026")
    print(number.quantize(Decimal("1.00"), ROUND_HALF_DOWN))       # 10.03
    
    number = Decimal("10.025")
    print(number.quantize(Decimal("1.00"), ROUND_HALF_DOWN))       # 10.02
    
  • ROUND_05UP: arredonda para cima se o próximo dígito for 5 ou maior, mesmo se o dígito atual for zero.

    number = Decimal("10.005")
    print(number.quantize(Decimal("1.00"), ROUND_05UP))       # 10.01
    
    number = Decimal("10.025")
    print(number.quantize(Decimal("1.00"), ROUND_05UP))       # 10.02
    
  • ROUND_CEILING: arredonda sempre para cima, independente do próximo dígito.

    number = Decimal("10.021")
    print(number.quantize(Decimal("1.00"), ROUND_CEILING))       # 10.03
    
    number = Decimal("10.025")
    print(number.quantize(Decimal("1.00"), ROUND_CEILING))       # 10.03
    
  • ROUND_FLOOR: arredonda sempre para baixo, independente do próximo dígito.

    number = Decimal("10.021")
    print(number.quantize(Decimal("1.00"), ROUND_FLOOR))       # 10.02
    
    number = Decimal("10.025")
    print(number.quantize(Decimal("1.00"), ROUND_FLOOR))       # 10.02
    
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com