Decimal Python

Resumo : neste tutorial, você aprenderá sobre o decimalmódulo Python que oferece suporte à aritmética de ponto flutuante decimal com arredondamento rápido e correto.

Introdução ao módulo decimal Python

Muitos números decimais não têm representações exatas em ponto flutuante binário , como 0,1. Ao usar esses números em operações aritméticas, você obterá um resultado inesperado. Por exemplo:

x = 0.1
y = 0.1
z = 0.1

s = x + y + z

print(s)Linguagem de código:  PHP  ( php )

Saída:

0.30000000000000004Linguagem de código:  CSS  ( css )

O resultado é 0,30000000000000004, não 0,3.

Para resolver este problema, você usa a Decimalclasse do decimalmódulo da seguinte forma:

import decimal
from decimal import Decimal


x = Decimal('0.1')
y = Decimal('0.1')
z = Decimal('0.1')

s = x + y + z

print(s)Linguagem de código:  JavaScript  ( javascript )

Saída:

0.3Linguagem de código:  CSS  ( css )

A saída é a esperada.

O módulo Python decimalsuporta aritmética que funciona da mesma forma que a aritmética que você aprende na escola.

Ao contrário de floats , Python representa números decimais exatamente. E a exatidão é transferida para a aritmética. Por exemplo, a seguinte expressão retorna exatamente 0,0:

Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')Linguagem de código:  JavaScript  ( javascript )

Contexto decimal

Decimal sempre está associado a um contexto que controla os seguintes aspectos:

  • Precisão durante uma operação aritmética
  • Algoritmo de arredondamento

Por padrão, o contexto é global. O contexto global é o contexto padrão. Além disso, você pode definir um contexto temporário que terá efeito local sem afetar o contexto global.

Para obter o contexto padrão, você chama a getcontext()função do decimalmódulo:

decimal.getcontext()Linguagem de código:  CSS  ( css )

A getcontext()função retorna o contexto padrão, que pode ser global ou local.

Para criar um novo contexto copiado de outro contexto, você usa a localcontext()função:

decimal.localcontext(ctx=None)

O localcontext()retorna um novo contexto copiado do contexto, ctxse especificado.

Depois de obter o objeto de contexto, você pode acessar a precisão e o roteamento por meio da propriedade precand respectivamente:rounding

  • ctx.pre: obtém ou define a precisão. O ctx.pre é um número inteiro cujo padrão é 28
  • ctx.rounding: obtém ou define o mecanismo de arredondamento. O arredondamento é uma string. O padrão é 'ROUND_HALF_EVEN'. Observe que os carros alegóricos também usam esse mecanismo de arredondamento.

Python fornece os seguintes mecanismos de arredondamento:

Arredondamento Descrição
ARREDONDAR PARA CIMA arredondar a partir de zero
ARREDONDAR PARA BAIXO arredondar para zero
ROUND_CEILING arredondado para o teto (em direção ao infinito positivo)
ROUND_FLOOR arredondar para o chão (em direção ao infinito negativo)
ROUND_HALF_UP arredondar para o mais próximo, empatar a partir de zero
ROUND_HALF_DOWN arredondar para o mais próximo, empatar em direção a zero
ROUND_HALF_EVEN arredondar para o mais próximo, empatar com o par (dígito menos significativo)

Este exemplo ilustra como obter a precisão padrão e o arredondamento do contexto padrão:

import decimal

ctx = decimal.getcontext()

print(ctx.prec)
print(ctx.rounding)Linguagem de código:  PHP  ( php )

Saída:

28
ROUND_HALF_EVEN

O exemplo a seguir mostra como o 'ROUND_HALF_EVEN'mecanismo de arredondamento entra em vigor:

import decimal
from decimal import Decimal


x = Decimal('2.25')
y = Decimal('3.35')

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

Saída:

2.2
3.4Linguagem de código:  CSS  ( css )

Se você alterar o arredondamento para 'ROUND_HALF_UP', obterá um resultado diferente:

import decimal
from decimal import Decimal


