Sean Anderson a publié des hacks twiddling contenant l'algorithme d'Eric Cole pour trouver le d'un entier à bits dans les opérations avec multiplication et recherche.
L'algorithme repose sur un nombre "magique" de la séquence de De Bruijn. Quelqu'un peut-il expliquer les propriétés mathématiques fondamentales de la séquence utilisée ici?
uint32_t v; // find the log base 2 of 32-bit v
int r; // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
nt.number-theory
comp-number-theory
Yury Bayda
la source
la source
Réponses:
Notez d'abord que cet algorithme ne calcule que et que le code est écrit, il ne fonctionne que pour v qui tient dans un mot de 32 bits.⌈ journal2v ⌉ v 32
La séquence de décalages et de ou-s qui apparaît en premier a pour fonction de propager le bit 1 de tête de jusqu'au bit le moins significatif. Numériquement, cela vous donne 2 ⌈ log 2 v ⌉ - 1 .v 2⌈ journal2v ⌉- 1
La partie intéressante est l'astuce de Bruijn, qui provient de cet article de Leiserson, Prokop et Randall (apparemment, les professeurs du MIT passent du temps à faire des hacks bit :)). Ce que vous devez savoir sur les séquences de Bruijn, c'est qu'elles représentent toutes les séquences possibles d'une longueur donnée d'une manière aussi compressée que possible. Précisément, une séquence de De Brujn sur l'alphabet est une chaîne binaire s de longueur 2 k telle que chaque chaîne binaire de longueur k apparaît exactement une fois comme une sous-chaîne contiguë (le bouclage est autorisé). La raison pour laquelle cela est utile est que si vous avez un nombre X{ 0 , 1 } s 2k k X dont la représentation binaire est une séquence de Bruijn (complétée par zéros), alors les k premiers bits de 2 i X identifient de manière unique i (tant que i < k ).k k 2jeX je i < k
la source
Quelques commentaires (pas vraiment une réponse). Classons les entiers 32 bits comme suit:c
Le type X: (en tant que chaîne binaire) est une séquence de De Bruijn (pour toutes les rotations, les bits [27,31] sont distincts). Un exemple:c
Type Y: bits [27,31] de sont distincts pour i = 0 , 1 , . . . , 31 . C'est ce que Leiserson et al. les usages. Exemples:2je⋅ c i = 0 , 1 , . . . , 31
Type Z: bits [27,31] de sont distincts pouri=0,1,. . . ,31. C'est ce dont nous avons besoin dans la question initiale. Exemples:( 2i + 1- 1 ) ⋅ c i = 0 , 1 , . . . , 31
Quelques observations basées sur des expériences rapides (j'espère avoir bien compris):
Il y a 65536 entiers de type X.
Il y a 4096 entiers de type X + Y. Ce sont précisément ces entiers de type X qui commencent par la séquence '0000 ...'
Il y a 256 entiers de type X + Y + Z. Ce sont précisément ces entiers de type X qui commencent par la séquence '0000011111 ...'
Tous les entiers de type Y sont également de type X.
Cependant, il existe également 768 entiers de type Z qui ne sont ni de type X ni de type Y. Ils commencent par «1000011111 ...», «0111100000 ...» ou «1111100000 ...».
la source
Cette constante particulière est une séquence de De Bruijn avec alphabet binaire mais avec une propriété supplémentaire. Je vais l'appeler la «propriété Marc Dickinson» car l'algorithme original pourrait être implémenté sans ces séquences DB spéciales. En ajoutant 2 opérations supplémentaires, nous pourrions utiliser n'importe quelle séquence DB ordinaire. Opération: v ^ = (v >> 1); // clr tous les bits sauf MSB mis après la cascade ou le décalage.
Si vous espériez une formule mathématique élégante pour les décrire ou un théorème pour les produire ou quelque chose de similaire, je pense que cela nécessiterait un aperçu approfondi de la théorie des nombres et éventuellement d'autres domaines qui dépassent mes compétences. Si je devais deviner, je parierais qu'ils pourraient être produits par des automates cellulaires. Ce n'est pas une réponse pourquoi? sur une base rigoureuse mais une tentative de comprendre intuitivement pourquoi cela fonctionne et pourquoi cela fonctionne correctement, afin que vous puissiez l'utiliser en toute confiance.
la source