12
votes

Twidding bit pour vérifier si un numéro est en particulier une plage

J'ai trouvé un peu plus intéressant Twiddling dans "Source \ Common \ Unicode \ utf.h" Code> Fichier de la bibliothèque ICU (composants internationaux pour Unicode). Le bit TwidDling est destiné à vérifier si un numéro est dans une plage particulière.

MagicNumber = 0xffffffff - (HighBound - LowBound)


1 commentaires

3 Réponses :


12
votes

Pour que ces astuces appliquent, les chiffres doivent avoir des caractéristiques communes dans leur représentation binaire. XXX

Qu'est-ce que ce test est vraiment pour masquer les dix bits inférieurs. Ceci est généralement écrit comme xxx

après cette opération ("et non") Les dix bits inférieurs de seulhighbits sont garantis à zéro. Cela signifie que si ce nombre est égal à la plage inférieure de l'intervalle maintenant, il a été quelque part dans l'intervalle précédent.

Cet astuce fonctionne dans tous les cas où la limite inférieure et supérieure de l'intervalle commence avec le mêmes chiffres en binaire, et à un moment donné, la limite inférieure n'a que des zéros tandis que la limite supérieure n'a que des celles-ci. Dans votre exemple, c'est à la dixième position de la droite.


2 commentaires

Pouvez-vous fournir des références pour "généralement écrit comme"? Personnellement, je trouve a & ~ b au lieu de a & ~ b moins intuitif et a & b == C plus intuitif que a & ~ d == e car il y a moins d'opérations même si c'est juste ma préférence personnelle.


Sachez que A & B == C ne signifie pas ce que vous pensez probablement que cela signifie (cela signifie a & (b == c) ). A & ~ B est lexiquement identique à A & B , et je conviens que ce dernier est une meilleure transcription de celui-ci, si seulement parce que c'est comme ça que c'est comme ça que c'est comme ça que c'est habituellement.



3
votes

La formule fonctionne chaque fois que la plage que vous recherchez commence à un multiple d'une puissance de 2 (c'est-à-dire, 1 ou plusieurs bits à la fin bas de la forme binaire du numéro se termine dans 0) et la taille de la taille de la la plage est 2 ^ n-1 (c'est-à-dire, faible et élevé == basse et basse | HIGH == HIGH).


2 commentaires

L'avez-vous testé? Supposant que le numéro est 9 et la plage est 8..8 + (2 ^ 14-1) , la formule ne s'applique pas à ce cas.


Eh bien ... Le N doit être plus grand que le nombre de 0 à la fin du numéro de base (donc pour 8, N pourrait être compris entre 1 et 3). Je pensais que ce sera trop évident pour mentionner.



4
votes

Si vous n'avez pas de type 2 ^ x limites, vous pouvez utiliser le truc suivant:

si x> = 0 et x vous pouvez vérifier à la fois : xxx

Cela fonctionne en raison du fait que des nombres négatifs dans des numéros signés correspondent aux plus gros numéros de types de données non signés.

Vous pouvez prolonger ceci (quand La vérification de la plage est désactivée) à: xxx

Vous avez maintenant les deux tests (plage [A, B> ) dans un sous et un CMP plus un Single JCC, en supposant (B - A) est préalculé.

Je n'utilise que ces types d'optimisations lorsque vraiment nécessaires; Par exemple, ils ont tendance à rendre votre code moins lisible et il ne fait que raser quelques cycles d'horloge par test.

Note à C comme Lampe Lecteurs: Le longword est le type de données de 32 bits de Delphi.


1 commentaires

Merci@ritsaert, +1 de moi.