¿Redondear un número de coma flotante al entero más cercano?

127

Como sugiere el título, quiero tomar un número de coma flotante y redondearlo al entero más cercano. Sin embargo, si no es un todo, SIEMPRE quiero redondear la variable, independientemente de lo cerca que esté del siguiente entero. ¿Hay alguna forma de hacer esto?

Anthony Perez
fuente
2
Una posible dificultad es que los formatos de coma flotante IEEE pueden representar números tan grandes que la granularidad es mayor que 1. De modo que, si bien puede redondear x hacia abajo, redondear x + 1 hacia abajo no le dará el resultado que espera.
dmckee --- ex-gatito moderador
Por favor, publique algunos ejemplos.
Ashwini Chaudhary

Respuestas:

178

Sencillo

print int(x)

funcionará tan bien

Makaveli
fuente
77
int (0.6) = 0 en lugar de 1
Helin Wang
39
@HelinWang Eso es exactamente lo que OP solicitó.
Petr Peller
55
Este parece ser el enfoque más pitónico.
Gyan Veda
23
Esto funciona bien para números positivos, pero los números negativos se redondearán:int(-23.3) == 23
Alex Riley
2
y no funciona para un número más allá del rango entero, como 600851475143, básicamente marcará un error de memoria.
Muyide Ibukun
77

Uno de estos debería funcionar:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2
U2EF1
fuente
14
La salida de math.trunces un número entero, mientras que la salida de math.floores un flotante.
evedovelli
66
@evedovelli: Realmente ya no. type(math.floor(1.51)) -> inty a type(math.trunc(1.51)) -> intpartir depython 3.6.0
SKPS
44
Estas opciones son más explícitas que "int (x)" y, por lo tanto, son más Pythonic.
Tristán
44
x//1

El //operador devuelve el piso de la división. Dado que dividir entre 1 no cambia su número, esto es equivalente al piso pero no se necesita importar. Notas:

  1. Esto devuelve un flotador
  2. Esto se redondea hacia -∞
Huy D
fuente
Buena adición. int(-1.1) == -1sin -1.1//1 == -2.0embargo decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(como se documenta, la afirmación 2 no es cierta decimal), por lo que confiar en cómo se //comporta no es completamente estable, incluso hoy.
Tino
28

Para obtener el resultado de coma flotante, simplemente use:

round(x-0.5)

Funciona también para números negativos.

DmitryG
fuente
66
extremadamente sofisticado es
Alon
27

Creo que necesitas una función de piso:

math.floor (x)

voidMainReturn
fuente
55
en python 2 devuelve un flotador, mientras que en python 3 devuelve int
voidMainReturn
1
int (math.floor (x)) o float (math.floor (x))
Jeff
9

Mucha gente dice usar int(x), y esto funciona bien para la mayoría de los casos, pero hay un pequeño problema. Si el resultado de OP es:

x = 1.9999999999999999

se redondeará a

x = 2

después del 16 9 se redondeará. Esto no es un gran problema si está seguro de que nunca se encontrará con tal cosa. Pero es algo a tener en cuenta.

lokilindo
fuente
17
Esto se debe 1.9999999999999999a que 2.0en realidad es igual a en la representación interna float64. I. e. ya se redondea tan pronto como se analiza en un flotante, ya que un flotante de 64 bits no puede representar tantos dígitos significativos. Puede verificar eso con la evaluación 1.9999999999999999 == 2.0. Y si sospecha que la operación igual hace un redondeo en los flotadores, puede comparar la representación binaria con struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0), que también es igual.
blubberdiblub
44
Y si ese es exactamente tu punto, entonces no veo qué le pasa int(). El valor ya es 2.0 y lo convertirá felizmente en 2.
blubberdiblub
1
Si la intención de OP (o quien lea esto en el futuro) es usar el entero más cercano (y no el valor de redondeo) por cualquier razón, entonces sería algo a tener en cuenta.
lokilindo
3
@lokilindo Pero esto no tiene nada que ver int(), solo tiene que ver con un uso incorrecto defloat , como 1.9999999999999999se redondea 2.0 en el momento de la compilación (mientras int()se llama el tiempo de ejecución). Si usa el tipo de datos correcto para la variable, todo funciona como se esperaba: int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))da1
Tino
6

Si no desea importar matemáticas, puede usar:

int(round(x))

Aquí hay una pieza de documentación:

>>> help(round)
Help on built-in function round in module __builtin__:

round(...)
    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.
Tyler
fuente
Gracias por tu respuesta. La próxima vez obtendrá una mejor recepción si escribe el código apropiado (paréntesis) y proporciona alguna documentación.
Geoff
2
roundya fue discutido y rechazado como respuesta cuando se hizo esta pregunta hace un año. OP quiere math.floor.
Adam Smith
3

Si trabaja con numpy, puede usar la siguiente solución que también funciona con números negativos (también funciona en matrices)

import numpy as np
def round_down(num):
    if num < 0:
        return -np.ceil(abs(num))
    else:
        return np.int32(num)
round_down = np.vectorize(round_down)

round_down([-1.1, -1.5, -1.6, 0, 1.1, 1.5, 1.6])
> array([-2., -2., -2.,  0.,  1.,  1.,  1.])

Creo que también funcionará si solo usa el mathmódulo en lugar del numpymódulo.

Señor poin
fuente
1

No sé si resolvió esto, pero me topé con esta pregunta. Si desea deshacerse de los puntos decimales, puede usar int (x) y eliminará todos los dígitos decimales. No hay necesidad de usar round (x).

Gaahbon
fuente
1

Simplemente haga una ronda (x-0.5), esto siempre devolverá el siguiente valor entero redondeado hacia abajo de su flotador. También puedes redondear fácilmente haciendo do round (x + 0.5)

Dominic Nagel
fuente
-1

Puede ser muy simple, pero ¿no podrías redondearlo y luego menos 1? Por ejemplo:

number=1.5
round(number)-1
> 1

fuente
44
Esto da la respuesta incorrecta para enteros enteros. Por ejemplo, 2.0 redondeado hacia arriba es 2, y si resta 1 obtiene el resultado incorrecto 1.
Pascal Cuoq
@PascalCuoq No entiendo tu problema. ¿Quieres 1.0 como resultado? Porque OP claramente quería redondear y luego numerar al más cercano integer.
bad_keypoints
1
@bad_keypoints No creo que el OP quiera redondear 2.0 a 1.
Pascal Cuoq
@PascalCuoq lo siento, solo volví a mirar la respuesta en el hilo de comentarios de lo que estamos.
bad_keypoints
-3

Usé este código donde restas 0.5 del número y cuando lo redondeas, es el número original redondeado hacia abajo.

redondo (a-0.5)

usuario10555509
fuente
1
¿Cuál es la diferencia de esta respuesta existente ?
xskxzr