Comment Java convertit-il en octet?

int i =132; byte b =(byte)i; System.out.println(b); 

La sortie est -124

Pourquoi donc? Je sais que c’est une question très simple, mais je ne suis toujours pas en mesure de la cartographier ou de comprendre comment cela se produit?

En Java, un int est de 32 bits. Un byte est de 8 bits .

La plupart des types primitifs de Java sont signés, et les byte , les short , les int et les long sont codés en complément à deux. (Le type de caractère n’est pas signé et le concept de signe ne s’applique pas à boolean .)

Dans ce schéma numérique, le bit le plus significatif spécifie le signe du numéro. Si plus de bits sont nécessaires, le bit le plus significatif (“MSB”) est simplement copié dans le nouveau MSB.

Donc, si vous avez l’octet 255 : 11111111 et que vous voulez le représenter sous la forme d’un int (32 bits), copiez simplement le 1 à gauche 24 fois.

Maintenant, pour lire un nombre de complément à deux négatifs, vous devez commencer par le bit le moins significatif, aller à gauche jusqu’à ce que vous trouviez le premier, puis inverser chaque bit par la suite. Le nombre résultant est la version positive de ce nombre

Par exemple: 11111111 passe à 00000001 = -1 . C’est ce que Java affichera comme valeur.

Ce que vous voulez probablement faire, c’est connaître la valeur non signée de l’octet.

Vous pouvez accomplir cela avec un masque de bits qui supprime tout sauf les 8 bits les moins significatifs. (0xff)

Alors:

 byte signedByte = -1; int unsignedByte = signedByte & (0xff); System.out.println("Signed: " + signedByte + " Unsigned: " + unsignedByte); 

Imprime: "Signed: -1 Unsigned: 255"

Qu’est-ce qui se passe réellement ici?

Nous utilisons le bit AND pour masquer tous les bits de signe superflus (les 1 à la gauche des 8 bits les moins significatifs). Lorsqu’un int est converti en octet, Java coupe les 24 bits les plus à gauche.

 1111111111111111111111111010101 & 0000000000000000000000001111111 = 0000000000000000000000001010101 

Puisque le 32ème bit est maintenant le bit de signe au lieu du 8ème bit (et que nous mettons le bit de signe à 0, ce qui est positif), les 8 bits d’origine de l’octet sont lus par Java en tant que valeur positive.

Pour comprendre comment cela fonctionne, nous devons savoir que les ordinateurs fonctionnent en bits.

132 en base 10 (décimal) est 10000100 en base 2 (binary). Depuis que Java stocke dans 32 bits, ce que nous avons est

  00000000_00000000_00000000_10000100 

Lorsqu’un int est converti en un byte , Java coupe les 24 bits les plus à gauche. Ce que nous obtenons est 10000100 .

En complément à deux , le bit le plus à gauche est utilisé comme signe. Si le bit le plus à gauche est 0 , rien ne sera fait.

Si le bit le plus à gauche est 1 (comme nous l’avons ici), cela signifie que le nombre est négatif et que davantage de travail doit être effectué. Pour obtenir la magnitude, nous avons moins un puis appliquons son complément (appliquer son complément signifie inverser les bits):

  1. 10000100 – 1 = 10000011

  2. Inverser 10000011 = 01111100

01111100 lorsqu’il est interprété comme un nombre décimal, est 124.

Nous avons donc un nombre négatif avec une magnitude de 124, ce qui nous donne -124 .

l’octet en Java est signé, donc il a une plage de -2 ^ 7 à 2 ^ 7-1 – c’est-à-dire de -128 à 127. Comme 132 est au-dessus de 127, vous finissez par entourer 132-256 = -124. C’est-à-dire que essentiellement 256 (2 ^ 8) sont ajoutés ou soustraits jusqu’à ce qu’ils tombent dans la gamme.

Pour plus d’informations, vous pouvez lire sur le complément à deux .

