Alerta de versão: esse post foi escrito com base na versão 2 da linguagem Python. Na versão 3, o operador de divisão inteira é o //
.
Para quem já estudou um pouco de programação, o seguinte resultado não é surpresa alguma:
>>> 3 / 2 1
Por se tratar de uma divisão de números inteiros, o resultado é truncado em um número inteiro também. Até aí, está tudo dentro do esperado, não? Então, abra um shell Python e teste a seguinte operação:
>>> -3 / 2 -2
Quem imaginava que o resultado seria -1
, levante a mão: \o_
Por que -2 ?!
Em Python, a divisão inteira arredonda o resultado para baixo, ou seja, sempre para o menor número inteiro mais próximo. Por exemplo: 3 / 2
seria 1.5
, mas o resultado é arredondado para 1
(e não 2
), pois 1 < 2
. Já no caso de -3 / 2
, o resultado seria -1.5
, mas por se tratar de uma divisão inteira, ele é arredondado para -2
e não para -1
, pois -2 < -1
.
Isso não é muito comum nas linguagens de programação. Em C e Java, por exemplo, uma divisão inteira tem o seu resultado sempre arredondado em direção ao 0
. Python, como já vimos, faz com que o resultado de uma divisão inteira seja arredondado para baixo. Veja a ilustração abaixo:
Mas por que Python faz dessa forma? Ninguém melhor para explicar isso do que o criador da linguagem, o Guido Van Rossum. Em um post no blog Python History, ele explica que resultados negativos de divisão inteira são arredondados em direção a -∞ para que a seguinte relação entre as operações de divisão (/
) e de módulo (%
) se mantenha também para as operações com resultados negativos:
quociente = numerador / denominador resto = numerador % denominador denominador * quociente + resto == numerador
Vamos testar?
>>> numerador = -3 >>> denominador = 2 >>> quociente = numerador / denominador >>> resto = numerador % denominador >>> print quociente, resto -2 1 >>> print denominador * quociente + resto == numerador True # e agora, com numerador positivo >>> numerador = 3 >>> quociente = numerador / denominador >>> resto = numerador % denominador >>> print quociente, resto 1 1 >>> print denominador * quociente + resto == numerador True
Perceba que se o resultado fosse arredondado em direção ao zero, a propriedade não seria satisfeita.
Esse é um detalhe de implementação muito importante e que todo desenvolvedor Python deve conhecer para não introduzir bugs em seus códigos, para evitar de perder horas depurando algo que parecia fugir comportamento esperado e também para evitar sentimentos de “esse intepretador está errado!”.
Leia mais sobre o assunto no post do Guido Van Rossum no blog The History of Python: Why Python’s Integer Division Floors.