Convertir "flotter" en octets en Javascript sans Float32Array

D'accord, alors je suis une situation assez ennuyeuse où je n'ai pas accès à des tableaux dactylographiés tels que Float32Array, mais j'ai encore besoin de convertir un nombre Javascript en octets. Maintenant, un entier que je peux gérer très bien, mais je ne sais pas comment le faire pour une valeur à virgule flottante.

J'ai résolu le problème de l'inverser (bytes dans un flotteur), mais la documentation sur la conversion de flotter en octets est assez rare, car la plupart des langages vous permettent de lire le pointeur ou d'avoir des cours courants pour le gérer.

Idéalement, j'aimerais pouvoir convertir des flotteurs en représentations de 4 octets et de 8 octets, et choisir celui à utiliser. Cependant, un code qui peut simplement prendre un nombre et le cracher comme 8 octets serait toujours génial, car je peux probablement créer la version 32 bits à partir de là.

D'accord, alors j'ai réussi à le comprendre, donc je vais partager ma solution pour une simple et double précision. Maintenant, je ne peux pas garantir qu'ils sont 100% conformes aux normes, mais ils n'ont besoin de boucles et semblent fonctionner très bien:

La précision unique (donnée une valeur décimale produit un seul entier entier endian 32 bits avec la représentation binaire):

 function toFloat32(value) { var bytes = 0; switch (value) { case Number.POSITIVE_INFINITY: bytes = 0x7F800000; break; case Number.NEGATIVE_INFINITY: bytes = 0xFF800000; break; case +0.0: bytes = 0x40000000; break; case -0.0: bytes = 0xC0000000; break; default: if (Number.isNaN(value)) { bytes = 0x7FC00000; break; } if (value <= -0.0) { bytes = 0x80000000; value = -value; } var exponent = Math.floor(Math.log(value) / Math.log(2)); var significand = ((value / Math.pow(2, exponent)) * 0x00800000) | 0; exponent += 127; if (exponent >= 0xFF) { exponent = 0xFF; significand = 0; } else if (exponent < 0) exponent = 0; bytes = bytes | (exponent << 23); bytes = bytes | (significand & ~(-1 << 23)); break; } return bytes; }; 

La double précision (donnée en une valeur décimale produit deux entiers 32 bits avec la représentation binaire dans l'ordre big-endian):

 function toFloat64(value) { if ((byteOffset + 8) > this.byteLength) throw "Invalid byteOffset: Cannot write beyond view boundaries."; var hiWord = 0, loWord = 0; switch (value) { case Number.POSITIVE_INFINITY: hiWord = 0x7FF00000; break; case Number.NEGATIVE_INFINITY: hiWord = 0xFFF00000; break; case +0.0: hiWord = 0x40000000; break; case -0.0: hiWord = 0xC0000000; break; default: if (Number.isNaN(value)) { hiWord = 0x7FF80000; break; } if (value <= -0.0) { hiWord = 0x80000000; value = -value; } var exponent = Math.floor(Math.log(value) / Math.log(2)); var significand = Math.floor((value / Math.pow(2, exponent)) * Math.pow(2, 52)); loWord = significand & 0xFFFFFFFF; significand /= Math.pow(2, 32); exponent += 1023; if (exponent >= 0x7FF) { exponent = 0x7FF; significand = 0; } else if (exponent < 0) exponent = 0; hiWord = hiWord | (exponent << 20); hiWord = hiWord | (significand & ~(-1 << 20)); break; } return [hiWord, loWord]; }; 

Des excuses pour toutes les erreurs de copie / collage, aussi le code implique toute manipulation de l'énonciation, bien qu'il soit assez facile à ajouter.

Merci à tous d'avoir posté des suggestions, mais j'ai fini par figurer principalement sur mon propre, car je voulais éviter de boucler autant que possible la vitesse; Il n'est toujours pas très rapide, mais ça va faire =)

Voir BinaryParser.encodeFloat ici .

Vous pouvez utiliser une implémentation JavaScript d'IEEE 754 comme celle de http://ysangkok.github.io/IEEE-754/index.xhtml . Il utilise Emscripten et gmp.js.