Nous savons que par exemple modulo de puissance de deux peut être exprimé comme ceci:
x % 2 inpower n == x & (2 inpower n - 1).
Exemples:
x % 2 == x & 1
x % 4 == x & 3
x % 8 == x & 7
Qu'en est-il de la non-puissance générale de deux nombres?
Disons:
x% 7 ==?
Réponses:
Tout d'abord, il n'est pas exact de dire que
Simple contre - :
x = -1
. Dans de nombreuses langues, y compris Java,-1 % 2 == -1
. Autrement dit,%
n'est pas nécessairement la définition mathématique traditionnelle de modulo. Java l'appelle par exemple "opérateur de reste".En ce qui concerne l'optimisation au niveau du bit, seules les puissances modulo de deux peuvent "facilement" être effectuées en arithmétique au niveau du bit. D'une manière générale, seules les puissances modulo de base b peuvent "facilement" être réalisées avec une représentation en base b des nombres.
En base 10, par exemple, pour non-négatif
N
,N mod 10^k
prend juste lesk
chiffres les moins significatifs .Références
la source
-1 = -1 (mod 2)
, vous ne savez pas à quoi vous voulez en venir - vous voulez dire que ce n'est pas la même chose que le reste IEEE 754?(a / b) / b + a % b == a
, pour les opérateurs de type C, a et b entiers, b non nul, et aussi celaabs(a % b) < abs(b)
avec les mêmes conditions.(a / b)
*b + a % b == a
.Il n'y a qu'un moyen simple de trouver un module de 2 ^ i nombres en utilisant le bit.
Il existe une manière ingénieuse de résoudre les cas de Mersenne selon le lien tel que n% 3, n% 7 ... Il existe des cas particuliers pour n% 5, n% 255 et des cas composites tels que n% 6.
Pour les cas 2 ^ i, (2, 4, 8, 16 ...)
Les plus compliqués sont difficiles à expliquer. Ne lisez que si vous êtes très curieux.
la source
Cela ne fonctionne que pour les puissances de deux (et souvent uniquement positives) car elles ont la propriété unique de n'avoir qu'un seul bit mis à «1» dans leur représentation binaire. Étant donné qu'aucune autre classe de nombres ne partage cette propriété, vous ne pouvez pas créer d'expressions et de bits pour la plupart des expressions de module.
la source
C'est spécifiquement un cas particulier car les ordinateurs représentent des nombres en base 2. Ceci est généralisable:
(nombre) base % base x
équivaut aux x derniers chiffres de la base (nombre) .
la source
Il existe des modules autres que les puissances de 2 pour lesquels des algorithmes efficaces existent.
Par exemple, si x est 32 bits non signé int alors x% 3 = popcnt (x & 0x55555555) - popcnt (x & 0xaaaaaaaa)
la source
Modulo "7" sans opérateur "%"
la source
Ne pas utiliser l'
&
opérateur binaire et ( ) en binaire, il n'y en a pas. Esquisse de preuve:Supposons qu'il y ait une valeur k telle que
x & k == x % (k + 1)
, mais k! = 2 ^ n - 1 . Alors si x == k , l'expressionx & k
semble "fonctionner correctement" et le résultat est k . Maintenant, considérons x == ki : s'il y avait des bits "0" dans k , il y a un certain i supérieur à 0 qui ki ne peut être exprimé qu'avec 1 bits dans ces positions. (Par exemple, 1011 (11) doit devenir 0111 (7) lorsque 100 (4) en a été soustrait, dans ce cas, le bit 000 devient 100 lorsque i = 4. ) Si un bit de l'expression de k doit changer de zéro à un pour représenter ki, alors il ne peut pas calculer correctement x% (k + 1) , qui dans ce cas devrait être ki , mais il n'y a aucun moyen pour le booléen au niveau du bit et de produire cette valeur étant donné le masque.la source
Dans ce cas précis (mod 7), nous pouvons toujours remplacer% 7 par des opérateurs bit à bit:
Cela fonctionne car 8% 7 = 1. Evidemment, ce code est probablement moins efficace qu'un simple x% 7, et certainement moins lisible.
la source
En utilisant bitwise_and, bitwise_or et bitwise_not, vous pouvez modifier n'importe quelle configuration de bit en une autre configuration de bit (c'est-à-dire que cet ensemble d'opérateurs est "fonctionnellement complet"). Cependant, pour des opérations comme le module, la formule générale serait forcément assez compliquée, je ne prendrais même pas la peine d'essayer de la recréer.
la source