2009-04-10 21 views
15

¿Alguien puede explicar por qué no se compila lo siguiente?Cambio de bit izquierdo 255 (como un byte)

byte b = 255 << 1 

El error:

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

Estoy esperando el siguiente en binario:

1111 1110 

La conversión de tipo me ha dejado perplejos.

Respuesta

35

literales numéricos en C# son int, no byte (y el desplazamiento de bits serán evaluados por el compilador, por lo tanto, sólo los 510 restos). Por lo tanto, intenta asignar un valor a byte que no se ajusta. Puede enmascarar con 255:

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

para reducir el resultado a 8 bits nuevamente. A diferencia de Java, C# no permite que los desbordamientos pasen desapercibidos. Básicamente tendrías dos opciones sensatas cuando intentas asignar 510 a un byte: o fija el valor máximo, luego obtienes 255, o descarta los bits que no encajan, en cuyo caso obtendrás 254.

también puede utilizar unchecked, como lassevk mentioned:

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

No estoy seguro de por qué pensé que 255 se almacenaría como un 8 bit –

+0

Bueno, 255 ajustes, todo lo anterior no :) – Joey

+4

Cabe señalar, como me empujaron aquí desde otro hilo, que incluso si tiene dos bytes, cualquier operación bit a bit en ellos devolverá un int. –

1
255 << 1 

le dará más de un byte.

1

¿Has probado a enviarlo?

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

Este es un enfoque interesante - el código anterior funcionará si envuelto en un bloque unchecked como esto:

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

Puesto que es unchecked el valor se trunca al valor previsto de 254. ¡Así que es posible hacer esto con un yeso!

+0

-1 no se puede convertir, se ni siquiera compilará –

+0

Quizás te refieres (byte) (255 << 1)? – finnw

+1

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

8

Está cambiando 255 por 1 bit, y luego intenta asignarlo a un byte. 255 << 1 is 510, y 510 no cabe en un byte.

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

el resultado del operador << es un Int32, no lo que puso en él.

Debe emitir el resultado del cambio, no la entrada. Además, producirá un desbordamiento (es más grande que un byte después de todo), por lo que debe especificar que necesita un lanzamiento sin marcar.

En otras palabras, esto va a funcionar:

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

Y puesto < < tiene una precedencia mayor que & puede guardar los soportes:

byte b = 255 << 1 & 0xff; 
Cuestiones relacionadas