我有一个文件,其中包含单精度浮点数的二进制表示(如果您感兴趣,它实际上是一个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.html 和https://www.binaryhexconverter.com/decimal-to-binary-converter
答案 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循环中的方法(如果是你的设置,则在字节流中)。此方法(及其亲属getFloat32
,getFloat64
等)强制执行您选择的字节序。 Big-endian是默认值,所以我最终得到了类似的东西:
getInt16