lecture de unsigned byte et sauvegarde en signed

a marqué ce sujet comme résolu.

Salut à tous,

J’ai un truc qui me perturbe énormément.
je fais un projet d’école et on dois lire un fichier, jusque là pas de souci, mais le problème c’est qu’on doit récupérer des bytes dans ce fichier. Le créateur du fichier l’a rempli en se disant que c’était des unsigned bytes donc des valeurs de [0;255], mais en java, les bytes sont signés donc avec une range de [-128;127] lorsque je lis 255 i.e. 11111111 java pense que c’est écrit -1. Comme ce n’est pas le sujet du TP, la prof nous a donné une méthode pour garder la signification de valeur et modifier ce byte contenant 11111111 pour qu’on puisse comparer les bytes du fichier entre eux.

Sa méthode est ((byte & 0xFF) -128) mon -1 devient un 127, la plus grande valeur dans la range signed byte tout comme le 255 d’origine était la plus grande valeur dans sa range.

Ca joue mais je comprend pas ce qui se passe, le & 0xFF est le AND logique donc ça conserve les 8 premiers bits et ça enlève -128 i.e. 10000000 normallement le bit de signe change et j’ai 127, i.e. 01111111
Mais je vois pas vraiment à quoi sert le 0xFF s’il conserve les 8 premiers bits et qu’il y en a pas d’autre ( un byte = 8 bits) il ne fait aucun travail non ? Pourquoi pas simplement faire byte -128 ?

J’ai fais quelques testes et il me semble que la même manipulation refait la même chose en sens inverse quelqu’un pourrait confirmer ?

+0 -0

Salut,

L’élément qu’il te manque pour bien comprendre, c’est la promotion automatique.

En Java comme dans d’autres langages de programmation dont le C et le C++, quand tu fais des opérations sur des entiers dont la taille est inférieure au mot machine, ils sont automatiquement promus en entiers ayant la taille d’un mot machine, quitte à être reconvertis après pour stockage. En Java, le mot machine est normé comme correspondant à int, d’une taille de 32 bits.

La promotion des entiers signés se fait habituellement en prolongeant le bit de signe. Autrement dit pour un nombre positif on ajoute des 0, et pour un nombre négatif on ajoute des 1. Quand tu écris int i = b&0xFF pour un b en tant que byte valant -1, il se passe donc ceci:

  1. Conformément au système de complément à 2, la représentation en binaire de -1 sur un byte est 11111111
  2. Le byte est promu en int. Comme c’est un nombre négatif, on ajoute des 1. On obtient donc 11111111 11111111 11111111 11111111. Remarque qu’à ce stade le int vaut toujours -1 en décimal.
  3. On fait le et binaire, on a donc: 11111111 11111111 11111111 11111111 et 00000000 00000000 00000000 11111111.
  4. Résultat, on a 00000000 00000000 00000000 11111111, ce qui vaut à 255 en décimal.

ARrivé ici, tu as une valeur entre 0 et 255. Si tu fais -128 alors tu auras une valeur entre -128 et 127. Mais aTtention avec cette méthode au fait que ton byte -1 code au final un 127, qu’un byte 0 code -128, et que le byte 127 code -1. Si tu veux que le int reflète la valeur du byte entre -128 et 127 alors tu n’as rien à faire, pas même le &0xFF. JE trouve que cette soustraction est un peu bizarre, mais il y a probablement une raison.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte