web-dev-qa-db-fra.com

Opérateur Modulo dans Python

Que fait modulo dans le code suivant?

from math import *
3.14 % 2 * pi

Comment calcule-t-on modulo sur un nombre à virgule flottante?

51
KodeWarrior

Quand vous avez l'expression:

a % b = c

Cela signifie vraiment qu'il existe un entier n qui rend c aussi petit que possible, mais non négatif.

a - n*b = c

À la main, vous pouvez simplement soustraire 2 (ou ajouter 2 si votre nombre est négatif) encore et encore jusqu'à ce que le résultat final soit le plus petit nombre positif possible:

  3.14 % 2
= 3.14 - 1 * 2
= 1.14

De plus, 3.14 % 2 * pi est interprété comme (3.14 % 2) * pi. Je ne sais pas si vous vouliez écrire 3.14 % (2 * pi) (dans les deux cas, l'algorithme est le même. Soustrayez/ajoutez jusqu'à ce que le nombre soit aussi petit que possible).

63
Blender

Outre les autres réponses, la fmod documentation contient des informations intéressantes sur le sujet:

math.fmod(x, y)

Renvoie fmod(x, y), tel que défini par la bibliothèque C de la plateforme. Notez que l'expression Python x % y_ peut ne pas renvoyer le même résultat. Le but de la norme C est que fmod(x, y) soit exactement (mathématiquement; à précision infinie) égal à _x - n*y_ pour un entier n tel que le résultat ait le même signe que x et une magnitude inférieure à abs(y). _x % y_ de Python renvoie un résultat portant le signe y à la place et peut ne pas être exactement calculable pour les arguments flottants. Par exemple, fmod(-1e-100, 1e100) est _-1e-100_, mais le résultat de Python _-1e-100 % 1e100_ est _1e100-1e-100_, qui ne peut pas être représenté exactement comme un flottant, et arrondit au surprenant _1e100_. Pour cette raison, la fonction fmod() est généralement préférée lorsqu’on travaille avec des flottants, alors que Python’s _x % y_ est préféré lorsqu’on travaille avec des entiers.

24
Thomas

Même chose que vous attendez d'un modulo normal .. par exemple. 7 % 4 = 3, 7.3 % 4.0 = 3.3

Méfiez-vous des problèmes de précision en virgule flottante.

3
Xorlev

identique à un modulo normal 3.14 % 6.28 = 3.14, tout comme 3.14%4 =3.143.14%2 = 1.14 (le reste ...)

2
Joran Beasley

vous devriez utiliser fmod (a, b)

While abs(x%y) < abs(y) is true mathématiquement, pour floats il peut ne pas être vrai numériquement en raison de roundoff.

Par exemple, en supposant une plate-forme sur laquelle un Python float est un nombre double précision IEEE 754, afin que -1e-100 % 1e100 ait le même signe que 1e100, le résultat calculé est -1e-100 + 1e100, qui est numériquement exactement égal à 1e100.

La fonction fmod() dans le module mathématique renvoie un résultat dont le signe correspond au signe du premier argument et renvoie donc -1e-100 dans ce cas. L'approche la plus appropriée dépend de l'application.

where x = a%b est utilisé pour le modulo entier

1
praveen kansara