2009-09-18 5 views
7

Je dois prendre des paires d'octets dans et court-circuiter des sorties, et prendre des courts-circuits dans et sortir des paires d'octets. Voici les fonctions que j'ai conçu à cette fin:Bon moyen de convertir entre court et octets?

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

Je pense que cela est correct, mais je ne suis pas sûr. Si ce n'est pas la bonne façon de le faire, qu'est-ce que c'est? existe-t-il un moyen de le faire déjà dans le cadre?

+0

Vous devez déplacer 8 bits, pas 4. –

+0

Une des choses intéressantes ici est que dans 'ToShort' byte1 est le MSB (c'est-à-dire celui de gauche), où -comme dans' FromShort' byte1 est le LSB (c'est-à-dire celui de droite). J'ai changé ces derniers dans ma réponse ;-p –

Répondre

16

version plus courte (décalage aussi 8 bits au lieu de 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

Je pense que je vais aller avec cela, merci pour l'aide! – RCIX

+4

a dû envelopper le code dans la méthode ToShort avec une distribution à court, juste pensé que je vous le ferais savoir ... – RCIX

+0

cela ne compile pas ... pourquoi tant upvotes? short + short se résout en un opérateur entier et ne peut implicitement cast int aussi court – Assimilater

5

Les octets sont 8 bits, et non 4, donc votre décalage est désactivé. Vous avez également déclaré des variables locales dans la deuxième fonction afin de ne pas écrire les paramètres out comme vous le souhaitez. Il est également plus clair/meilleur si vous vous limitez aux opérations au niveau du bit (&, | et ~) si possible.

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

Notez que les décalages gauche et droit par zéro sont inutiles, à proprement parler. Je viens de mettre ceux pour la symétrie. Aussi, personnellement, je vous recommande d'apprendre le froid arithmétique bit à bit et de sauter des fonctions d'aide à l'écriture comme celles-ci. Pas besoin de cacher les détails avec quelque chose de si fondamental, à mon humble avis.

+1

C'est la seule solution que je recommanderais. – Goot

+1

Ceci est la seule solution qui est correcte pour le court signé – Yiping

+0

Cela devrait être la réponse acceptée ... il compile effectivement ... – Assimilater

4

Si vous voulez prendre octets ... prendre octets; et vos changements sont éteints, et | seraient plus intuitive:

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

que la prise de bytes chose était en fait une erreur ... Bons conseils cependant, merci! – RCIX

+0

Vous voudrez généralement changer de bit octet2, pas byte1. Donc quelque chose comme: return (short) ((byte2 << 8) | byte1); –

+0

bien que les distributions int sont inutiles, il montre ce qui se passera de toute façon (et je pense que c'est ce que vous vouliez dire par le commentaire), donc +1 – Assimilater

0

System.BitConverter

+1

Tant que cela ne vous dérange pas la surcharge d'un tableau tout le temps, et non avoir le contrôle sur si c'est little-endian ou big-endian .. –

+0

@Marc Gravell En ce qui concerne le contrôle, vous devrez mettre en logique pour gérer à la fois BE et LE? même que l'inversion du tableau droit? Mais je suppose que le tableau serait un léger frais généraux si ... – TJB

+1

Au moment où vous avez mis dans une telle logique, vous pourriez aussi bien avoir utilisé l'arithmétique bitwise et évité tous les problèmes ... si vous avez affaire à des conversions d'octets, alors apprendre un peu-maths est probablement la meilleure réponse; -p –

27

Utilisez BitConverter

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

Hmm n'a pas pensé à ça mais j'aime la slution d'Ates pour l'instant. Merci! – RCIX

+2

Tout ce qui fonctionne le mieux pour vous! L'avantage d'utiliser une méthode comme celle-ci est que si vous devez utiliser ce code dans d'autres projets, il sera simplement là au lieu de devoir créer une bibliothèque et partager du code. En outre, d'autres développeurs peuvent réutiliser leurs connaissances de BitConverter s'ils en ont. Personnellement, nous avions l'habitude d'avoir du code wrapper pour les conversions d'octets que nous partagerions, mais cela devenait plus compliqué à gérer plutôt que d'utiliser simplement le contenu intégré. Mais sérieusement, utilisez ce qui fonctionne le mieux pour vous; – TJB

+1

En tant que programmeur ac/C++ au fond, je trouve idiot que n'importe qui trouverait fastidieux de faire un simple bitshift et ou opération ... générant un 'byte []' et ensuite 'BitConverter' est implémenté pour analyser ledit 'byte [] 'après semble juste stupide .... – Assimilater

Questions connexes