web-dev-qa-db-fra.com

Comment vérifier si une valeur flottante est un nombre entier

J'essaie de trouver la racine de cube la plus grande qui soit un nombre entier, c'est-à-dire moins de 12 000. 

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

Je ne sais pas comment vérifier s'il s'agit d'un nombre entier ou non! Je pourrais le convertir en chaîne puis utiliser l'indexation pour vérifier les valeurs finales et voir si elles sont nulles ou non, ce qui semble plutôt fastidieux. Y a-t-il un moyen plus simple?

141
chopper draw lion4

Pour vérifier si une valeur flottante est un nombre entier, utilisez la méthode float.is_integer() :

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

La méthode a été ajoutée au type float dans Python 2.6.

Notez que dans Python 2, 1/3 est 0 (division de plancher pour les opérandes entiers!) Et que l'arithmétique en virgule flottante peut être imprécise (une float est une approximation utilisant des fractions binaires, non un nombre réel précis) . Mais en ajustant un peu votre boucle, cela donne:

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

ce qui signifie que tout ce qui dépasse 3 cubes (y compris 10648) a été omis en raison de l'imprécision susmentionnée:

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

Vous devez plutôt vérifier les numéros fermer à tout le nombre, ou ne pas utiliser float() pour rechercher votre numéro. Comme en arrondissant la racine du cube de 12000:

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

Si vous utilisez Python 3.5 ou une version plus récente, vous pouvez utiliser la fonction math.isclose() pour voir si une valeur à virgule flottante est comprise dans une marge configurable:

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

Pour les versions plus anciennes, l’implémentation naïve de cette fonction (ignorer la vérification des erreurs et ignorer l’infini et NaN) comme indiqué dans 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)
269
Martijn Pieters

Nous pouvons utiliser l'opérateur modulo (%). Cela nous indique combien de restes nous avons lorsque nous divisons x par y - exprime sous la forme x % y. Chaque nombre entier doit être divisé par 1, donc s'il reste un reste, il ne doit pas s'agir d'un nombre entier. 

Cette fonction retournera un booléen, True ou False, selon que n est un nombre entier.

def is_whole(n):
    if n % 1 == 0:
        return True
    else:
        return False
19
MagikCow

Vous pouvez utiliser ceci:

if k == int(k):
    print(str(k) + "is a whole number!"
12
Juri Robl

Vous pouvez utiliser une opération modulo pour cela.

if (n ** (1.0/3)) % 1 != 0:
    print("We have a decimal number here!")
7
Jakub Jirutka

Vous n'avez pas besoin de faire une boucle ou de vérifier quoi que ce soit. Il suffit de prendre une racine cubique de 12 000 et de l’arrondir: 

r = int(12000**(1/3.0))
print r*r*r # 10648
7
georg

Ne serait-il pas plus facile de tester les racines du cube? Commencez avec 20 (20 ** 3 = 8000) et allez jusqu'à 30 (30 ** 3 = 27000). Ensuite, vous devez tester moins de 10 entiers.

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
6
hughdbrown

Que diriez-vous 

if x%1==0:
    print "is integer"
3
Daniel

Les réponses ci-dessus fonctionnent dans de nombreux cas, mais certaines d'entre elles en manquent. Considérer ce qui suit:

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

En utilisant ceci comme point de repère, certaines des autres suggestions n'obtiennent pas le comportement que nous pourrions souhaiter:

fl.is_integer() # False

fl % 1 == 0     # False

Au lieu d'essayer:

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

maintenant nous avons:

is_integer(fl)   # True

isclose vient avec Python 3.5+ , et pour les autres Python, vous pouvez utiliser cette définition pour l'essentiel équivalente (comme indiqué dans le PEP correspondant)

2
control_fd

Vous pouvez utiliser la fonction round pour calculer la valeur. 

Oui en python, comme beaucoup l'ont indiqué lorsque nous calculons la valeur d'une racine de cube, cela vous donnera une sortie avec un peu d'erreur. Pour vérifier si la valeur est un nombre entier, vous pouvez utiliser la fonction suivante:

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

Mais rappelez-vous que int(n) est équivalent à math.floor et pour cette raison si vous trouvez la int(41063625**(1.0/3.0)), vous obtiendrez 344 au lieu de 345.

Soyez donc prudent lorsque vous utilisez int avec des racines de cube.

J'espère avoir répondu à votre question. Si vous avez d'autres questions, vous pouvez me contacter .

0
Anivarth

Juste une information de côté, is_integer fait en interne: 

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

Pas exactement en python, mais l'implémentation de cpython est implémentée comme mentionné ci-dessus.

0
user1767754