Question

Je suis tombé sur un bug très étrange. Lire les commentaires dans le code pour voir ce que le bug est exactement, mais essentiellement une variable modulo 1 retourne 1 (mais il ne correspond pas à 1!). Je suppose qu'il ya un problème d'affichage où le flotteur est extrêmement proche de l'un, mais pas exactement. Cependant, il devrait être moduloing à zéro. Je ne peux pas tester ce cas facilement parce que (dernière% 1)! = 1.0! Lorsque je tente de brancher les mêmes numéros dans un autre terminal python, tout se comporte correctement. Que se passe-t-il?

def r(k,i,p):
    first = i*p
    last = first + p

    steps = int((i+1)*p) - int(i*p)
    if steps < 1:
        return p
    elif steps >= 1:
        if k == 0:
            return 1 - (first % 1)
        elif k == steps:
            if i == 189:
                print last, 1, type(last), last % 1, last - int(last)
                # Prints: 73.0 1 <type 'float'> 1.0 1.0
                print last % 1 == 1 # Returns False
            if last % 1 == 1.0:
                return 0
            return (last % 1)
        else:
            return 1
Était-ce utile?

La solution

Bienvenue sur IEEE754, profiter de votre séjour .

Autres conseils

Imprimer ne montre pas la pleine précision du nombre que stockées, vous pouvez utiliser repr() pour faire

>>> last=72.99999999999999
>>> print last, 1, type(last), last % 1, last - int(last)
73.0 1 <type 'float'> 1.0 1.0
>>> print last % 1 == 1
False
>>> print repr(last), 1, type(last), repr(last%1), repr(last - int(last))
72.999999999999986 1 <type 'float'> 0.99999999999998579 0.99999999999998579
>>> 

Vous devez utiliser math.fmod (x, y). Voici un extrait de http://docs.python.org/library/math.html:

"Notez que l'expression Python x% y peut ne pas retourner le même résultat L'objectif de la norme C est que fmod (x, y) exactement (mathématiquement, à une précision infinie) égale à x - n * y pour. un entier n tel que le résultat a le même signe que x et grandeur inférieure abs (y). x% y de Python renvoie un résultat avec le signe de y au lieu, et peut ne pas être exactement calculable pour les arguments de flotteur. par exemple, fmod (-1e-100, 1E100) est -1e-100, mais le résultat de -1e-100% 1E100 Python est 1e100-1e-100, qui ne peut pas être représenté exactement comme un flotteur, et tours à la surprenante 1E100 . Pour cette raison, fmod () fonction est généralement préférée lorsque l'on travaille avec des flotteurs, tandis que x% y de Python est préféré lorsque l'on travaille avec des nombres entiers. "

Vous pouvez essayer la fonction math.fmod au lieu de last % 1 , peut-être qu'il est mieux adapté pour vous problème. Ou vous pourriez vous reformuler problème dans l'espace entier.

Quoi qu'il en soit, il est bon de comparer les valeurs flottantes utilisant l'opérateur de == d'égalité, en raison des résultats imprécis même des activités seemigly triviales comme 0.1 + 0.2 == 0.3

Si vous avez besoin de précision arbitraire, il y a quelques projets qui ne tiennent cela. gmpy poignées entiers multi-précision, mpmath qui a l'air assez bon et BigFloat qui enveloppe MPFR. Ce que vous avez peut-être assez par la réponse de gnibbler, mais, au cas où.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top