nodejs écrire 64 bits entier non signé de la mémoire tampon
Je veux stocker un 64 bits (8 octets) entier à un nodejs tampon objet en big endian format.
Le problème à propos de cette tâche est de nodejs tampon prend uniquement en charge l'écriture des entiers 32 bits maximum (avec buf.write32UInt32BE(valeur de décalage)). Alors j'ai pensé, pourquoi ne pouvons-nous pas juste diviser le 64 bits entier?
var buf = new Buffer(8);
buf.fill(0) //clear all bytes of the buffer
console.log(buf); //outputs <Buffer 00 00 00 00 00 00 00 00>
var int = 0xffff; //as dezimal: 65535
buf.write32UInt32BE(0xff, 4); //right the first part of the int
console.log(buf); //outputs <Buffer 00 00 00 00 00 00 00 ff>
buf.write32UInt32BE(0xff, 0); //right the second part of the int
console.log(buf); //outputs <Buffer 00 00 00 ff 00 00 00 ff>
var bufInt = buf.read32UInt32BE(0) * buf.read32UInt32BE(4);
console.log(bufInt); //outputs 65025
Comme vous le voyez c'près des œuvres. Le problème est juste de fractionnement le 64 bits entier et de trouver les manquants 510 à lire. Quelqu'un voudrait-il l'esprit montrant les solutions à ces deux problèmes?
Depuis la dernière Node.js v12.0.0, vous pouvez maintenant utiliser
buf.writeBigInt64BE
OriginalL'auteur bodokaiser | 2013-02-06
Vous devez vous connecter pour publier un commentaire.
Je pense que ce que vous cherchez est:
Maj le premier nombre par 8 bits, et ajouter (au lieu de multiplier), qui renvoie
65535
MODIFIER
Une autre façon d'écrire serait:
voir mon edit. rappelez-vous que le changement est bizarre en javascript, il ne fonctionne qu'en 32 bits. Je ne pense pas que ce serait de travailler avec un certain nombre qui est la valeur ne peut pas être représentée par 32-bits.
Cela ne fonctionnera pas pour 64-bits. Vos changements sont aussi. Vous auriez besoin de passer par 32, pas 8, JS ne peut pas faire.
Pour clarifier, qui va travailler pour la valeur de 16 bits, il a mis dans sa question, mais pas pour le cas général. Vous êtes également perdre de l'espace à l'aide d'un Tampon avec 8 octets pour stocker 2 octets.
les opérations bit à bit sur les numéros de convertir les nombres de 32 bits.
OriginalL'auteur Chad
Je suis confus parce que votre exemple de valeur de
0xFFFF
est de 16 bits uniquement, pas 64 bits.Gardez à l'esprit que la JS
number
type est spécifié comme un IEEE754 valeur à virgule flottante, de sorte qu'il n'est pas garanti d'être en mesure de tenir 64 bits non signé valeur. Si vous voulez un vrai 64 bits de l'entier soutien, vous devez utiliser un module de lui fournir, comme bignum. Le fichier lisez-moi qui a des exemples de la lecture et de l'écriture des valeurs de tampons.Des valeurs à virgule flottante ne peut que représenter des valeurs jusqu'à
2^53 - 1
sans perdre de précision. Vous pouvez voir que dans cet exemple, en utilisant la norme JS numéros:Le résultat de ceci est
18446744073709552000
lorsque la valeur correcte est18446744073709551615
.Il en résulte une
BigNum
objet avec la valeur18446744073709551615
.Aussi, de donner des précisions sur votre exemple de code, la valeur que vous utilisez est que de 16 bits, et que vous essayez de travailler avec elle à l'aide de fonctions de 32 bits. Il vous suffit de faire ceci:
OriginalL'auteur loganfsmyth
De la lecture et des écritures UINT les nombres jusqu'à
Number.MAX_SAFE_INTEGER
.convertir
OriginalL'auteur dash1e
OriginalL'auteur meil
Des opérations bit à bit en JavaScript/EcmaScript force du nombre (ou toute valeur vraiment) en un entier de 32 bits.
Vous vraiment besoin d'utiliser bignum pour les plus grandes valeurs si vous avez besoin d'une certaine précision, ou de traiter avec les tampons avec plus de 32-bits.
L'exemple ci-dessus utilise
Number.MAX_SAFE_INTEGER
qui estMath.pow(2,53)-1
. Si vous avez besoin d'utiliser un plus grand nombre, ils doivent être accessibles en tant que bignum chaînes... si vous pouvez rester à l'intérieur de la plage des Entiers en JS, vous pouvez les garder et de les convertir comme ci-dessus.OriginalL'auteur Tracker1
De lecture /Écriture 64bit valeurs:
J'utilise ce code sans des modules spéciaux.
Mise à JOUR
Ne fonctionne que pour les numéros de
<= Number.MAX_SAFE_INTEGER
const low = int64 & MAX_UINT32
un peu plus court ^_^Étant donné le nombre de ci-dessous: 18446744073709552000.
~~(18446744073709552000 / 0xFFFFFFFF)
est de 1,(18446744073709552000 % 0xFFFFFFFF) - 1
est de 0. Ce code est cassé.Oui, vous avez raison( C'est petit "hack" que worsk avec quelques chiffres. Je vais corriger mon code rapidement. Thx) Utilisation
bignum
.Je pense que vous devriez diviser et modulo par 0x0100000000 à la place. Considérons le cas où int64 = 0xFFFFFFFF (=4294967295): la haute = 0, bas devrait = 4294967295, tampon doit = <00 00 00 00 ff ff ff ff> Mais dans votre cas, haut = 1, bas = -1, tampon = <00 00 00 01 00 00 00 00> C'est le bon code:
const high = Math.trunc(int64 / 0x0100000000);
const low = int64 % 0x0100000000;
Ce sera aussi mal à chaque fois le plus bas int32 est FFFFFFFF. Si vous utilisez ce pour convertir une date alors peut frapper une erreur à chaque 49,7 jours.Ce code ne fonctionne pas
OriginalL'auteur ReklatsMasters