2009-04-10 7 views
15

Quelqu'un peut-il expliquer pourquoi ce qui suit ne compile pas?Le décalage de bits gauche 255 (en tant qu'octet)

byte b = 255 << 1 

L'erreur:

Constant value '510' cannot be converted to a 'byte'

Je me attends à ce qui suit en binaire:

1111 1110 

La conversion de type m'a déconcerté.

Répondre

35

Les littéraux numériques en C# sont int, et non byte (et le décalage de bits sera évalué par le compilateur, donc seul le 510 reste). Vous essayez donc d'attribuer une valeur à un byte qui ne correspond pas. Vous pouvez masquer avec 255:

byte b = (255 << 1) & 0xFF 

pour réduire à nouveau le résultat à 8 bits. Contrairement à Java, C# n'autorise pas les dépassements à ne pas être détectés. Fondamentalement vous auriez deux options raisonnables en essayant d'assigner 510 à un byte: Soit pincez à la valeur maximum, alors vous obtiendriez 255, ou jetez les bits qui ne tiennent pas, auquel cas vous obtiendriez 254.

vous pouvez également utiliser unchecked, comme lassevk mentioned:

byte b = unchecked((byte)(255 << 1)); 
+0

Je ne sais pas pourquoi je pensais 255 serait stocké comme un 8 bits –

+0

Eh bien, 255 correspond, tout ce qui précède ne fonctionne pas :) – Joey

+4

Il convient de noter, comme je l'ai poussé ici d'un autre thread, que même si vous avez deux octets, toute opération sur bit sur eux retournera un int. –

1
255 << 1 

vous donnera plus d'un octet.

1

avez-vous essayé de le couler?

byte b = (byte)(255 << 1) 

C'est une approche intéressante - le code ci-dessus fonctionnera si enveloppé dans un unchecked bloc comme celui-ci:

unchecked 
{ 
    byte b = (byte)(255 << 1); 
} 

Comme il est unchecked la valeur est tronquée à la valeur prévue de 254. Il est donc possible de le faire avec un casting!

+0

-1 Vous ne pouvez pas lancer, il ne compilera même pas. –

+0

Peut-être que vous voulez dire (octet) (255 << 1)? – finnw

+1

try: byte b = (255 << 1) & 0xff; – Joel

8

Vous modifiez 255 par 1 bit, puis essayez de l'affecter à un octet. 255 << 1 is 510, et 510 ne correspondra pas à un octet.

5
byte b = 0xff & (255 << 1); 
5

le résultat de l'opérateur << est un Int32, pas ce que vous y mettez.

Vous devez afficher le résultat du décalage, pas l'entrée. De plus, il produira un débordement (il est plus grand qu'un octet afterall), vous devez donc spécifier que vous avez besoin d'un cast non contrôlé.

En d'autres termes, cela fonctionnera:

Byte b = unchecked((Byte)(255 << 1)); 
0

Et depuis < < a une priorité plus élevée que & vous pouvez enregistrer les crochets:

byte b = 255 << 1 & 0xff; 
Questions connexes