Pourquoi 11010100 << 1 est-il égal à 110101000 et non 10101000?

40

Pourquoi quand j'essaye de décaler des bits pour 11010100 2 , le résultat est 110101000 2 , pas 10101000 2 .

int a = Integer.parseInt("11010100", 2) << 1;

J'essaye de faire ça:

int a = (byte)(Integer.parseInt("11010100", 2) << 1);

Mais si la valeur de sortie est supérieure à 128, tout passe en moins, ce qui est logique. Comment puis-je faire en sorte que le nombre de bits ne change pas?

Yaroshenko Yaroslav
la source
4
L'arithmétique entière est toujours effectuée sur ints ou longs.
Tom Hawtin - tackline
34
Vous utilisez des entiers de 32 bits de long. Pourquoi vous attendriez-vous à ce que le résultat soit tronqué à 8 bits?
jhamon
1
l'octet a = ... le corrigera.
Perdi Estaquel

Réponses:

61

Prenons-le une étape à la fois.

  1. Integer.parseInt("11010100", 2)- c'est la valeur int 212. Cela est d'ailleurs inutile; vous pouvez simplement écrire: 0b11010100.

  2. 0b11010100 << 1est le même que 0b110101000424.

  3. Vous Rabattre ensuite à un octet: (byte)(0b11010100 << 1). Les bits au-delà des 8 premiers sont tous supprimés, ce qui laisse 0b10101000, qui est -88. Moins, oui, car en java, les octets sont signés.

  4. Vous avez ensuite casté silencieusement ce -88 en int, comme vous l'affectez à une valeur int. Il reste -88, ce qui signifie que tous les bits supérieurs sont tous des 1.

Par conséquent, la valeur finale est -88.

Si vous voulez voir à la 168place (qui sont exactement les mêmes bits, mais affichés non signés au lieu de signés), l'astuce habituelle est d'utiliser & 0xFF, qui définit tous les bits sauf les 8 premiers à 0, garantissant ainsi un nombre positif:

byte b = (byte) (0b11010100 << 1);
System.out.println(b); // -88. It is not possible to print 168 when printing a byte.
int asUnsigned = b & 0xFF;
System.out.println(asUnsigned); // 168.

// or in one go:

System.out.println(((byte) (0b11010100 << 1)) & 0xFF); // 168
rzwitserloot
la source
19
Il stocke la valeur int a, donc si vous en avez & 0xFF, alors vous n'avez pas besoin de lancer du tout. int a = (0b11010100<< 1) & 0xFF;
Mooing Duck
9

Si vous souhaitez mettre à 0 tous les bits supérieurs aux 8 derniers bits, vous pouvez utiliser les bits ET:

int a = (Integer.parseInt("11010100", 2) << 1) & 0xff;
System.out.println (Integer.toString(a,2));

Production:

10101000
Eran
la source
6

Essayez quelque chose comme ceci:

int anInt = Integer.parseInt("11010100", 2) << 1;
int asUnsignedInt= Byte.toUnsignedInt((byte) anInt);

toUnsignedInt a été introduit dans Java SE 8.

Puce
la source