Question

J'ai quelques lignes de code dans un projet, que je ne vois pas la valeur de ...

buffer[i] = (currentByte & 0x7F) | (currentByte & 0x80);

Il lit le filebuffer à partir d'un fichier, stocké sous forme d'octets, puis transfère ensuite à tampon [i] comme indiqué, mais je ne peux pas comprendre ce que l'objectif global est, des idées?

Merci

Était-ce utile?

La solution

Comme les autres réponses déjà dit, (currentByte & 0x7F) | (currentByte & 0x80) équivaut à (currentByte & 0xFF). Le JLS3 15.22.1 Voici ce que dit est promu un int:

  

Lorsque les deux opérandes d'un opérateur et,   ^, Ou | sont d'un type qui est   convertible (§5.1.8) à une primitive   type intégral, numérique binaire   la promotion est d'abord effectuée sur la   opérandes (§5.6.2). Le type de   expression de l'opérateur au niveau du bit est le   type de opérandes promu.

parce que JLS3 5.6.2 dit que lorsque currentByte est de type byte et 0x7F est un int (ce qui est le cas), alors les deux opérandes sont promus à int.

Par conséquent, buffer sera un tableau de type d'élément int ou plus large.

, en effectuant & 0xFF sur un int, nous dressons la carte efficacement la gamme byte originale -128..127 dans la gamme non signée 0..255, une opération souvent utilisée par les flux java.io par exemple.

Vous pouvez le voir en action dans l'extrait de code suivant. Notez que pour comprendre ce qui se passe ici, vous devez savoir que Java magasins types intégrés, à l'exception char, comme 2 complément de valeurs .

byte b = -123;
int r = b;
System.out.println(r + "= " + Integer.toBinaryString(r));
int r2 = b & 0xFF;
System.out.println(r2 + "= " + Integer.toBinaryString(r2));

Enfin, pour un exemple réel, consultez le Javadoc et la mise en œuvre de la méthode read de java.io.ByteArrayInputStream:

/**
 * Reads the next byte of data from this input stream. The value 
 * byte is returned as an <code>int</code> in the range 
 * <code>0</code> to <code>255</code>. If no byte is available 
 * because the end of the stream has been reached, the value 
 * <code>-1</code> is returned. 
 */
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}

Autres conseils

 (currentByte & 0x7F) | (currentByte & 0x80)

est équivalent à

 currentByte & (0x7F | 0x80)

qui est égal à

 currentByte & 0xFF

ce qui est exactement le même que

 currentByte

Edit: Je ne regardais le côté droit de la mission, et je pense encore est vrai, l'équivalence

.

Cependant, il semble que le code veut lancer l'octet signé à un type plus grand en interprétant l'octet comme non signé.

Y at-il un moyen plus facile de jeter signé octet unsigned en java?

Je pense que quelqu'un ne trop penser ici. C'est tout simplement pas droit.

Je remarque qu'une

  • L'auteur original était inquiet au sujet de la course en temps remplaçant l'octet avec un entier natif signé (probablement 32 bits) et tente explicitement de nous dire quelque chose sur le bit de signe étant « spécial »?

Il est le code laissé derrière lui. À moins que vous savez que vous êtes sur une exécution de poisson? Quel est le type de « tampon » de toute façon?

La logique au niveau du bit complexe est totalement superflue.

for (int i = 0; i < buffer.length; i++) {
    buffer[i] = filebuffer[currentPosition + i] & 0xff;
}

fait la même chose. Si le tampon est déclarée comme un tableau d'octets, vous pouvez même laisser le & 0xff, mais malheureusement, la déclaration n'apparaît pas.

La raison peut être que le développeur original a été confondu par octets étant signé en Java.

Le résultat d'une opération ET a un 1 sur les bits que lorsque les deux bits sont 1, tandis que le résultat d'une opération OU sur une hase que des bits où soit l'un des bits de bot est 1.

une évaluation exemple pour la valeur 0x65:

  01100101 0x65
& 01111111 0x7F
===============
  01100101 0x65

  01100101 0x65
& 10000000 0x80
===============
  00000000 0x00

  01100101 0x65
| 00000000 0x00
===============
  01100101 0x65

La bonne chose au sujet de ce genre d'opérations logiques. Vous pouvez essayer toutes les combinaisons possibles (tous les 256 d'entre eux) et vérifiez que vous obtenez la réponse que vous attendiez

Il s'avère, le fichier qui l'octet est en cours de lecture était dans une notation binaire signée et d'une longueur différente, donc il a été requried pour effectuer cette tâche pour lui permettre d'étendre le type int java, tout en conservant son signe correct:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top