2009-09-18 8 views
7

Potrzebuję wziąć pary bajtów i wyjściowe szorty, i wziąć szorty i wyjściowe pary bajtów. Oto funkcje Wymyśliłem do tego celu:Dobry sposób na konwersję między krótkim i bajtów?

static short ToShort(short byte1, short byte2) 
{ 
    short number = (short)byte2; 
    number <<= 4; 
    number += (short)byte1; 
    return number; 
} 
static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte byte2 = (byte)(number >> 4); 
    short tempByte = (short)byte2 << 4; 
    byte byte1 = (byte)(number - tempByte); 
} 

myślę, że to jest poprawna, ale nie jestem pewien. Jeśli nie jest to właściwy sposób, co to jest? czy istnieje sposób, aby to zrobić już w ramach?

+0

Trzeba przesunąć 8 bitów, a nie 4. –

+0

Ciekawym rzeczy tutaj jest to, że w 'ToShort' byte1 jest MSB (tj. ten po lewej), gdzie-jak w' FromShort' byte1 jest LSB (tj. ten po prawej). Zmieniłem je w mojej odpowiedzi ;-p –

Odpowiedz

16

Krótsza wersja (także przesunięcie 8 bitów zamiast 4):

static short ToShort(short byte1, short byte2) 
{ 
    return (byte2 << 8) + byte1; 
} 

static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte2 = (byte)(number >> 8); 
    byte1 = (byte)(number & 255); 
} 
+0

Myślę, że pójdę z tym, dzięki za pomoc! – RCIX

+4

musiałem zawinąć kod w metodzie ToShort za pomocą rzutu krótkiego, tylko pomyślałem, że dam ci znać ... – RCIX

+0

to nie kompiluje ... dlaczego tak wiele przebojów? short + short rozdziela na operatora całkowitoliczbowego i nie może domyślnie rzutować int tak krótko – Assimilater

5

Bajty to 8 bitów, a nie 4, więc Twoja zmiana jest wyłączona. Zadeklarowałeś również zmienne lokalne w drugiej funkcji, abyś nie zapisał parametrów, jakie zamierzałeś. Jest także bardziej przejrzyste/lepsze, jeśli ograniczysz się do operacji bitowych (&, | i ~) tam, gdzie to możliwe.

static short ToShort(byte byte1, byte byte2) 
{ 
    return (short) ((byte2 << 8) | (byte1 << 0)); 
} 

static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte2 = (byte) (number >> 8); 
    byte1 = (byte) (number >> 0); 
} 

Należy zauważyć, że przesunięcia w lewo i w prawo o zero są niepotrzebne, ściśle mówiąc. Po prostu umieściłem je dla symetrii. Osobiście polecam, abyś nauczył się arytmetycznego bitowego algorytmu bitowego i pomijał funkcje pomocnicze piszące w ten sposób. Nie trzeba ukrywać szczegółów za pomocą czegoś tak fundamentalnego, IMHO.

+1

To jedyne rozwiązanie, które polecam. – Goot

+1

To jedyne rozwiązanie, które jest poprawne dla podpisanego skrótu – Yiping

+0

To powinna być zaakceptowana odpowiedź ... to faktycznie kompiluje ... – Assimilater

4

Jeśli chcesz wziąć bajtów ... wziąć bajtów; a twoje zmiany są wyłączone, a | byłoby bardziej intuicyjny:

static short ToShort(byte byte1, byte byte2) 
{ // using Int32 because that is what all the operations return anyway... 
    return (short)((((int)byte1) << 8) | (int)byte2); 
} 
static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte1 = (byte)(number >> 8); // to treat as same byte 1 from above 
    byte2 = (byte)number; 
} 
+0

że robienie bajtów było błędem ... Dobre wskazówki, dzięki! – RCIX

+0

Zazwyczaj chcesz zmienić bajt bajtu2, a nie bajt1. Oto coś takiego: return (short) ((byte2 << 8) | byte1); –

+0

chociaż int jest niepotrzebne, pokazuje co się stanie i tak (i ​​myślę, że to właśnie miałeś na myśli przez komentarz), więc +1 – Assimilater

0

System.BitConverter

+1

Tak długo, jak nie masz nic przeciwko obciążeniu tablicy przez cały czas, a nie mając kontrolę nad tym, czy jest to mały endian czy big-endian ... –

+0

@Marc Gravell Jeśli chodzi o kontrolę, musisz wprowadzić logikę, aby obsłużyć BE i LE, prawda? tak samo jak odwrócenie prawej tablicy? Ale myślę, że tablica byłaby niewielka, ale ... – TJB

+1

Zanim wprowadzisz taką logikę, równie dobrze możesz użyć arytmetyki bitowej i uniknąć wszystkich problemów ... jeśli masz do czynienia z konwersjami bajtów, to odrobina nauki jest prawdopodobnie najlepszym rozwiązaniem; -p –

27

Zastosowanie BitConverter

short number = 42; 
byte[] numberBytes = BitConverter.GetBytes(number); 
short converted = BitConverter.ToInt16(numberBytes); 
+0

Hmm o tym nie myślałam, ale na razie lubię polizać Atesa. Dzięki! – RCIX

+2

Cokolwiek działa najlepiej dla Ciebie! Plusem używania takiej metody jest to, że jeśli będziesz musiał użyć tego kodu w innych projektach, po prostu będzie tam, zamiast tworzyć bibliotekę i udostępniać kod. Ponadto inni programiści mogą ponownie wykorzystać swoją wiedzę o BitConverterze, jeśli ją posiadają. Osobiście dysponowaliśmy pewnym kodem opakowania dla konwersji bajtów, które udostępniliśmy, ale stało się bardziej kłopotliwe utrzymanie niż używanie wbudowanych elementów. Ale poważnie, użyj tego, co działa najlepiej dla ciebie;) – TJB

+1

Jako programista ac/C++ w sercu uważam to za głupie, że ktokolwiek uznałby za uciążliwe robienie prostego bitshift i lub operacji ... generowanie 'byte []', a następnie jednak 'BitConverter' jest zaimplementowany do parsowania' bajta ' [] 'potem wydaje się głupie .... – Assimilater

Powiązane problemy