2010-02-02 12 views
40

Comment puis-je convertir un short (2 octets) en un tableau d'octets en Java, par ex.Convertir short to byte [] en Java

short x = 233; 
byte[] ret = new byte[2]; 

... 

ça devrait être quelque chose comme ça. Mais pas sûr.

((0xFF << 8) & x) >> 0; 

EDIT:

Aussi, vous pouvez utiliser:

java.nio.ByteOrder.nativeOrder(); 

A découvrir pour obtenir si l'ordre des bits natif est grand ou petit. En outre, le code suivant est extrait de java.io.Bits qui fait:

  • octet (array/offset) à booléen
  • tableau d'octets à carboniser
  • tableau d'octets à court
  • réseau
  • d'octets int
  • tableau d'octets à flotter
  • tableau
  • octets à longue
  • tableau
  • octets doubler

Et vice versa.

+0

http://stackoverflow.com/ questions/3114935/convertir-de-court-à-byte-et-viceversa-en-java? rq = 1 – LadyDi

Répondre

59
ret[0] = (byte)(x & 0xff); 
ret[1] = (byte)((x >> 8) & 0xff); 
+1

Ah merci. J'ai aussi posté une méthode. – Hugh

+32

C'est petit boutiste, cependant. L'ordre des octets du réseau est big endian: 'byte [] arr = nouvel octet [] {(octet) ((x >> 8) & 0xFF), (octet) (x & 0xFF)}; –

+2

Cela pourrait aussi fonctionner 'byte [] arr = new octet [] {(octet) (x >>> 8), (octet) (x & 0xFF)}' – Javier

7

figured it out, son:

public static byte[] toBytes(short s) { 
    return new byte[]{(byte)(s & 0x00FF),(byte)((s & 0xFF00)>>8)}; 
} 
3

Cela dépend comment vous voulez représenter:

  • big endian ou little endian? Cela va déterminer dans quel ordre vous mettez les octets.

  • Voulez-vous utiliser le complément 2 ou un autre moyen de représenter un nombre négatif? Vous devriez utiliser un schéma qui a la même portée que le short en java pour avoir un mapping 1-to-1.

Pour big endian, la transformation doit être le long des lignes de: ret [0] = x/256; ret [1] = x% 256;

33

Un nettoyeur, mais une solution beaucoup moins efficace est:

ByteBuffer buffer = ByteBuffer.allocate(2); 
buffer.putShort(value); 
return buffer.array(); 

Gardez cela à l'esprit lorsque vous avez à faire des transformations d'octets plus complexes à l'avenir. Les ByteBuffers sont très puissants.

+0

Le basculement du tampon est-il nécessaire? Si oui, à quoi cela sert-il? – abimelex

+2

@abimelex, oui c'est nécessaire. Initialement, vous écrivez 2 octets à la position 0, 1. Si vous n'avez pas buffer.flip() 'alors buffer.array()' lira 'byte []' à partir de la position 2. 'buffer.flip()' définit la position à 0 et la limite à 2 de sorte que vous vous retrouvez avec un tableau de taille 2 commençant à la bonne position. Jetez un oeil à la Javadoc: http://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html#flip() – Gili

+0

@Gili Non, le flip() n'est pas nécessaire. buffer.array() retourne simplement le backing byte [] array. Donc, si vous allez simplement obtenir la représentation en octets en utilisant le tableau, il n'y a pas besoin de flip(). Cependant, si vous allez lire la représentation en octets en utilisant le ByteBuffer directement, vous devez retourner(). –

11

Une alternative qui est plus efficace:

// Little Endian 
    ret[0] = (byte) x; 
    ret[1] = (byte) (x >> 8); 

    // Big Endian 
    ret[0] = (byte) (x >> 8); 
    ret[1] = (byte) x; 
+0

Ne devrait-ce pas être l'inverse? C'est à dire. le premier est little-endian et le second est big-endian. –

+1

Vous avez raison ... mis à jour la réponse. Merci – David

+0

N'y at-il pas un '& 0xFF' nécessaire pour l'octet le moins significatif? – bvdb

1
public short bytesToShort(byte[] bytes) { 
    return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort(); 
} 

public byte[] shortToBytes(short value) { 
    byte[] returnByteArray = new byte[2]; 
    returnByteArray[0] = (byte) (value & 0xff); 
    returnByteArray[1] = (byte) ((value >>> 8) & 0xff); 
    return returnByteArray; 
} 
1

Plusieurs méthodes ont été évoquées ici. Mais lequel est le meilleur?suit ici une preuve que les 3 approches suivantes donnent lieu à la même sortie pour toutes les valeurs d'un short

// loops through all the values of a Short 
    short i = Short.MIN_VALUE; 
    do 
    { 
    // method 1: A SIMPLE SHIFT 
    byte a1 = (byte) (i >> 8); 
    byte a2 = (byte) i; 

    // method 2: AN UNSIGNED SHIFT 
    byte b1 = (byte) (i >>> 8); 
    byte b2 = (byte) i; 

    // method 3: SHIFT AND MASK 
    byte c1 = (byte) (i >> 8 & 0xFF); 
    byte c2 = (byte) (i & 0xFF); 

    if (a1 != b1 || a1 != c1 || 
     a2 != b2 || a2 != c2) 
    { 
     // this point is never reached !! 
    } 
    } while (i++ != Short.MAX_VALUE); 

Conclusion: moins est plus?

byte b1 = (byte) (s >> 8); 
byte b2 = (byte) s; 

(Comme d'autres réponses ont mentionné, attention aux LE/BE).

0

court à l'octet

short x=17000;  
byte res[]=new byte[2];  
res[i]= (byte)(((short)(x>>7)) & ((short)0x7f) | 0x80);  
res[i+1]= (byte)((x & ((short)0x7f))); 

octet à court

short x=(short)(128*((byte)(res[i] &(byte)0x7f))+res[i+1]); 
1

à court octets méthode convertir en Kotlin fonctionne pour moi:

fun toBytes(s: Short): ByteArray { 
    return byteArrayOf((s.toInt() and 0x00FF).toByte(), ((s.toInt() and 0xFF00) shr (8)).toByte()) 
} 
+0

Cette question est identifiée pour Java, pas Kotlin. – Gili