Complementando...
Com relação ao round
, existem várias formas de arredondar em caso de "empate" (ou seja, quando a parte decimal é .5
).
Entre as opções existentes, podemos listar as mais comuns:
- arredondar para o maior (ou seja,
2.5
vira3
e-2.5
vira-2
), também chamado de "em direção ao infinito positivo" (towards infinity) - arredondar para o menor (ou seja,
2.5
vira2
e-2.5
vira-3
), também chamado de "em direção ao infinito positivo negativo" (towards negative infinity) - arredondar para o valor mais próximo de zero (
2.5
vira2
e-2.5
vira-2
), também chamado de "towards zero" - arredondar para o valor mais distante de zero (
2.5
vira3
e-2.5
vira-3
), também chamado de "away from zero" - arredondar para o número par mais próximo (
2.5
vira2
e1.5
também vira2
) - essa é usada como o default em Python e C#- como curiosidade, esta regra também é conhecida como bankers rounding ou Banker's algorithm, tem mais detalhes sobre ela aqui.
- arredondar para o número ímpar mais próximo (
2.5
vira3
e1.5
vira1
)
A tabela abaixo tem um resumo disso:
Valor | Towards +∞ | Towards -∞ | Par | Ímpar | Towards zero | Away from zero |
---|---|---|---|---|---|---|
1.5 | 2 | 1 | 2 | 1 | 1 | 2 |
2.5 | 3 | 2 | 2 | 3 | 2 | 3 |
-1.5 | -1 | -2 | -2 | -1 | -1 | -2 |
-2.5 | -2 | -3 | -2 | -3 | -2 | -3 |
Muitas linguagens, inclusive, possuem formas de escolher qual opção queremos ao arredondar. Claro que nem todas as linguagens possuem todas as opções, e outras podem ter mais formas ainda. Python, por exemplo, possui a opção ROUND_05UP
: se o último dígito depois de arredondar em direção ao zero for 0 ou 5, usa o critério away from zero , senão usa towards zero ("Round away from zero if last digit after rounding towards zero would have been 0 or 5; otherwise round towards zero").
Quanto ao fato de floor
e ceiling
darem resultados "inesperados" com números negativos, na verdade faz sentido se levarmos em conta a definição. floor
arredonda "para baixo", ou seja, o resultado é um número inteiro menor ou igual ao valor original. Por isso que floor(-2.1)
é -3
e não -2
. De forma similar, ceiling(-2.9)
é um número inteiro que é maior ou igual ao valor original, por isso é -2
e não -3
.
Estas formas de arredondamento também costumam ser descritas como "towards negative infinity" (floor
) e "towards positivy infinity" (ceil
), ou seja, o número é arredondado em determinada direção na Reta Numérica:
floor(-1.2) ceil(-1.2) floor(1.2) ceil(1.2)
negative infinity <---- -2 --------- -1 ----- 0 ---- 1 -------- 2 ----> positive infinity
-1.2 1.2
No caso, floor
arredonda em direção ao infinito negativo: a partir do número, começa-se a "caminhar" na direção do infinito negativo, e o resultado é o primeiro número inteiro que for encontrado neste caminho. ceil
faz o mesmo em direção ao infinito positivo.
Vale notar que no caso de floor
e ceil
, o critério é usado sempre para qualquer número, ao contrário do round
, que usa somente em caso de empate (pode usar algum dos já citados acima como o default, ou qualquer outro indicado via algum parâmetro). Ou seja, floor(2.9)
e floor(2.5)
resultam em 2
, ceil(2.9)
e ceil(2.5)
resultam em 3
, e round(2.9)
resulta em 3
. Mas round(2.5)
pode ser 2
ou 3
dependendo do critério de desempate usado.
Valor | floor | ceil | round |
---|---|---|---|
2.1 | 2 | 3 | 2 |
2.5 | 2 | 3 | 2 ou 3 (depende do critério de desempate) |
2.9 | 2 | 3 | 3 |
Por fim, já escrevi um post bem detalhado sobre isso (do qual retirei/adaptei os trechos acima), serve como um complemento :-)