¿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?


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


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

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 -∞

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.


66
extremadamente sofisticado es
Alon


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.


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.

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.


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).


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)


-1

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

number=1.5
round(number)-1
> 1

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.