Votre idée est fondamentalement OK. Il y a quelques choses à savoir.
Je crois que le résultat que vous recherchez dans votre cas est 0001010000110100000000000111110000000000000000000000000000000000
.
est ici une tentative qui ne fonctionne pas:
int[] registers = { 5172, 124, 0, 0 };
long result = registers[0] << 48 | registers[1] << 32 | registers[2] << 16 | registers[3];
System.out.println(Long.toBinaryString(result));
<< 48
un moyen de décalage 48 bits vers la gauche, qui devrait être assez bon, non? |
est un bit logique ou, il remplit les 1 bits de l'un ou l'autre opérande dans la même position de bit du résultat. Vous pouvez utiliser +
à la place si vous préférez.
Cette impression:
10100001101000000000001111100
Nous avons seulement les 32 premiers bits du résultat, ce n'est pas assez bon. Lorsque vous essayez de le lire, notez que Long.toBinaryString()
n'inclut pas les zéros en tête. Imaginez juste 3 zéros devant le numéro.
Mais qu'est-ce qui s'est usé? Où sont passés les 32 derniers bits? Même quand ils étaient tous des zéros. Le problème est que nous faisons le calcul en int
s, ils sont 32 bits, pas 64. EDIT: Mon explication précédente n'était pas entièrement correcte sur ce point. La vérité est la suivante: Lorsque vous faites <<
sur un int
, seuls les 5 derniers bits de l'opérande droit sont pris en compte, donc puisque 48 est 110000 en binaire, seulement 10000 est utilisé, donc le décalage est le même que << 16
. De même << 32
est le même que << 0
, aucun changement du tout. Donc registers[0]
et [1]
ont fini dans la mauvaise position de bit. La solution est facile quand vous le savez: nous devons convertir en long
avant faire le calcul.Maintenant, les derniers bits de l'opérande de droite sont utilisés, de sorte que 48 et 32 sont comprises comme 48 et 32:
long result = ((long) registers[0]) << 48 | ((long) registers[1]) << 32 | registers[2] << 16 | registers[3];
Cette fois, nous obtenons
1010000110100000000000111110000000000000000000000000000000000
Encore une fois, imaginez 3 zéro bits avant et tout est comme prévu.
Il y a une chose de plus. Disons que vous avez une valeur négative d'un registre, par exemple:
int[] registers = { 5172, -124, 0, 0 };
Le calcul qui vient travaillé nous donne maintenant
Cette fois-ci, il y a 64 bits imprimés, il est donc facile de voir il y a trop de 1 au début. Ils proviennent de la représentation int
de -124. La solution est de les masquer:
int[] registers = { 5172, -124, 0, 0 };
long result = ((long) registers[0] & 0xFFFF) << 48
| ((long) registers[1] & 0xFFFF) << 32
| (registers[2] & 0xFFFF) << 16
| (registers[3] & 0xFFFF);
System.out.println(Long.toBinaryString(result));
0xFFFF
est de 16 1 bits, et &
est le niveau du bit logique « et », donnant un bit 1 dans le résultat uniquement dans des positions où les deux opérandes ont un bit 1. Maintenant -124 masqué à 1111111110000100
obtient donc le résultat est le prévu:
1010000110100111111111000010000000000000000000000000000000000
Cela devrait le faire.
Je ne comprends pas vraiment comment vos valeurs sont stockées, mais si vous connaissez les valeurs décimales, pourquoi ne pas les écrire? Sinon, considérez built-int Long.parseLong méthodes –
Les valeurs lorsque je les lis à partir de l'appareil, j'obtiens des valeurs décimales, comme dans l'exemple ci-dessus, chaque valeur dans l'appareil est stockée dans 4 registres 16bit donc j'ai besoin de convertir ces valeurs valeur. Je ne suis pas sûr de savoir comment faire ça. – Josef
Vos octets sont 16 bits ?? Vérifiez s'il vous plaît. Il n'y a rien de tel que stocker la valeur 5172 dans une variable de type 'byte'. –