如何获取 javascript 64 位浮点数的实际字节数

How to get the actual bytes of a javascript 64bit float

我一直在努力弄清楚如何在 JavaScript 中使用类型化数组,但我还没有找到答案。我不明白如何正确地 read/write 到 "view"。

var a = 23453.342;

现在假设我想将其存储在 Float64Array 类型的数组中

view[0] = ??? //how do I copy the bytes that represent variable a into here.

另外假设我想将 JavaScript 中的整数 123456 在内部存储为 64 位浮点数:

var i = 123456;

但我想把它当作一个 4 字节整数来存储。

var buff = new ArrayBuffer(4);
var view = new UInt32Array(buff);

view[0] = ???; //how do i determine and write the 4 bytes that would represent the value of i.

然后在这两种情况下,一旦我能够在那里写入数据,我如何将它读回 JavaScript 中的局部变量。

当您创建某种类型的 TypedArray 时,请这样说 Int8Array

let my = new Int8Array(1);

并为其赋值,如下所示:

my[0] = 123456;

使用基于 on the this table is performed. So, for Int8Array the method ToInt8 的转换,最后的步骤是:

...
Let int8bit be int modulo 2^8.
If int8bit ≥ 2^7, return int8bit − 2^8, otherwise return int8bit.

所以,如果我们运行这些步骤

Let int8bit be 123456 modulo 2^8 // 64
64 < 2^7 -> return int8bit, which is 64

所以 64 是您应该期待的:

console.log(my[0]); // 64

如果您对实际位顺序感兴趣,请查看 for the algorithm or this article for the details of floating point

如果您的值小于类型化数组单元而不是将值存储到数组中,例如您有 23453.342 并使用 Float64,则只需将其放入数组中

var view = new Float64Array(1);
view[0] = 23453.342;

现在,如果您想将一个数字转换成它的单个字节,例如一个 32 位数字并获得构成它的 4 个字节,您可以使用两个 TypedArray 视图。将你的值放入高位数组,从低位单元数组中读取字节。

//The argument passed to ArrayBuffer constructor 
//is number of Bytes the buffer should be
var buff = new ArrayBuffer(4);
//Since buffer was made for 4 bytes, this view can read/store 1 32bit value
var view = new Uint32Array(buff);
//buffer still has 4 bytes, so this view can read/store 4 8bit values
var view2 = new Uint8Array(buff);

view[0] = 123456;
console.log(view2);

如果您想手动获取字节,或者无法访问更高单位类型的数组,那么您可以使用位移位和按位与运算符来获取各个字节

var i = 123456;

var buff = new ArrayBuffer(4);
var view = new Uint32Array(buff);
var view2 = new Uint8Array(buff);

view2[0] = i & 0x000000FF;
view2[1] = (i & 0x0000FF00) >> 8;
view2[2] = (i & 0x00FF0000) >> 16;
view2[3] = (i & 0xFF000000) >> 24; 

console.log( view2, view[0] );

关于取回值,在使用两个类型数组的情况下,您只需读取目标单元的数组即可。在这种情况下,从 Uint32Array

读取

var buff = new ArrayBuffer(4);
var view = new Uint32Array(buff);
var view2 = new Uint8Array(buff);
view2[0] = 64, view2[1] = 226, view2[2] = 1, view2[3] = 0;
var i = view[0];
console.log(i);

同样,如果您想使用移位方式,您需要将每个字节从较小类型的数组中移出,然后将它们按位或运算在一起。

var buff = new ArrayBuffer(4);
var view = new Uint8Array(buff);
view[0] = 64, view[1] = 226, view[2] = 1, view[3] = 0;
var i = 0;
i |= view[3] << 24;
i |= view[2] << 16;
i |= view[1] << 8;
i |= view[0];
console.log(i);