2009-04-10 12 views
15

Czy ktoś może wyjaśnić, dlaczego następujące nie kompiluje?Przeniesienie lewej bity 255 (jako bajt)

byte b = 255 << 1 

Błąd:

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

Czekam następujące binarnie:

1111 1110 

Konwersja typu jest zakłopotany mnie.

Odpowiedz

35

Literały numeryczne w języku C# to int, a nie byte (a przesunięcie bitowe zostanie ocenione przez kompilator, w związku z tym pozostanie tylko 510). Dlatego próbujesz przypisać wartość do byte, która nie pasuje. Można maskować za pomocą 255:

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

, aby ponownie zmniejszyć wynik do 8 bitów. W przeciwieństwie do Java, C# nie pozwala, aby przepełnienia przechodziły niewykryte. Zasadniczo masz dwie rozsądne opcje, gdy próbujesz przypisać 510 do bajtu: albo zacisk na maksymalnej wartości, potem uzyskasz 255, albo wyrzuć bity, które nie pasują, w takim przypadku otrzymasz 254.

można również użyć unchecked, jak lassevk mentioned:

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

Nie wiem, dlaczego myślałem, że 255 będzie przechowywane jako 8-bitowe –

+0

Cóż, 255 pasuje, wszystko powyżej nie :) – Joey

+4

Należy zauważyć, ponieważ zostałem popchnięty tutaj z innego wątku, że nawet jeśli masz dwa bajty, każda bitowa operacja na nich zwróci int. –

1
255 << 1 

da Ci więcej niż jeden bajt.

1

Czy próbowałeś rzucić to?

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

Jest to ciekawe podejście - powyższy kod będzie działać, jeśli owinięte w unchecked bloku jak ten:

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

Ponieważ jest unchecked wartość jest obcinana do zamierzonej wartości 254. Tak więc można to zrobić z obsadą!

+0

-1 Nie można rzucać, to nawet się nie skompiluje. –

+0

Może masz na myśli (bajt) (255 << 1)? – finnw

+1

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

8

Przesuwasz 255 na 1 bit, a następnie próbujesz przypisać go do bajtu. 255 << 1 is 510, a 510 nie zmieści się do bajtu.

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

wynik operatora << jest Int32, nie to, co się w nim.

Musisz rzucić wynik zmiany, a nie dane wejściowe. Dodatkowo wygeneruje przepełnienie (jest większe niż bajt), więc musisz określić, że potrzebujesz niezaznaczonej obsady.

Innymi słowy, będzie to działa:

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

a od < < ma wyższy priorytet niż & można zapisać wsporniki:

byte b = 255 << 1 & 0xff;