ctx = decimal.getcontext()
ctx.rounding = decimal.ROUND_HALF_UP

x = Decimal('2.25')
y = Decimal('3.35')

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

Saída:

2.3
3.4Linguagem de código:  CSS  ( css )

O exemplo a seguir mostra como copiar o contexto padrão e alterar o arredondamento para 'ROUND_HALF_UP':

import decimal
from decimal import Decimal


x = Decimal('2.25')
y = Decimal('3.35')

with decimal.localcontext() as ctx:
    print('Local context:')
    ctx.rounding = decimal.ROUND_HALF_UP
    print(round(x, 1))
    print(round(y, 1))

print('Global context:')
print(round(x, 1))
print(round(y, 1))Linguagem de código:  PHP  ( php )

Saída:

Local context:
2.3
3.4
Global context:
2.2
3.4Linguagem de código:  CSS  ( css )

Observe que o contexto local não afeta o contexto global. Após o bloco with, o Python usa o mecanismo de arredondamento padrão.

Construtor decimal

O Decimalconstrutor permite criar um novo Decimalobjeto baseado em um valor:

Decimal(value='0', context=None)Linguagem de código:  JavaScript  ( javascript )

O valueargumento pode ser um número inteiro, string, tupla, float ou outro objeto Decimal. Se você não fornecer o argumento value, o padrão será '0'.

Se o valor for uma tupla, ele deverá ter três componentes: um sinal (0 para positivo ou 1 para negativo), uma tupla de dígitos e um expoente inteiro:

(sign, (digit1,digit2, digit3,...), exponent)

Por exemplo:

3.14 = 314 x 10^-2

A tupla tem três elementos como segue:

  • sinal é 0
  • dígitos é (3,1,4)
  • expoente é -2

Portanto, você precisará passar a seguinte tupla para o Decimalconstrutor:

import decimal
from decimal import Decimal

x = Decimal((0, (3, 1, 4), -2))
print(x)Linguagem de código:  JavaScript  ( javascript )

Saída:

3.14Linguagem de código:  CSS  ( css )

Observe que a precisão do contexto decimal afeta apenas a operação aritmética, não o Decimalconstrutor. Por exemplo:

import decimal
from decimal import Decimal


decimal.getcontext().prec = 2

pi = Decimal('3.14159')
radius = 1

print(pi)

area = pi * radius * radius
print(area)Linguagem de código:  JavaScript  ( javascript )

Quando você usa um float que não possui uma representação flutuante binária exata, o Decimalconstrutor não pode criar uma representação decimal precisa. Por exemplo:

import decimal
from decimal import Decimal

x = Decimal(0.1)
print(x)Linguagem de código:  JavaScript  ( javascript )

Saída:

0.1000000000000000055511151231257827021181583404541015625Linguagem de código:  CSS  ( css )

Na prática, você usará uma string ou tupla para construir um arquivo Decimal.

Operações aritméticas decimais

Alguns operadores aritméticos não funcionam da mesma forma que floats ou inteiros , como div ( //) e mod( %).

Para números decimais, o //operador realiza uma divisão truncada:

x // y = trunc( x / y)Linguagem de código:  JavaScript  ( javascript )

A Decimalclasse fornece algumas operações matemáticas, como sqrte log. Porém, não possui todas as funções definidas no mathmódulo.

Quando você usa funções do mathmódulo para números decimais, o Python converterá os Decimalobjetos em carros flutuantes antes de realizar operações aritméticas. Isso resulta na perda da precisão incorporada nos objetos decimais.

Resumo

  • Use o módulo Python decimalquando desejar oferecer suporte à aritmética de ponto flutuante decimal rapidamente arredondada corretamente.
  • Use a Decimalclasse do decimalmódulo para criar objetos Decimal a partir de strings, inteiros e tuplas.
  • Os Decimalnúmeros possuem um contexto que controla a precisão e o mecanismo de arredondamento.
  • A Decimalclasse não possui todos os métodos definidos no mathmódulo. No entanto, você deve usar os métodos aritméticos do Decimal, se estiverem disponíveis.

Deixe um comentário

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