web-dev-qa-db-fra.com

Comment vérifier si la valeur a même parité de bits ou impaire?

Une valeur a même parité si elle a un nombre pair de 1 bits. Une valeur a une parité impaire si elle a un nombre impair de 1 bits. Par exemple, 0110 a une parité paire et 1110 a une parité impaire.

Je dois renvoyer 1 si x a même parité.

int has_even_parity(unsigned int x) {
    return 
}
10
Manuel

Essayer: 

int has_even_parity(unsigned int x){
    unsigned int count = 0, i, b = 1;

    for(i = 0; i < 32; i++){
        if( x & (b << i) ){count++;}
    }

    if( (count % 2) ){return 0;}

    return 1;
}

valter

x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return (~x) & 1;

En supposant que vous sachiez que 32 bits sont inclus.


Voyons comment cela fonctionne. Pour rester simple, utilisons un entier de 8 bits, pour lequel nous pouvons ignorer les deux premiers décalages/XOR. Étiquetons les bits a à travers h . Si nous regardons notre numéro, nous voyons:

unebcefgh )


La première opération est x ^= x >> 4 (rappelez-vous que nous sautons les deux premières opérations car nous ne traitons qu'avec un entier de 8 bits dans cet exemple). Écrivons les nouvelles valeurs de chaque bit en combinant les lettres XOR en même temps (par exemple, un B signifie que le bit a la valeur une xor b).

unebcefgh ) xor ( unebc )

Le résultat est les bits suivants:

unebcaebfcgdh )


L'opération suivante est x ^= x >> 2:

unebcaebfcgdh ) xor (0 0 unebcaebf )

Le résultat est les bits suivants:

unebacbdacebdfacegbdfh )

Remarquez comment nous commençons à accumuler tous les bits sur le côté droit.


L'opération suivante est x ^= x >> 1:

unebacbdacebdfacegbdfh ) xor (0 unebacbdacebdfaceg )

Le résultat est les bits suivants:

uneun Babca B c dabcdea B c d e Fabcdefghabcdefgh )


Nous avons accumulé tous les bits du mot original, XOR'd ensemble, dans le bit le moins significatif. Donc, ce bit est maintenant zéro si et seulement s'il y avait un nombre pair de 1 bits dans le mot d'entrée (parité paire). Le même processus fonctionne sur les entiers 32 bits (mais nécessite ces deux décalages supplémentaires que nous avons ignorés dans cette démonstration).

La dernière ligne de code supprime simplement tout le bit, à l'exception du bit le moins significatif (& 1), puis l'inverse (~x). Le résultat est alors 1 si la parité du mot d'entrée est pair, ou zéro sinon.

52
TypeIA

La réponse suivante a été soulevée sans vergogne directement de Bit Twiddling Hacks de Sean Eron Anderson, [email protected]

Calcule la parité de Word avec une multiplication

La méthode suivante calcule la parité de la valeur 32 bits dans seulement 8 opérations> en utilisant une multiplication.

unsigned int v; // 32-bit Word
v ^= v >> 1;
v ^= v >> 2;
v = (v & 0x11111111U) * 0x11111111U;
return (v >> 28) & 1;

Également pour 64 bits, 8 opérations suffisent encore.

unsigned long long v; // 64-bit Word
v ^= v >> 1;
v ^= v >> 2;
v = (v & 0x1111111111111111UL) * 0x1111111111111111UL;
return (v >> 60) & 1;

Andrew Shapira est venu avec cela et m'a envoyé le 2 septembre 2007.

5
Troyseph

Sur GCC, il existe une fonction intégrée pour cela:

Fonction intégrée: int __builtin_parity (unsigned int x)

Renvoie la parité de x, c'est-à-dire le nombre de 1 bits dans x modulo 2.

C'est à dire. cette fonction se comporte comme has_odd_parity. Inverser la valeur pour has_even_parity.

Ceci est garanti pour être l'alternative la plus rapide sur GCC. Bien sûr, son utilisation n’est pas portable en tant que telle, mais vous pouvez l’utiliser dans votre implémentation, gardée par une macro par exemple.

2
Antti Haapala

Généraliser la réponse de @ TypelA pour n'importe quelle architecture:

int has_even_parity(unsigned int x) 
{
    unsigned char shift=1;
    while (shift < (sizeof(x)*8))
    {
            x ^= (x>>shift);
            shift<<=1;
    }
    return !(x & 0x1);
}
1
Rishav Ambasta

L'idée principale est la suivante. Désactivez le bit '1' le plus à droite en utilisant x & ( x - 1 ). Disons que x = 13 (1101) et que l'opération x & ( x - 1 ) est 1101 & 1100 qui correspond à 1100, remarquez que le bit le plus à droite est converti en 0.

Maintenant x est 1100. L'opération de x & ( x - 1 ) i.e 1100 & 1011 est 1000. Notez que la x d'origine est 1101 et que, après deux opérations de x & (x - 1), la x est 1000, c'est-à-dire que deux bits définis sont supprimés après deux opérations. Si, après odd nombre d'opérations, x devient zéro, alors c'est une parité impair, sinon c'est une parité paire.

1
madhu sudhan

Voici un une ligne #definequi fait l'affaire pour un char:

#define PARITY(x) ((~(x ^= (x ^= (x ^= x >> 4) >> 2) >> 1)) & 1) /* even parity */

int main()
{
    char x=3;
    printf("parity = %d\n", PARITY(x));
}

Il est portable comme bonjour et facilement modifié pour fonctionner avec des mots plus gros (16, 32 bits). Il est important de noter également que l'utilisation d'un #define accélère le code. Chaque appel de fonction nécessite du temps pour pousser la pile et allouer de la mémoire. La taille du code n'en pâtit pas, en particulier si elle n'est implémentée que quelques fois dans votre code - l'appel de fonction peut prendre autant de code objet que les XOR.

Certes, les mêmes efficiences peuvent être obtenues en utilisant la version inline function de this, inline char parity(char x) {return PARITY(x);} (GCC) ou __inline char parity(char x) {return PARITY(x);} (MSVC). En supposant que vous gardiez la ligne définie.

0
Danny Holstein
int parity_check(unsigned x) {
    int parity = 0;
    while(x != 0) {
        parity ^= x;
        x >>= 1;
    }
    return (parity & 0x1);
}
0
Shreyas Shivalkar