Eu tenho tentado arredondar números longos de flutuação como:
32.268907563;
32.268907563;
31.2396694215;
33.6206896552;
...
Sem sucesso até agora. Eu tentei math.ceil(x)
, math.floor(x)
(apesar de que seria arredondar para cima ou para baixo, o que não é o que estou procurando) e round(x)
que não quer trabalhar (ainda flutuar números).
O que eu poderia fazer?
EDIT: CÓDIGO:
for i in widthRange:
for j in heightRange:
r, g, b = rgb_im.getpixel((i, j))
h, s, v = colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0)
h = h * 360
int(round(h))
print(h)
int(x)
Respostas:
Arredondará e alterará para inteiro
EDITAR:
Você não está atribuindo int (round (h)) a nenhuma variável. Quando você chama int (round (h)), ele retorna o número inteiro, mas não faz mais nada; você precisa alterar essa linha para:
Para atribuir o novo valor a h
EDIT 2:
Como o @plowman disse nos comentários, o Python
round()
não funciona como seria de se esperar, e isso ocorre porque o modo como o número é armazenado como uma variável geralmente não é o que você vê na tela. Há muitas respostas que explicam esse comportamento:round () não parece estar arredondando corretamente
Uma maneira de evitar esse problema é usar o decimal, conforme declarado por esta resposta: https://stackoverflow.com/a/15398691/4345659
Para que esta resposta funcione corretamente sem o uso de bibliotecas extras, seria conveniente usar uma função de arredondamento personalizada. Depois de muitas correções, eu vim com a seguinte solução, que, tanto quanto eu testei, evitava todos os problemas de armazenamento. É baseado no uso da representação de string, obtida com
repr()
(NOTstr()
!). Parece hacky, mas foi a única maneira que encontrei para resolver todos os casos. Funciona com o Python2 e o Python3.Testes:
Finalmente, a resposta corrigida seria:
EDIT 3:
Testes:
O problema aqui é que o
dec
décimo-decimal pode ser 9 e, se odec+1
décimo-dígito> = 5, o 9 se tornará um 0 e um 1 deve ser carregado para odec-1
-ésimo dígito.Se levarmos isso em consideração, obtemos:
Na situação descrita acima,
b = 10
a versão anterior concatenariaa
eb
resultaria em uma concatenação de10
onde o 0 à direita desapareceria. Esta versão se transformab
na casa decimal correta com base emdec
, como um transporte adequado.fonte
int(round(4.5))
rodadas para baixo a 4, enquantoint(round(4.500001))
corretamente rodadas a 5.round(x)
é suficiente no Python 3.6.2 (e talvez também em versões inferiores). O resultado já é do tipo int. Nota:round(x, n)
será do tipo float.Use
round(x, y)
. Ele arredondará seu número até a casa decimal desejada.Por exemplo:
fonte
round(value,significantDigit)
é a solução comum, no entanto, isso não funciona como seria de esperar da perspectiva matemática quando os valores arredondados terminam em5
. Se o5
dígito estiver logo após o número para o qual você é arredondado, esses valores às vezes são arredondados para cima conforme o esperado (por exemplo,8.005
arredondar para dois dígitos decimais8.01
). Para certos valores devido às peculiaridades da matemática de ponto flutuante, eles são arredondados para baixo!ie
Esquisito.
Supondo que sua intenção seja fazer o arredondamento tradicional para estatísticas nas ciências, este é um invólucro útil para que a
round
função funcione conforme o esperado, necessitando deimport
coisas extrasDecimal
.Aha! Então, com base nisso, podemos fazer uma função ...
Basicamente, isso adiciona um valor garantido para ser menor que o dígito menos especificado da string em que você está tentando usar
round
. Ao adicionar essa pequena quantidade, ele preserva oround
comportamento da maioria dos casos, enquanto agora assegura se o dígito inferior ao que está sendo arredondado é arredondado para5
cima e, se for4
, arredondado para baixo.A abordagem do uso
10**(-len(val)-1)
foi deliberada, pois é o maior número pequeno que você pode adicionar para forçar a mudança, além de garantir que o valor adicionado nunca mude o arredondamento, mesmo que o decimal.
esteja ausente. Eu poderia usar apenas10**(-len(val))
um condicionalif (val>1)
para subtrair1
mais ... mas é mais simples sempre subtrair o valor,1
pois isso não mudará muito o intervalo aplicável de números decimais que esta solução alternativa pode manipular adequadamente. Essa abordagem falhará se seus valores atingirem os limites do tipo, isso falhará, mas, para quase todo o intervalo de valores decimais válidos, deve funcionar.Você também pode usar a biblioteca decimal para fazer isso, mas o invólucro que proponho é mais simples e pode ser preferido em alguns casos.
Edit: Obrigado Blckknght por apontar que a
5
caixa de franja ocorre apenas para determinados valores. Além disso, uma versão anterior desta resposta não era explícita o suficiente para que o comportamento de arredondamento ímpar ocorresse apenas quando o dígito imediatamente inferior ao dígito para o qual você está arredondando possui a5
.fonte
5
o último dígito sempre arredondado para baixo. Isso não é o caso em um teste rápido eu fiz com números como1.5
,2.5
,3.5
e assim por diante e1.05
,1.15
,1.25
,1.35
arredondando a uma casa decimal. O primeiro conjunto (metades exatas que arredondam para números inteiros pequenos) sempre arredonda para um número inteiro par. O último conjunto não arredonda consistentemente, provavelmente devido a representações binárias inexatas de alguns dos valores. Os carros alegóricos que têm representações binárias exatas, como o1.25
arredondamento, têm um dígito ainda menos significativo, mas os outros parecem arredondar aleatoriamente.round(4.0005,3)
dá4.0
eround(1.0005,3)
dá1.0
, masround(2.0005,3)
dá2.001
eround(3.0005,3)
dá3.001
. Mas é exatamente por isso que minha solução proposta é necessária ... você não sabe o que esperar da rodada de ações, nesse caso significativo!, digits
no final dessa declaração de retorno? Sem trocadilhos. ( média eu quero dizer)Para positivos, tente
Para fazê-lo funcionar também com negativos, tente
int()
funciona como uma função de piso e, portanto, você pode explorar essa propriedade. Esta é definitivamente a maneira mais rápida.fonte
>>> x=-0.999
>>> int(x), round(x), int(x+0.5)
(0, -1.0, 0)
O Python não está fazendo apenas a metade da rodada , como prescrito pelo IEEE 754 ?
Tenha cuidado ao redefinir ou usar arredondamentos "não padrão" ...
(Consulte também https://stackoverflow.com/a/33019948/109839 )
fonte
Round half to even
não é absolutamente prescrito pelo IEEE 754, mas é apenas uma das várias opções de arredondamento descritas pelo padrão .Round to nearest, ties away from zero
(ou seja, o comportamento que a maioria das pessoas espera) também é uma opção e é o padrão, por exemplo, em C / C ++.round
está explicado) e está fazendo isso de acordo com o modo como "metade da metade para o par" é prescrito para trabalhar (ou descrito) pela norma.Você também pode usar numpy assumindo que, se estiver usando python3.x, aqui está um exemplo
fonte
Sua solução está chamando sem especificar o segundo argumento (número de casas decimais)
que é um resultado muito melhor do que
Na documentação do Python em https://docs.python.org/3/library/functions.html#round
fonte
Se você precisar (por exemplo) de uma aproximação de dois dígitos para A,
int(A*100+0.5)/100.0
fará o que estiver procurando.Se você precisar de uma aproximação de três dígitos, multiplique e divida por 1000 e assim por diante.
fonte
Algo assim também deve funcionar
fonte
Para esse propósito, sugiro apenas fazer o seguinte -
Isso lhe dará o número inteiro mais próximo.
Espero que isto ajude!!
fonte
Eu uso e posso recomendar a seguinte solução (python3.6):
Funciona bem para meio-números (positivos e negativos) e funciona ainda mais rápido que int (rodada (x)):
fonte