Eu sei que as perguntas sobre arredondamento em python já foram feitas várias vezes, mas as respostas não me ajudaram. Estou procurando um método que está arredondando um número flutuante pela metade e retorna um número flutuante. O método também deve aceitar um parâmetro que define a casa decimal para a qual arredondar. Eu escrevi um método que implementa esse tipo de arredondamento. No entanto, acho que não parece nada elegante.
def round_half_up(number, dec_places):
s = str(number)
d = decimal.Decimal(s).quantize(
decimal.Decimal(10) ** -dec_places,
rounding=decimal.ROUND_HALF_UP)
return float(d)
Eu não gosto disso, que eu tenho que converter float em uma string (para evitar imprecisão de ponto flutuante) e depois trabalhar com o módulo decimal . Você tem soluções melhores?
Edit: Como apontado nas respostas abaixo, a solução para o meu problema não é tão óbvia quanto o arredondamento correto requer uma representação correta dos números em primeiro lugar, e esse não é o caso do float. Então, eu esperaria que o seguinte código
def round_half_up(number, dec_places):
d = decimal.Decimal(number).quantize(
decimal.Decimal(10) ** -dec_places,
rounding=decimal.ROUND_HALF_UP)
return float(d)
(que difere do código acima apenas pelo fato de que o número flutuador é convertida diretamente em um número decimal e não para uma string primeiro) para retornar 2,18 quando usado como este: round_half_up(2.175, 2)
Mas não porque Decimal(2.175)
vai voltar Decimal('2.17499999999999982236431605997495353221893310546875')
, a forma como o flutuador número é representado pelo computador. Surpreendentemente, o primeiro código retorna 2,18 porque o número flutuante é convertido em string primeiro. Parece que a função str () conduz um arredondamento implícito para o número que inicialmente deveria ser arredondado. Portanto, existem dois arredondamentos. Mesmo que esse seja o resultado que eu esperaria, é tecnicamente errado.