Esquisitices (ou não) no arredondamento em Python 3

por Valdir Stumm Jr

O arredondamento de números em Python 3 pode ser feito usando uma função builtinchamada round(). Em sua forma mais simples, ela recebe um número qualquer e o arredonda para um número inteiro. Veja ela em ação:

>>> round(1.2)
1
>>> round(1.8)
2

Ela ainda aceita um segundo parâmetro, que indica quantos dígitos de precisão queremos no resultado. O valor padrão desse parâmetro é 0, mas podemos passar qualquer valor:

>>> round(1.847, ndigits=2)
1.85
>>> round(1.847, ndigits=1)
1.8

E o que será que acontece quando queremos arredondar um número como 1.5? A round() arredonda pra cima ou pra baixo? Vamos ver:

>>> round(1.5)
2

Arredonda pra cima? Vamos ver mais um número só pra ter certeza:

>>> round(2.5)
2

Ops, agora foi pra baixo! Vamos ver mais alguns:

>>> round(3.5)
4
>>> round(4.5)
4
>>> round(5.5)
6

Calma aí que tudo tem uma explicação. Em Python 3, a round() define o arredondamento assim:

Arredonda pro mais próximo.
Se empatar, arredonda pro número PAR mais próximo.

Agora faz sentido né? Revendo os exemplos dali de cima, vemos que o arredondamento sempre foi feito pro par mais próximo:

>>> round(3.5)
4
>>> round(4.5)
4
>>> round(5.5)
6

No caso do 3.5, tanto o 3 quanto o 4 estão à mesma distância dele. Ou seja, deu empate. Como a regra determina, round() desempata pro par mais próximo, que é 4. 🙂

E em Python 2?

Em Python 2 é diferente. O empate em arredondamentos é sempre resolvido pra cima, em caso de números positivos:

>>> round(1.5)
2.0
>>> round(2.5)
3.0

E pra baixo, em caso de números negativos:

>>> round(-1.5)
-2.0
>>> round(-2.5)
-3.0

Mas por que Python 3 faz diferente?

O objetivo é deixar o arredondamento menos tendencioso.

Imagine um banco onde todos os arredondamentos são feitos para cima. Ao final do dia, o relatório de receitas do banco vai mostrar um valor mais alto do que o banco realmente recebeu. É exatamente o que acontece em Python 2:

>>> valores = [1.5, 2.5, 3.5, 4.5]
>>> sum(valores)
12.0
>>> sum(round(v) for v in valores)
14.0

Usando a regra de arredondamento de Python 3, os valores arredondados nas operações tendem a ser amortizados, porque metade deles vai ser para cima e a outra metade para baixo, visto que metade dos números existente são pares e a outra metade são ímpares. Veja o mesmo código, agora rodando em Python 3:

>>> valores = [1.5, 2.5, 3.5, 4.5]
>>> sum(valores)
12.0
>>> sum(round(v) for v in valores)
12

Na realidade, isso não é uma novidade de Python 3. Esse tipo de arredondamento é antigo e tem até nome: Bankers Rounding (Arredondamento de Banqueiros).

Se ficou interessado no assunto, dê uma olhada num outro post daqui do blog, que mostra como funciona a divisão inteira em Python: https://pythonhelp.wordpress.com/2013/06/30/comportamento-inesperado-na-divisao-inteira/

 

Anúncios

Escrito por zrhans

Professor at UFSM

Deixe um comentário

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s