J'ai deux matrices d'octets de même longueur. Je dois effectuer une opération XOR entre chaque octet et après cette somme de calcul des bits.
Par exemple: P>
11110000^01010101 = 10100101 -> so 1+1+1+1 = 4
9 Réponses :
Les éléments suivants doivent faire
int BitXorAndSum(byte[] left, byte[] right) { int sum = 0; for ( var i = 0; i < left.Length; i++) { sum += SumBits((byte)(left[i] ^ right[i])); } return sum; } int SumBits(byte b) { var sum = 0; for (var i = 0; i < 8; i++) { sum += (0x1) & (b >> i); } return sum; }
Qui résume les octets. J'ai compris l'OP signifie qu'il voulait que les bits soient résumés?
Salut. Merci de répondre. Mais j'ai besoin de la somme de bits, pas une somme simple. Voir mon exemple ci-dessus.
@winaed, @ bugai13 mon mauvais. Mis à jour.
Comme je l'ai compris, vous voulez résumer les morceaux de chaque xor entre les octets gauche et droit.
for (int b = 0; b < left.Length; b++) { int num = left[b] ^ right[b]; int sum = 0; for (int i = 0; i < 8; i++) { sum += (num >> i) & 1; } // do something with sum maybe? }
Si la performance est une contrepartie, vous souhaiterez peut-être précalculer la somme des bits pour chacune des 256 combinations d'octets possibles et les stocker dans une table de recherche. Je pense que cela donnerait un gain de performance, mais vous auriez besoin de le comparer.
Je ne suis pas sûr si vous voulez dire que les octets ou les bits. Pour résumer les bits dans un octet, cela devrait fonctionner:
int nSum = 0; for (int i=0; i<=7; i++) { nSum += (byte_val>>i) & 1; }
La manière la plus rapide serait probablement une table de recherche de 256 éléments ...
11110000^01010101 = 10100101 -> lut[165] == 4
+1 Nabbits. Je voudrais juste poster cela - vos compétences parallèles implicites sont exceptionnelles :-)
Utilisez une table de recherche. Il n'y a que 256 valeurs possibles après xoring, il ne s'agit donc pas de prendre beaucoup de temps. Contrairement à la solution de l'IZB, je ne suggérerais pas de placer manuellement toutes les valeurs dans - calculer la table de recherche une fois em> au démarrage en utilisant l'une des réponses de boucle. Par exemple: P> < Pré> xxx pré> (vous pourrait-il en faire une méthode d'extension si vous vouliez vraiment ...) p> Notez l'utilisation de Je voudrais presque certainement effectivement em> exprimer comme p> < Pré> xxx pré> dans la vie réelle, mais voir qui fonctionne mieux pour vous. p> Notez également le type de la variable code> xor code> comme un octet [] code> dans le
comtebitsafterxor code> méthode - vous pouvez em> pour le faire un
iEnumerable
int code>. En fait, il n'y a pas d'opérateur xor défini pour
valeurs d'octet code>, et si vous avez formulé
xor code> a
octet code> il compilerait toujours en raison de la nature du composé Les opérateurs d'affectation, mais cela effectuerait une distribution sur chaque itération - au moins dans l'IL. Il est tout à fait possible que le JIT s'en occupait de cela, mais il n'est pas nécessaire de le demander de :) p> p>
Merci beaucoup pour votre réponse.
Ceci est plus communément appelé compte de bit. Il y a littéralement des dizaines d'algorithmes différents pour le faire. ici est un site qui répertorie quelques-unes des méthodes les plus connues. Il y a même des instructions spécifiques à la CPU pour le faire. p>
théorogique, Microsoft pourrait ajouter un Bitarray.CountSetBitsbits code> qui se déroule avec le meilleur algorithme de cette architecture de la CPU. Pour moi, pour un, accueillerait une telle addition. P>
Une fonction générale pour compter les bits pourrait ressembler à: moins les 1-bits, plus cela fonctionne plus rapidement. Il bouclait simplement sur chaque octet et bascule le 1 bit le plus bas de cet octet jusqu'à ce que l'octet devienne 0. Les moulages sont nécessaires pour que le compilateur s'arrête de se plaindre du type élargissement et rétrécissement. P> Votre problème pourrait alors être résolu en utilisant ceci: p>
Il peut être réécrit comme ulong code> et utiliser
dangereux code> le pointeur, mais
octet code> est plus facile à comprendre:
static int BitCount(byte num)
{
// 0x5 = 0101 (bit) 0x55 = 01010101
// 0x3 = 0011 (bit) 0x33 = 00110011
// 0xF = 1111 (bit) 0x0F = 00001111
uint count = num;
count = ((count >> 1) & 0x55) + (count & 0x55);
count = ((count >> 2) & 0x33) + (count & 0x33);
count = ((count >> 4) & 0xF0) + (count & 0x0F);
return (int)count;
}
A une faute de frappe dans le troisième calcul, le masque 0xf0 est incorrect lorsqu'il est fait après le décalage, doit utiliser un masque 0x0f.
Une table de recherche devrait être le plus rapide, mais si vous voulez le faire sans une table de recherche, cela fonctionnera pour des octets en seulement 10 opérations.
public static int BitCount(byte value) { int v = value - ((value >> 1) & 0x55); v = (v & 0x33) + ((v >> 2) & 0x33); return ((v + (v >> 4) & 0x0F)); }