Étant donné un entier, comment puis-je trouver la prochaine plus grande puissance de deux à l'aide de bits à vous tourner?
Si j'ai un nombre entier n
, comment puis-je trouver le numéro suivant k > n
tels que k = 2^i
, avec quelques i
élément de N
par bit à bit le déplacement ou la logique.
Exemple: Si j'ai n = 123
, comment puis-je trouver k = 128
, qui est une puissance de deux, et non pas 124
qui est divisible par deux. Cela devrait être simple, mais il m'échappe.
- Ce serait une grande question d'entrevue.
- J'espère que vous n'êtes pas un enquêteur, et je vais maintenant mettre un pauvre candidat dans une situation difficile 😉
- Pourrait être un doublon de stackoverflow.com/questions/466204/..., de toute façon les réponses de cette question pourrait être d'intérêt ici.
- si n = 128, voulez-vous de trouver k = 128, ou k = 256?
- Double Possible de Algorithme pour trouver la plus petite puissance de deux qui est plus grande ou égale à une valeur donnée
- Double Possible de Arrondi à la puissance de 2
Vous devez vous connecter pour publier un commentaire.
Pour les nombres entiers de 32 bits, c'est une simple route:
Voici un exemple plus concret. Prenons le numéro 221, qui est 11011101 en binaire:
Il y a un peu dans le neuvième position, ce qui représente 2^8, ou 256, qui est en effet la deuxième plus grande puissance de 2. Chacun des quarts de travail chevauche toutes les bits à 1 dans le nombre avec une partie de la auparavant intactes les zéros, finit par produire un certain nombre de bits à 1 égal au nombre de bits dans le numéro d'origine. L'ajout d'une valeur produit une nouvelle puissance de 2.
Un autre exemple. nous allons utiliser 131, qui est 10000011 en binaire:
Et en effet, 256 est la prochaine plus haute puissance de 2 131.
Si le nombre de bits utilisés pour représenter l'entier est lui-même une puissance de 2, vous pouvez continuer à étendre cette technique de manière efficace et à l'infini (par exemple, ajouter un
n >> 32
ligne pour les entiers 64 bits).k >= n
, pask > n
Il est en fait un assemblage de solution (depuis le 80386 jeu d'instructions).
Vous pouvez utiliser le BSR (Bit de Balayage Inverse) instructions pour numériser pour le bit le plus significatif dans votre entier.
(Extrait de: http://dlc.sun.com/pdf/802-1948/802-1948.pdf)
Et de inc le résultat avec 1.
donc:
Dans de nouveaux CPU vous pouvez utiliser, beaucoup plus rapide
lzcnt
instruction (akarep bsr
).lzcnt
fait son travail en un seul cycle.Une plus de manière mathématique, sans boucles:
2 ^ (floor(log(x) / log(2)) + 1)
0
? Également, OP demandé pour la prochaine plus grande puissance de 2,floor
trouve la prochaine baisse de puissance de 2, non?n
est une puissance de deux et que vous souhaitez obtenirn
au lieu de "la puissance de deux", vous pouvez utiliser2 ^ ( ceil(log(x) / log(2)) )
à la place. Mais ce n'était pas la question (...comment puis-je trouver le numéro suivantk > n
...)Voici une logique de réponse:
Voici John Feminella de réponse mis en œuvre une boucle de sorte qu'il peut gérer Python entiers longs:
Il renvoie également plus rapide si n est déjà une puissance de 2.
Pour Python >2.7, c'est plus simple et plus rapide pour la plupart N:
shift <<= 1
au lieu deshift *= 2
. Vous ne savez pas si c'est vraiment le plus rapide en Python, mais il devrait être.Voici un sauvage qui n'a pas de boucles, mais utilise un intermédiaire flotteur.
Cela, et beaucoup d'autres peu-se tourner les hacks, y compris la présentation par Jean Feminella, peut être trouvé ici.
Supérieur à /Supérieur ou égal à
Les extraits suivants sont pour la prochain numéro k > n tel que k = 2^je
(n=123 => k=128, n=128 => k=256) tel que spécifié par l'OP.
Si vous voulez le plus petite puissance de 2 supérieure OU égale à n ensuite, il suffit de remplacer
__builtin_clzll(n)
par__builtin_clzll(n-1)
à l'intérieur de ces extraits.C++11 à l'aide de GCC ou Clang (64 bits)
D'amélioration de l'aide
CHAR_BIT
proposé par martinecC++17 à l'aide de GCC ou Clang (à partir de 8 à 128 bits)
D'autres compilateurs
Si vous utilisez un compilateur GCC ou Clang, veuillez visiter la page Wikipedia d'inscription de l' Compter les Zéros fonctions au niveau du bit:
__builtin_clzl()
par_BitScanForward()
__builtin_clzl()
par__lzcnt()
__builtin_clzl()
par_bit_scan_forward
__builtin_clzl()
parcountLeadingZeros()
Contribution bienvenue
N'hésitez pas à proposer des améliorations dans les commentaires. Aussi de proposer des alternatives pour le compilateur que vous utilisez, ou de votre langage de programmation...
Voir aussi les réponses semblables
supposons x n'est pas négatif.
Si vous utilisez GCC, MinGW ou Clang:
Si vous utilisez Microsoft Visual C++, l'utilisation de la fonction
_BitScanForward()
pour remplacer__builtin_clz()
.constexpr uint64_t nextPowerOfTwo64 (uint64_t x) { return 1ULL << (sizeof(uint64_t) * 8 - __builtin_clzll(x)); }
Bits-tourner, dites-vous?
Chaque boucle bandes les moins significatif de 1 bit directement. N. B. il ne fonctionne que lorsqu'signé nombres sont codés en complément à deux.
while
avecdo/while
et enregistrer un test, comme vous l'avez déjà confirmé le test initial avec le précédentif
déclaration.do while
.while(t > (t & -t))
.Ce que quelque chose comme cela:
Vous avez juste besoin de trouver le bit le plus significatif et le déplacer à gauche une fois. Voici un Python de mise en œuvre. Je pense que x86 a une instruction pour obtenir de l'ESM, mais ici, je suis la mise en œuvre de tout droit de Python. Une fois que vous avez le MSB c'est facile.
Oublier cela! Il utilise la boucle !
n+min+1
?ou même