web-dev-qa-db-fra.com

Est-ce que Java lit les nombres entiers en little endian ou big endian?

Je demande parce que j'envoie un flux d'octets d'un processus C à Java. Du côté C, l'entier de 32 bits a le LSB est le premier octet et MSB est le 4ème octet.

Ma question est donc la suivante: côté Java, lorsque nous lisons l’octet tel qu’il a été envoyé à partir du processus C, qu’est-ce que endian côté Java?

Une question de suivi: si l’endian côté Java n’est pas le même que celui envoyé, comment puis-je convertir entre eux?

88
hhafez

Utilisez l'ordre des octets du réseau (big endian), identique à celui utilisé par Java. Voir les manuels pour les différents traducteurs en C.

60
Egil

Je suis tombé ici par l'intermédiaire de Google et ma réponse a été que Java est big endian.

En relisant les réponses, je voudrais souligner que les octets ont bien un ordre final, même si, heureusement, si vous n’avez traité que des microprocesseurs "classiques", il est peu probable que vous l’ayez rencontré sous les noms Intel, Motorola et Zilog. ont convenu du sens de décalage de leurs puces UART et qu'un MSB d'octet serait 2 ** 7 et LSB de 2 ** 0 dans leurs processeurs (j'ai utilisé la notation de puissance FORTRAN pour souligner l'âge de ces données :)).

J'ai rencontré ce problème avec certaines données de liaison descendante série de bits de la navette spatiale il y a plus de 20 ans, lorsque nous avons remplacé un matériel d'interface d'une valeur de 10 000 dollars par un ordinateur Mac. Un briefing technique de la NASA a été publié à ce sujet il y a longtemps. J'ai simplement utilisé une table de consultation de 256 éléments avec les bits inversés (table [0x01] = 0x80, etc.) après le décalage de chaque octet du flux de bits.

42
WB Greene

Il n'y a pas d'entiers non signés en Java. Tous les entiers sont signés et en big endian.

Du côté C, chaque octet a le LSB au début est à gauche et le MSB à la fin.

On dirait que vous utilisez LSB comme bit le moins significatif, n'est-ce pas? LSB représente généralement l'octet le moins significatif . Endianness n'est pas basé sur des bits mais sur des octets.

Pour convertir un octet non signé en un entier Java:

int i = (int) b & 0xFF;

Pour convertir de little-endian 32 bits non signé en octet [] en Java long (du haut de ma tête, non testé):

long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;
18
Jonas Elfström

Il n’ya aucun moyen que cela puisse influencer quoi que ce soit en Java, car il n’existe aucun moyen (direct non API) de mapper des octets directement dans un int en Java.

Chaque API qui fait ceci ou quelque chose de similaire définit le comportement assez précisément, vous devriez donc consulter la documentation de cette API.

11
Joachim Sauer

Je voudrais lire les octets un par un et les combiner en une valeur long . De cette façon, vous contrôlez l’endianité et le processus de communication est transparent.

3
Wouter Lievens

S'il correspond au protocole que vous utilisez, envisagez d'utiliser un DataInputStream, où le comportement est très bien défini .

3
Ilja Preuß

Java est «Big-endian» comme indiqué ci-dessus. Cela signifie que le MSB d'un int est à gauche si vous examinez la mémoire (au moins sur un processeur Intel). Le bit de signe se trouve également dans le MSB pour tous les types d'entiers Java. 
Lire un entier non signé de 4 octets à partir d'un fichier binaire stocké par un système 'Little-endian' nécessite un peu d'adaptation en Java. La fonction readInt () de DataInputStream attend le format Big-endian.
Voici un exemple qui lit une valeur non signée sur quatre octets (telle que affichée par HexEdit sous la forme 01 00 00 00) dans un entier avec la valeur 1:

 // Declare an array of 4 shorts to hold the four unsigned bytes
 short[] tempShort = new short[4];
 for (int b = 0; b < 4; b++) {
    tempShort[b] = (short)dIStream.readUnsignedByte();           
 }
 int curVal = convToInt(tempShort);

 // Pass an array of four shorts which convert from LSB first 
 public int convToInt(short[] sb)
 {
   int answer = sb[0];
   answer += sb[1] << 8;
   answer += sb[2] << 16;
   answer += sb[3] << 24;
   return answer;        
 }
0
Donald W. Smith