2009-09-18 8 views
7

Ich muss Paare von Bytes aufnehmen, Kurzschlüsse ausgeben und Kurzschlüsse in Bytepaaren eingeben und ausgeben. Hier sind die Funktionen, die ich für einen solchen Zweck entwickelt habe:Gute Möglichkeit, zwischen kurzen und Bytes zu konvertieren?

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); 
} 

Ich denke, das ist richtig, aber ich bin mir nicht sicher. Wenn das nicht der richtige Weg ist, was ist das? Gibt es einen Weg, dies bereits im Rahmen zu tun?

+0

Sie benötigen 8 Bit zu verschieben, nicht 4. –

+0

Eine interessante Dinge hier ist in 'ToShort' Byte1 ist das MSB (dh das eine auf der linken Seite), wo - wie in' FromShort' byte1 ist das LSB (dh das eine auf der rechten Seite). Ich habe diese in meiner Antwort geschaltet; -p –

Antwort

16

Kürzere Version (auch Verschiebung 8 Bit anstelle von 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

Ich denke, ich werde damit gehen, danke für die Hilfe! – RCIX

+4

musste den Code in der ToShort-Methode mit einem Cast zu kurz umhüllen, dachte nur, ich würde Sie wissen lassen ... – RCIX

+0

das kompiliert nicht ... warum so viele upvotes? short + short wird in einen Ganzzahloperator aufgelöst und kann Int nicht implizit als – Assimilater

5

Bytes sind 8 Bits, nicht 4, also ist Ihre Verschiebung ausgeschaltet. Sie deklarierten auch lokale Variablen in der zweiten Funktion, so dass Sie nicht die out Parameter schreiben würden, wie Sie beabsichtigen. Es ist auch klarer/besser, wenn Sie sich auf bitweise Operationen beschränken (&, | und ~), wo es möglich ist.

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); 
} 

Beachten Sie, dass die Links und Rechts Verschiebungen durch Null sind streng genommen unnötig. Ich gebe diese nur für Symmetrie. Außerdem würde ich persönlich empfehlen, dass Sie nur bitweise arithmetische Kälte lernen und Hilfsfunktionen wie diese überspringen. Keine Notwendigkeit, die Details mit etwas so Grundlegendes zu verstecken, IMHO.

+1

Dies ist die einzige Lösung, die ich empfehlen würde. – Goot

+1

Dies ist die einzige Lösung, die für signierte kurze korrekt ist – Yiping

+0

Dies sollte die akzeptierte Antwort sein ... es kompiliert tatsächlich ... – Assimilater

4

Wenn Sie Bytes nehmen ... nehmen Bytes; und Ihre Verschiebungen sind ausgeschaltet, und | wäre intuitiver:

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

das Byte-Ding war eigentlich ein Fehler ... Gute Tipps, danke! – RCIX

+0

Normalerweise möchten Sie Byte2, nicht Byte1, verschieben. So etwas wie: zurück (kurz) ((byte2 << 8) | byte1); –

+0

obwohl die int-Casts unnötig sind, zeigt es, was sowieso passieren wird (und ich denke, das ist, was Sie mit dem Kommentar gemeint haben), so +1 – Assimilater

0

System.BitConverter

+1

Solange Sie den Overhead eines Arrays die ganze Zeit nichts ausmacht, und nicht Kontrolle darüber, ob es Little-Endian oder Big-Endian ist .. –

+0

@Marc Gravell Soweit Kontrolle zu haben, müssen Sie in Logik setzen, um sowohl BE und LE richtig zu behandeln? Genau wie das Array umgekehrt? Aber ich denke, das Array wäre ein leichter Overhead, obwohl ... – TJB

+1

Zu der Zeit, die Sie in eine solche Logik eingeführt haben, hätten Sie genauso gut bitweise Arithmetik verwendet und alle Probleme vermieden ... Wenn Sie mit Byte-Konvertierungen zu tun haben, dann ist das Lernen ein wenig Mathe wahrscheinlich die beste Antwort; -p –

27

Verwenden BitConverter

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

Hmm dachte nicht daran, aber ich mag Ates 'Lösung für jetzt. Vielen Dank! – RCIX

+2

Was für Sie am besten funktioniert! Der Vorteil einer solchen Methode besteht darin, dass Sie diesen Code nur dann verwenden müssen, wenn Sie diesen Code in anderen Projekten verwenden müssen, anstatt eine Bibliothek erstellen und Code freigeben zu müssen. Außerdem können andere Entwickler ihr Wissen über BitConverter erneut verwenden, wenn sie einen haben. Persönlich hatten wir einen Wrapper-Code für Byte-Conversions, den wir teilen würden, aber es wurde mühsamer, ihn zu verwalten und nicht nur die eingebauten Sachen zu verwenden. Aber im Ernst, nutze, was am besten für dich funktioniert;) – TJB

+1

Als ac/C++ Programmierer im Herzen finde ich es albern, dass jeder es lästig finden würde, eine einfache Bitshift und oder Operation zu tun ... Erzeugen eines 'byte []' und dann doch 'BitConverter' implementiert, um das' Byte zu parsen [] 'danach scheint einfach albern .... – Assimilater