10 votes

Comment diviser un entier de 64 bits en deux entiers de 32 bits ?

Je souhaite diviser un entier de 64 bits en deux entiers de 32 bits :

var bigInt = 0xffffff;

var highInt = bigInt >> 8 // get the high bits 0xfff
var lowInt = bigInt // cut of the first part (with &)?

console.log(highInt); // 0xfff
console.log(lowInt); // 0xfff

// set them together again
var reBigInt = (highInt << 8) + lowInt;

Malheureusement, ni l'obtention du highInt ni celle du lowInt ne fonctionnent... Quelqu'un pourrait-il me donner la réponse à la question de savoir comment je dois utiliser les opérateurs bitwise ?

regards

6voto

Alexander Gessler Points 26717

EDITAR JavaScript représente les nombres entiers en utilisant le format double précision de l'IEEE Il n'existe donc aucun moyen de stocker des entiers arbitraires de 64 bits sans perte de précision, si ce n'est par l'intermédiaire de bibliothèques personnalisées de grands entiers. Les opérations bitwise sur des valeurs potentiellement tronquées n'ont évidemment aucun sens.


En général, pour les langages qui supportent les entiers 64 bits :

Un motif de 64 bits est 0xffffffffffffffff . Pour extraire les 32 bits supérieurs, il faut décaler de 32 : >> 32 . Pour extraire les 32 bits inférieurs, il suffit de les remplacer par des 32 bits : & 0xffffffff .

Vous avez bien compris le principe, mais votre arithmétique sur le nombre de bits à décaler ou à masquer est erronée.

5voto

En JavaScript, tous les nombres sont représentés à l'aide de 53 bits. JavaScript utilise la représentation en virgule flottante pour stocker tous les nombres en interne, ce qui signifie que les nombres entiers sont stockés comme des nombres en virgule flottante (la mantisse a 53 bits).

Avec 53 bits, nous pouvons donc représenter au maximum 2^53 = 9007199254740992.

Mais vous ne pouvez pas utiliser le décalage vers la droite et les opérations binaires AND pour extraire les 32 bits inférieurs et les 21 bits supérieurs, même à partir de nombres de 53 bits.

En effet, lorsque nous appliquons l'opérateur binaire à un nombre quelconque, Javascript convertit d'abord ce nombre en un nombre signé de 32 bits, applique l'opération binaire et renvoie le résultat. Cela signifie que tout bit situé à une position supérieure à 32 sera écarté.

J'ai utilisé l'approche suivante pour extraire les parties supérieures (21 bits) et inférieures (32 bits) d'un nombre positif <= 2^53.

var bigNumber = Math.pow(2, 53); // 9007199254740992
var bigNumberAsBinaryStr = bigNumber.toString(2); // '100000000000000000000000000000000000000000000000000000'
// Convert the above binary str to 64 bit (actually 52 bit will work) by padding zeros in the left
var bigNumberAsBinaryStr2 = ''; 
for (var i = 0; i < 64 - bigNumberAsBinaryStr.length; i++) {
    bigNumberAsBinaryStr2 += '0'; 
}; 

bigNumberAsBinaryStr2 += bigNumberAsBinaryStr;

var lowInt = parseInt(bigNumberAsBinaryStr2.substring(0, 32), 2);
var highInt = parseInt(bigNumberAsBinaryStr2.substring(32), 2);

Pour confirmer que la logique ci-dessus est correcte, essayons de construire le bigNumber à partir de deux parties

Assert((lowInt * Math.pow(2, 32) + highInt) === bigNumber);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X