2010-08-21 21 views
2

Une chose que je ne l'ai jamais vraiment compris pourquoi dans de nombreuses bibliothèques, les constantes sont définies comme suit:Sélection des valeurs pour les constantes

public static final int DM_FILL_BACKGROUND = 0x2; 
public static final int DM_FILL_PREVIOUS = 0x3; 
public static final int TRANSPARENCY_MASK = 1 << 1; 
public static final int TRANSPARENCY_PIXEL = 1 << 2; 

Quoi de neuf avec le 0x et < < choses? Pourquoi les gens n'utilisent-ils pas simplement des valeurs entières ordinaires?

+0

De quelle manière '0x2' * n'est * pas une" valeur entière ordinaire "? C'est complètement normal.Comme pour '1 << 1', bien sûr, c'est une expression plutôt qu'une seule valeur, mais son résultat est toujours une" valeur entière ordinaire ". – Timwi

Répondre

6

Le décalage de bits de 1 est généralement utilisé pour les situations dans lesquelles vous souhaitez stocker des valeurs non exclusives. Par exemple, supposons que vous souhaitiez dessiner des lignes sur n'importe quel côté d'une boîte. Vous définissez:

LEFT_SIDE = 1 << 0 # binary 0001 (1) 
RIGHT_SIDE = 1 << 1 # binary 0010 (2) 
TOP_SIDE = 1 << 2 # binary 0100 (4) 
BOTTOM_SIDE = 1 << 3 # binary 1000 (8) 
           ---- 
           0111 (7) = LEFT_SIDE | RIGHT_SIDE | TOP_SIDE 

Ensuite, vous pouvez les combiner pour plusieurs côtés:

DrawBox (LEFT_SIDE | RIGHT_SIDE | TOP_SIDE) # Don't draw line on bottom. 

Le fait qu'ils utilisent des bits totalement différents signifie qu'ils sont indépendants les uns des autres. Par OR ing, vous obtenez 1 | 2 | 4 qui est égal à 7 et vous pouvez détecter chaque bit individuel avec d'autres opérations booléennes (voir here et here pour une explication de ceux-ci).

Si elles étaient définies comme 1, 2, 3 et 4, vous auriez probablement à faire un appel pour chaque côté ou vous auriez à passer quatre paramètres différents, un par côté. Sinon, vous ne pourriez pas faire la différence entre LEFT and RIGHT (1 + 2 = 3) et TOP (3), puisque les deux auraient la même valeur (avec une simple opération d'addition).

La substance 0x est juste des nombres hexadécimaux qui sont plus faciles à voir comme bitmasks binaires (chaque chiffre hexadécimal correspond exactement à quatre chiffres binaires. Vous aurez tendance à voir des modèles comme 0x01, 0x02, 0x04, 0x08, 0x10, et 0x20 ainsi de suite, car ils sont l'équivalent d'un seul bit 1 déplacement vers la position de bit le plus significatif - ces valeurs sont équivalentes à binaire 00000001, 00000010, 00000100, 00001000, 00010000, 00100000 et ainsi de suite

0123.

À côté: Une fois que vous êtes habitué à l'hexagone, vous avez rarement à vous soucier de la substance 1 << n. Vous pouvez reconnaître instantanément 0x4000 comme binaire 0100 0000 0000 0000. C'est moins évident si vous voyez la valeur 16384 dans le code, bien que certains d'entre nous reconnaissent même que :-)

+0

Bien dit. J'aime le format 1 << BitNo pour les drapeaux parce que vous savez de quel bit il s'agit en regardant la définition. J'ai un extrait générique défini comme _ Enum Public Enum _Flag As Integer avec 32 indicateurs prédéfinis. – dbasnett

2

En ce qui concerne << choses: cela dans ma façon préférée.

Lorsque j'ai besoin de définir la constante avec 1 dans la position du bit 2, et 0 dans tous les autres bits, je peux le définir comme 4, 0x4 ou 1<<2. 1<<2 est plus lisible, à mon avis, et explique exactement le but de cette constante. BTW, toutes ces façons donnent les mêmes performances, puisque les calculs sont effectués au moment de la compilation.

+0

'1 << 2' pourrait bien être plus lisible. C'est certainement plus _accurate_, étant donné que la valeur est '4', pas' 7' :-) – paxdiablo

+0

Je ne crois pas! Bien sûr, 4. Ne mélangez jamais la bière et la programmation! –