6

I have serialized 32-bit floating number using GO language function (math.Float32bits) which returns the floating point number corresponding to the IEEE 754 binary representation. This number is then serialized as 32-bit integer and is read into java script as byte array.

For example, here is actual number:

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

There is a demo converter that displays the same numbers.

I need to get that same floating number back from byte array in JavaScript and I have no idea how to do that.

Sergei G
  • 1,561
  • 3
  • 18
  • 26
  • Does this answer your question? [Read/Write bytes of float in JS](https://stackoverflow.com/questions/4414077/read-write-bytes-of-float-in-js) – user202729 Jan 30 '21 at 10:46

3 Answers3

15

Given the data you've described:

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

We can retrieve the value as a floating-point number using a 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));
Jeremy
  • 1
  • 85
  • 340
  • 366
  • DataView is a great solution. It is an internal application and I am using Chrome exclusively. It works with it. – Sergei G May 26 '16 at 21:49
7

a little bit different solution, if you cannot use 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);
Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
  • 3
    Just for future readers wondering why most implementations use `127` in `m * Math.pow(2, e - 127)`: above, `m * Math.pow(2, e - 150)` equals `m * Math.pow(2, -23) * Math.pow(2, e - 127)` and is a nice optimisation to add the 24th [implicit leading bit in the mantissa](http://steve.hollasch.net/cgindex/coding/ieeefloat.html). – Arjan Aug 01 '17 at 20:44
0

My answer is like @Jeremys answer, except for small changes. Please use now const/let and Float32Array/Float64Array instead of DataView. I solved it like this:

// 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];
phip1611
  • 5,460
  • 4
  • 30
  • 57