如何在JavaScript中读取.bin文件的16位半精度浮点数并转为浮点数组
JavaScript读取半精度浮点数二进制文件方案
核心逻辑
你的sph.bin存储的是16位半精度浮点数,单条数据占2字节,JavaScript原生支持通过DataView读取半精度浮点数,旧环境可以手动实现半精度转标准64位Number的逻辑。
实现代码
浏览器端实现
// 绑定文件选择事件 document.querySelector('input[type="file"]').addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file) return; // 读取文件为二进制缓冲 const buf = await file.arrayBuffer(); const dataView = new DataView(buf); const result = new Float32Array(buf.byteLength / 2); for (let i = 0; i < result.length; i++) { // 第二个参数控制是否小端序,数值异常时可切换为false测试 result[i] = dataView.getFloat16(i * 2, true); } console.log('转换完成的浮点数组:', result); })
Node.js端实现
const fs = require('fs/promises'); async function parseSphBin(filePath = './sph.bin') { const fileBuf = await fs.readFile(filePath); const dataView = new DataView(fileBuf.buffer, fileBuf.byteOffset, fileBuf.byteLength); const result = new Float32Array(fileBuf.length / 2); for (let i = 0; i < result.length; i++) { // 第二个参数控制是否小端序,数值异常时可切换为false测试 result[i] = dataView.getFloat16(i * 2, true); } return result; } // 调用示例 parseSphBin().then(res => console.log(res));
旧环境兼容方案
如果运行环境不支持原生getFloat16方法,可以用手动转换函数替代:
function uint16ToFloat16(val) { const sign = val >> 15 ? -1 : 1; const exponent = (val >> 10) & 0x1f; const mantissa = val & 0x3ff; if (exponent === 0) return sign * mantissa * Math.pow(2, -24); if (exponent === 0x1f) return mantissa ? NaN : sign * Infinity; return sign * (1 + mantissa * Math.pow(2, -10)) * Math.pow(2, exponent - 15); } // 替换读取逻辑即可 const uint16 = dataView.getUint16(i * 2, true); result[i] = uint16ToFloat16(uint16);
注意事项
- 字节序是最容易出错的点,如果转换后的数值完全不符合预期,优先切换大小端参数测试
- 数据量较大时使用
Float32Array存储结果,性能和内存占用都比普通数组更优
内容的提问来源于stack exchange,提问作者Štěpán Chvatík
相关产品推荐
相关产品推荐

