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):
10000100
– 1 = 10000011
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:
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:
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