132 est en dehors de la plage d’un octet compris entre -128 et 127 (Byte.MIN_VALUE to Byte.MAX_VALUE) Au lieu de cela, le bit supérieur de la valeur 8 bits est traité comme le signé, ce qui indique qu’il est négatif dans ce cas. Le nombre est donc 132 – 256 = -124.

souvent dans les livres, vous trouverez l’explication de la conversion de l’int en octet comme étant effectuée par la division du module. ce n’est pas ssortingctement correct comme indiqué ci-dessous ce qui se passe réellement est que les 24 bits les plus significatifs de la valeur binary du nombre int sont rejetés en laissant la confusion si le bit restant le plus à gauche est défini qui désigne le nombre comme négatif

 public class castingsample{ public static void main(Ssortingng args[]){ int i; byte y; i = 1024; for(i = 1024; i > 0; i-- ){ y = (byte)i; System.out.print(i + " mod 128 = " + i%128 + " also "); System.out.println(i + " cast to byte " + " = " + y); } } } 

voici une méthode très mécanique sans les théories distrayantes:

  1. Convertissez le nombre en représentation binary (utilisez une calculasortingce ok?)
  2. Copiez uniquement les 8 bits les plus à droite (LSB) et supprimez le rest.
  3. À partir du résultat de l’étape 2, si le bit le plus à gauche est 0, utilisez une calculasortingce pour convertir le nombre en décimal. Ceci est votre réponse.
  4. Sinon (si le bit le plus à gauche est 1) votre réponse est négative. Laissez tous les zéros les plus à droite et le premier bit non nul inchangé. Et inverser le rest, c’est-à-dire remplacer les 1 par des 0 et des 0 par 1. Ensuite, utilisez une calculasortingce pour convertir en décimal et ajoutez un signe négatif pour indiquer que la valeur est négative.

Cette méthode plus pratique est conforme aux nombreuses réponses théoriques ci-dessus. Donc, ceux qui lisent encore ces livres Java en disant utiliser modulo, c’est définitivement faux puisque les 4 étapes que j’ai décrites ci-dessus ne sont certainement pas une opération modulo.

Equation du complément à deux:

entrer la description de l'image ici


En Java, les byte (N = 8) et int (N = 32) sont représentés par le complément à 2 ci-dessus.

De l’équation, un 7 est négatif pour l’ byte mais positif pour l’ int .

 coef: a7 a6 a5 a4 a3 a2 a1 a0 Binary: 1 0 0 0 0 1 0 0 ---------------------------------------------- int: 128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = 132 byte: -128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = -124 

Un algorithme rapide qui simule la façon dont il fonctionne est le suivant:

 public int toByte(int number) { int tmp = number & 0xff return (tmp & 0x80) == 0 ? tmp : tmp - 256; } 

Comment ça marche? Regardez la réponse daixtr . Une implémentation de l’algorithme exact décrit dans sa réponse est la suivante:

 public static int toByte(int number) { int tmp = number & 0xff; if ((tmp & 0x80) == 0x80) { int bit = 1; int mask = 0; for(;;) { mask |= bit; if ((tmp & bit) == 0) { bit <<=1; continue; } int left = tmp & (~mask); int right = tmp & mask; left = ~left; left &= (~mask); tmp = left | right; tmp = -(tmp & 0xff); break; } } return tmp; } 

Conceptuellement, des soustractions répétées de 256 sont effectuées sur votre nombre, jusqu’à ce qu’il soit compris entre -128 et +127. Donc, dans votre cas, vous commencez avec 132, puis vous obtenez -124 en une seule étape.

Sur le plan informatique, cela correspond à l’extraction des 8 bits les moins significatifs de votre numéro d’origine. (Et notez que le bit le plus significatif de ces 8 devient le bit de signe.)

Notez que dans d’autres langages, ce comportement n’est pas défini (par exemple, C et C ++).

  N is input number case 1: 0<=N<=127 answer=N; case 2: 128<=N<=256 answer=N-256 case 3: N>256 temp1=N/256; temp2=N-temp*256; if temp2<=127 then answer=temp2; else if temp2>=128 then answer=temp2-256; case 4: negative number input do same procedure.just change the sign of the solution