HOWTO · Python

Truncar float em Python

Este tutorial explica como truncar um float em Python

Nesta página

Um float do Python não pode ser encurtado diretamente: ele é um valor de ponto flutuante binário, não uma string decimal com uma quantidade fixa de dígitos. Para descartar dígitos depois de uma casa decimal escolhida, crie um Decimal a partir do texto decimal do número e quantize-o com ROUND_DOWN. Para obter um inteiro, use math.trunc() ou int(). Essas operações truncam em direção a zero; round() e a formatação numérica têm comportamentos diferentes.

Escolha entre truncamento e arredondamento

O truncamento descarta os dígitos além de uma posição escolhida e leva o valor em direção a zero. O arredondamento escolhe um valor próximo de acordo com uma regra de arredondamento. A função round(number, ndigits) do Python arredonda; ela não trunca. Por exemplo, round(3.146, 2) arredonda para 3.15, enquanto truncar para duas casas decimais resulta em 3.14. A função integrada round() do Python usa o critério de empate para o par nos casos intermediários, portanto não deve ser considerada um método geral de truncamento decimal.

Trunque um float para uma quantidade fixa de casas decimais

Use Decimal quando precisar manter uma quantidade específica de casas decimais. Crie o valor a partir de uma representação em string e, em seguida, chame quantize() com ROUND_DOWN. No módulo decimal, ROUND_DOWN arredonda em direção a zero: descarta os dígitos nessa direção, de modo que valores negativos se aproximam de zero em vez de ficarem mais negativos. Passar uma string como "3.14159" preserva o valor decimal pretendido; já construir Decimal diretamente a partir de um float captura a aproximação binária desse float.

Execute este exemplo:

O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.

from decimal import Decimal, ROUND_DOWN

values = ("3.14159", "-3.14159", "0", "2.1")
places = 2
quantum = Decimal("1").scaleb(-places)
for text in values:
    print(Decimal(text).quantize(quantum, rounding=ROUND_DOWN))
3.14
-3.14
0.00
2.10

Os dois primeiros resultados mostram o truncamento em direção a zero para valores positivos e negativos, inclusive para a entrada negativa. A quantização também mantém a quantidade de casas fracionárias solicitada: zero se torna 0.00, e 2.1 se torna 2.10. Se você já tem um float e quer usar como entrada sua representação decimal exibida mais curta, use Decimal(str(value)); isso não recupera informações decimais perdidas antes da criação do float. Para valores monetários ou outras quantidades decimais exatas, prefira aceitar texto decimal ou construir Decimal desde o início a partir de inteiros e strings. Consulte a documentação do módulo decimal.

Trunque em direção a zero para obter um inteiro

Quando precisar de um inteiro em vez de uma quantidade fixa de casas decimais, math.trunc() retorna explicitamente a parte inteira em direção a zero. A função integrada int() faz o mesmo ao converter um float. Por exemplo, math.trunc(5.67) resulta em 5, e math.trunc(-3.45) resulta em -3. Nenhuma das duas funções mantém casas decimais; use Decimal.quantize() quando o resultado precisar de uma escala decimal fixa. math.trunc() também aceita tipos numéricos que implementam __trunc__(), método que fornece o valor inteiro usado no truncamento.

Por que multiplicar um float por uma escala pode gerar resultados inesperados

Um atalho comum multiplica um float por uma potência de dez, converte o resultado em inteiro e depois divide novamente. Isso pode funcionar para alguns valores, mas floats binários não conseguem representar exatamente muitas frações decimais. Por isso, a multiplicação pode resultar em um valor ligeiramente abaixo ou acima do decimal pretendido, e int(value * 100) / 100 pode descartar um dígito inesperado. A operação também retorna outro float, que continua sujeito às limitações da representação binária. Evite depender desse padrão em cálculos sensíveis a casas decimais; use Decimal com entrada textual. Em cálculos cujo domínio é inerentemente aproximado, mantenha os valores como floats e leve a precisão em conta, em vez de tratar os dígitos exibidos como exatos.

Escolha o método adequado

  • Use Decimal criado a partir de texto decimal e quantize(..., rounding=ROUND_DOWN) para truncar para uma quantidade fixa de casas decimais.
  • Use math.trunc() ou int() para descartar a parte fracionária e retornar um inteiro em direção a zero.
  • Use round() quando a operação desejada for arredondar, não truncar.
  • Use formatação quando precisar apenas controlar o texto exibido. Uma f-string como f"{value:.2f}" produz uma string e arredonda o valor exibido; ela não altera nem trunca o float subjacente.

Escolha conforme o resultado de que precisa: um valor decimal com precisão definida, um inteiro, um valor arredondado ou apenas uma string formatada.