【问题标题】:Converting IEEE 754 from bit stream into float in JavaScript将 IEEE 754 从比特流转换为 JavaScript 中的浮点数
【发布时间】:2016-05-26 21:16:18
【问题描述】:

我使用 GO 语言函数 (math.Float32bits) 序列化了 32 位浮点数,该函数返回与 IEEE 754 二进制表示相对应的浮点数。然后将该数字序列化为 32 位整数,并作为字节数组读入 java 脚本。

例如,这里是实际数字:

float: 2.8088086
as byte array:  40 33 c3 85
as hex: 0x4033c385

有一个demo converter 显示相同的数字。

我需要从 JavaScript 中的字节数组中取回相同的浮点数,但我不知道该怎么做。

【问题讨论】:

标签: javascript floating-point ieee-754


【解决方案1】:

鉴于您描述的数据:

var buffer = new ArrayBuffer(4);
var bytes = new Uint8Array(buffer);
bytes[0] = 0x40;
bytes[1] = 0x33;
bytes[2] = 0xc3;
bytes[3] = 0x85;    

我们可以使用DataView 将值作为浮点数检索:

var view = new DataView(buffer);
// If you only had a Uint8Array, you would use bytes.buffer instead of buffer.

console.log(view.getFloat32(0, false));
2.8088085651397705

var buffer = new ArrayBuffer(4);
var bytes = new Uint8Array(buffer);
bytes[0] = 0x40;
bytes[1] = 0x33;
bytes[2] = 0xc3;
bytes[3] = 0x85;    

var view = new DataView(buffer);

console.log(view.getFloat32(0, false));

【讨论】:

  • DataView 是一个很好的解决方案。这是一个内部应用程序,我只使用 Chrome。它适用于它。
【解决方案2】:

有点不同的解决方案,如果你不能使用 DataView:

var bytes = [ 0x40, 0x33, 0xc3, 0x85 ];
var bits = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | (bytes[3]);
var sign = ((bits >>> 31) == 0) ? 1.0 : -1.0;
var e = ((bits >>> 23) & 0xff);
var m = (e == 0) ? (bits & 0x7fffff) << 1 : (bits & 0x7fffff) | 0x800000;
var f = sign * m * Math.pow(2, e - 150);

document.write(f);

【讨论】:

  • 只是为了让未来的读者想知道为什么大多数实现在m * Math.pow(2, e - 127) 中使用127:上面,m * Math.pow(2, e - 150) 等于m * Math.pow(2, -23) * Math.pow(2, e - 127),并且是添加第 24 个implicit leading bit in the mantissa 的一个很好的优化。
【解决方案3】:

我的回答类似于@Jeremys 的回答,只是有一些小改动。请现在使用const/letFloat32Array/Float64Array 而不是DataView。我是这样解决的:

// 0x40a00000 is "5" in float/IEEE-754 32bit.
// You can check this here: https://www.h-schmidt.net/FloatConverter/IEEE754.html
// MSB (Most significant byte) is at highest index
const bytes = [0x00, 0x00, 0xa0, 0x40];
// The buffer is like a raw view into memory.
const buffer = new ArrayBuffer(bytes.length);
// The Uint8Array uses the buffer as its memory.
// This way we can store data byte by byte
const byteArray = new Uint8Array(buffer);
for (let i = 0; i < bytes.length; i++) {
  byteArray[i] = bytes[i];
}

// float array uses the same buffer as memory location
const floatArray = new Float32Array(buffer);

// floatValue is a "number", because a number in javascript is a
// double (IEEE-754 @ 64bit) => it can hold f32 values
const floatValue = floatArray[0];

// prints out "5"
console.log(`${JSON.stringify(bytes)} as f32 is ${floatValue}`);

// double / f64
// const doubleArray = new Float64Array(buffer);
// const doubleValue = doubleArray[0];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-18
    • 2023-03-08
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 2014-06-18
    相关资源
    最近更新 更多