节点无法将原始二进制数据读入Float32Array

时间:2018-04-12 07:19:40

标签: javascript node.js typed-arrays

我有一个文件,其中包含单精度浮点数的二进制表示(如果您感兴趣,它实际上是一个FITS文件)。

这里有一些示例代码和输出来指导您:

begin = 2880;
end = 2884;
console.log('HEX');
console.log(fileBuffer.slice(begin, end));
console.log('DEC');
console.log(fileBuffer.slice(begin, end).toJSON());
console.log(new Float32Array(fileBuffer.buffer.slice(begin, end)));

输出

HEX
<Buffer 7f c0 00 00>
DEC
{ type: 'Buffer', data: [ 127, 192, 0, 0 ] }
Float32Array [ 6.905458702346266e-41 ]

所以在第一行中,我正在查看节点缓冲区,然后是下一个十进制表示。

这是单精度的IEEE NaN,二进制是: 0111 1111 1100 0000 0000 0000 0000 0000那么,为什么我当时没有获得NaN的价值?

但那还不是全部!让我们转到数据中的非NaN点:

console.log(`start and stop: ${startByte} ${stopByte}`);
testArr = new Uint8Array(dataBuffer, startByte, stopByte);
console.log(testArr.slice(760, 774));
testArr = new Float32Array(dataBuffer, startByte, stopByte);
console.log(testArr.slice(190, 192));

带输出

start and stop: 3072 4096
Uint8Array [ 127, 192, 0, 0, 199, 80, 6, 235, 199, 83, 165, 123, 199, 101 ]
Float32Array [ 6.905458702346266e-41, -1.6237752004906055e+26 ]

你可以看到前4个字节再次是NaN(我将其作为一个完整性检查,我没有被一个字节或其他东西关闭)接下来的四个字节出现在11000111010100000000011011101011-53254.918,而不是您在上面看到的-1.62e+26

是什么给出了?

注意:我通过以下方式检查了我的工作:https://www.h-schmidt.net/FloatConverter/IEEE754.htmlhttps://www.binaryhexconverter.com/decimal-to-binary-converter

1 个答案:

答案 0 :(得分:1)

如果您看一下以下内容,您可能会注意到一些有趣的事情:

a = new Float32Array([NaN]);
b = a.buffer;
u = new Uint8Array(b);

输出

Uint8Array(4) [0, 0, 192, 127]

换句话说,NaN在这里与问题中所述的期望完全相反。

这种逆转是big-endian和little-endian之间的区别。第一个顺序(在前面有大数字)称为big-endian,第二个顺序(在末尾有高数字)称为little-endian。

由于您的FITS数据以big-endian字节顺序存储,并且您运行Node on的计算机是little-endian,因此您需要使用DataView和{{1循环中的方法(如果是你的设置,则在字节流中)。此方法(及其亲属getFloat32getFloat64等)强制执行您选择的字节序。 Big-endian是默认值,所以我最终得到了类似的东西:

getInt16