Cómo comprobar si un valor flotante es un número entero


Estoy tratando de encontrar la raíz cúbica más grande que es un número entero, que es menos de 12.000.

processing = True
n = 12000
while processing:
    n -= 1
    if n ** (1/3) == #checks to see if this has decimals or not

No estoy seguro de cómo comprobar si es un número entero o no! Podría convertirlo en una cadena y luego usar la indexación para verificar los valores finales y ver si son cero o no, aunque parece bastante engorroso. ¿Hay una manera más simple?

Author: Martijn Pieters, 2014-02-05

11 answers

Para comprobar si un valor flotante es un número entero, utilice el float.is_integer() método :

>>> (1.0).is_integer()
True
>>> (1.555).is_integer()
False

El método se agregó al tipo float en Python 2.6.

Tenga en cuenta que en Python 2, 1/3 es 0 (división de piso para operandos enteros!), y que la aritmética de coma flotante puede ser imprecisa (a float es una aproximación usando fracciones binarias, no un número real preciso). Pero ajustando su bucle un poco esto da:

>>> for n in range(12000, -1, -1):
...     if (n ** (1.0/3)).is_integer():
...         print n
... 
27
8
1
0

Lo que significa que cualquier cosa más de 3 al cubo, (incluyendo 10648) se perdió debido a la imprecisión antes mencionada:

>>> (4**3) ** (1.0/3)
3.9999999999999996
>>> 10648 ** (1.0/3)
21.999999999999996

Tendrías que buscar números cerrar al número entero en su lugar, o no usar float() para encontrar tu número. Como redondear la raíz cúbica de 12000:

>>> int(12000 ** (1.0/3))
22
>>> 22 ** 3
10648

Si está utilizando Python 3.5 o posterior, puede utilizar el math.isclose() función para ver si un valor de coma flotante está dentro de un margen configurable:

>>> from math import isclose
>>> isclose((4**3) ** (1.0/3), 4)
True
>>> isclose(10648 ** (1.0/3), 22)
True

Para versiones anteriores, el ingenuo implementación de esa función (omitiendo la comprobación de errores e ignorando infinity y NaN) como se menciona en PEP485 :

def isclose(a, b, rel_tol=1e-9, abs_tol=0.0):
    return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
 231
Author: Martijn Pieters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-10 19:15:06

Podemos usar el operador modulo ( % ). Esto nos dice cuántos restos tenemos cuando dividimos x por y-expresa como x % y. Cada número entero debe dividirse por 1, por lo que si hay un resto, no debe ser un número entero.

Esta función devolverá un booleano, True o False, dependiendo de si n es un número entero.

def is_whole(n):
    if n % 1 == 0:
        return True
    else:
        return False
 15
Author: MagikCow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-30 13:56:45

Podrías usar esto:

if k == int(k):
    print(str(k) + "is a whole number!"
 11
Author: Juri Robl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-05 17:09:38

Puede usar una operación modulo para eso.

if (n ** (1.0/3)) % 1 != 0:
    print("We have a decimal number here!")
 6
Author: Jakub Jirutka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-05 17:16:00

No es necesario hacer un bucle o comprobar nada. Basta con tomar una raíz cúbica de 12.000 y redondearla hacia abajo:

r = int(12000**(1/3.0))
print r*r*r # 10648
 6
Author: georg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-05 17:22:31

¿No sería más fácil probar las raíces cúbicas? Comience con 20 (20**3 = 8000) y vaya hasta 30 (30**3 = 27000). Entonces usted tiene que probar menos de 10 enteros.

for i in range(20, 30):
    print("Trying {0}".format(i))
    if i ** 3 > 12000:
        print("Maximum integral cube root less than 12000: {0}".format(i - 1))
        break
 5
Author: hughdbrown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-05 17:11:47

¿Qué tal

if x%1==0:
    print "is integer"
 3
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-14 08:56:23

Las respuestas anteriores funcionan para muchos casos, pero faltan algunos. Considere lo siguiente:

fl = sum([0.1]*10)  # this is 0.9999999999999999, but we want to say it IS an int

Usando esto como punto de referencia, algunas de las otras sugerencias no obtienen el comportamiento que podríamos desear:

fl.is_integer() # False

fl % 1 == 0     # False

En su lugar intente:

def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

def is_integer(fl):
    return isclose(fl, round(fl))

Ahora tenemos:

is_integer(fl)   # True

isclose viene con Python 3.5 + , y para otros Python puede usar esta definición casi equivalente (como se menciona en el correspondiente PEP)

 2
Author: control_fd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-10 17:24:00

Puede utilizar el round la función para calcular el valor.

Sí en python como muchos han señalado cuando calculamos el valor de una raíz cúbica, le dará una salida con un poco de error. Para comprobar si el valor es un número entero puede utilizar la siguiente función:

def cube_integer(n):
    if round(n**(1.0/3.0))**3 == n:
        return True
    return False

Pero recuerda que int(n) es equivalente a math.floor y debido a esto si usted encuentra el int(41063625**(1.0/3.0)) obtendrá 344 en lugar de 345.

Así que tenga cuidado al usar int con las raíces cúbicas.

Espero haber respondido a su pregunta. Si tiene alguna otra consulta entonces puede contactarme .

 0
Author: Anivarth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-17 09:24:53

Solo una información lateral, is_integer está haciendo internamente:

import math
isInteger = (math.floor(x) == x)

No exactamente en python, pero la implementación de cpython se implementa como se mencionó anteriormente.

 0
Author: user1767754,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-22 08:04:21

Intenta usar:

int(val) == val

Dará mucha más precisión que cualquier otro método.

 -1
Author: Nishant Ingle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-25 10:00:39