He estado tratando de redondear números flotantes largos como:
32.268907563;
32.268907563;
31.2396694215;
33.6206896552;
...
Sin éxito hasta ahora. Lo intenté math.ceil(x)
, math.floor(x)
(aunque eso se redondearía hacia arriba o hacia abajo, que no es lo que estoy buscando) y round(x)
que tampoco funcionó (todavía números flotantes).
¿Qué puedo hacer?
EDITAR: 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)
Respuestas:
Lo redondeará y lo cambiará a entero
EDITAR:
No está asignando int (round (h)) a ninguna variable. Cuando llama a int (round (h)), devuelve el número entero pero no hace nada más; tienes que cambiar esa línea por:
Para asignar el nuevo valor a h
EDITAR 2:
Como @plowman dijo en los comentarios, Python
round()
no funciona como uno esperaría normalmente, y eso se debe a que la forma en que se almacena el número como variable generalmente no es la forma en que lo ves en la pantalla. Hay muchas respuestas que explican este comportamiento:round () no parece estar redondeando correctamente
Una forma de evitar este problema es usar el decimal como se indica en esta respuesta: https://stackoverflow.com/a/15398691/4345659
Para que esta respuesta funcione correctamente sin usar bibliotecas adicionales, sería conveniente usar una función de redondeo personalizada. Después de muchas correcciones, se me ocurrió la siguiente solución, que por lo que probé evitó todos los problemas de almacenamiento. Se basa en el uso de la representación de cadena, obtenida con
repr()
(str()
¡ NO !). Parece hacky pero fue la única forma que encontré para resolver todos los casos. Funciona con Python2 y Python3.Pruebas:
Finalmente, la respuesta corregida sería:
EDITAR 3:
Pruebas:
El problema aquí es que el
dec
enésimo decimal puede ser 9 y si eldec+1
enésimo dígito> = 5, el 9 se convertirá en un 0 y un 1 debería llevarse aldec-1
enésimo dígito.Si tomamos esto en consideración, obtenemos:
En la situación descrita anteriormente
b = 10
y la versión anterior sería simplemente concatenara
yb
que daría lugar a una concatenación de10
donde el 0 se arrastra desaparecería. Esta versión se transformab
en el lugar decimal correcto basado endec
, como un acarreo adecuado.fuente
int(round(4.5))
redondea a 4 mientras queint(round(4.500001))
redondea correctamente a 5.round(x)
es suficiente en Python 3.6.2 (y quizás también en versiones inferiores). El resultado ya es de tipo int. Nota:round(x, n)
será de tipo flotante.Uso
round(x, y)
. Redondeará su número al lugar decimal deseado.Por ejemplo:
fuente
round(value,significantDigit)
es la solución ordinaria, sin embargo, esto no funciona como cabría esperar desde una perspectiva matemática cuando los valores redondos terminan en5
. Si el5
está en el dígito justo después del que se redondea, estos valores solo se redondean a veces como se esperaba (es decir, se8.005
redondea a dos dígitos decimales8.01
). Para ciertos valores debido a las peculiaridades de las matemáticas de coma flotante, ¡se redondean hacia abajo!es decir
Extraño.
Suponiendo que su intención es hacer el redondeo tradicional para las estadísticas en las ciencias, este es un útil contenedor para que la
round
función funcione como se espera y necesitaimport
cosas adicionales comoDecimal
.¡Ajá! Entonces, en base a esto, podemos hacer una función ...
Básicamente, esto agrega un valor garantizado para ser más pequeño que el dígito menos dado de la cadena que está tratando de usar
round
. Al agregar esa pequeña cantidad, preserva elround
comportamiento de la mayoría de los casos, al tiempo que garantiza que el dígito inferior al redondeado se redondea hacia5
arriba y, si es así,4
se redondea hacia abajo.El enfoque de uso
10**(-len(val)-1)
fue deliberado, ya que es el número pequeño más grande que puede agregar para forzar el cambio, al tiempo que garantiza que el valor que agregue nunca cambie el redondeo, incluso si.
falta el decimal . Podría usar solo10**(-len(val))
con una condiciónif (val>1)
para restar1
más ... pero es más simple restar siempre,1
ya que eso no cambiará mucho el rango aplicable de números decimales que esta solución puede manejar adecuadamente. Este enfoque fallará si sus valores alcanzan los límites del tipo, esto fallará, pero para casi todo el rango de valores decimales válidos debería funcionar.También puede usar la biblioteca decimal para lograr esto, pero el contenedor que propongo es más simple y puede preferirse en algunos casos.
Editar: Gracias Blckknght por señalar que el
5
caso marginal se produce solo para ciertos valores. Además, una versión anterior de esta respuesta no fue lo suficientemente explícita como para que el comportamiento de redondeo impar ocurra solo cuando el dígito inmediatamente inferior al dígito al que está redondeando tiene un5
.fuente
5
como su último dígito siempre se redondearán hacia abajo. Ese no es el caso en una prueba rápida que acabo de hacer con números como1.5
,2.5
,3.5
y así sucesivamente y1.05
,1.15
,1.25
,1.35
redondeando a un decimal. El primer conjunto (mitades exactas redondeando a enteros pequeños) siempre se redondea a un entero par. El último conjunto no se redondea consistentemente, probablemente debido a representaciones binarias inexactas de algunos de los valores. Los flotadores que tienen representaciones binarias exactas como1.25
redondear tienen un dígito aún menos significativo, pero los otros parecen redondearse al azar.round(4.0005,3)
da4.0
yround(1.0005,3)
da1.0
, peroround(2.0005,3)
da2.001
yround(3.0005,3)
da3.001
. Pero es precisamente por eso que mi solución propuesta es necesaria ... ¡no sabes qué esperar de la ronda de acciones, en este caso significativo!, digits
al final de esa declaración de devolución? Sin juego de palabras. ( Quiero decir, quiero decir)Para aspectos positivos, intente
Para que funcione también para los negativos, intente
int()
funciona como una función de piso y, por lo tanto, puede explotar esta propiedad. Esta es definitivamente la forma más rápida.fuente
>>> x=-0.999
>>> int(x), round(x), int(x+0.5)
(0, -1.0, 0)
¿No solo Python está haciendo la mitad de la ronda , como lo prescribe IEEE 754 ?
Tenga cuidado al redefinir, o al usar el redondeo "no estándar" ...
(Ver también https://stackoverflow.com/a/33019948/109839 )
fuente
Round half to even
absolutamente no está prescrito por IEEE 754, sino que es solo una de varias opciones de redondeo descritas por el estándar .Round to nearest, ties away from zero
(es decir, el comportamiento que la mayoría de la gente espera) también es una opción, y es el predeterminado en, por ejemplo, C / C ++.round
se explica) y lo hace de acuerdo con la forma en que se prescribe "redondear a la mitad para igualar" para trabajar (o descrito) por el estándar.También puede usar numpy asumiendo si está usando python3.x aquí hay un ejemplo
fuente
Su solución es llamar sin especificar el segundo argumento (número de decimales)
que es un resultado mucho mejor que
De la documentación de Python en https://docs.python.org/3/library/functions.html#round
fuente
Si necesita (por ejemplo) una aproximación de dos dígitos para A, entonces
int(A*100+0.5)/100.0
hará lo que está buscando.Si necesita una aproximación de tres dígitos, multiplique y divida por 1000 y así sucesivamente.
fuente
Algo como esto también debería funcionar
fuente
Para este propósito, sugeriría hacer lo siguiente:
Esto te dará el entero más cercano.
¡¡Espero que esto ayude!!
fuente
Utilizo y puedo recomendar la siguiente solución (python3.6):
Funciona bien para números medios (positivos y negativos) y funciona incluso más rápido que int (round (x)):
fuente