Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert javascript array to Float32Array to buffer and Back

I have a JS array with floats like so [0.0028808217, -0.027968751, -0.029748825] and I transform it to a Float32 Buffer with the following function:

function toFloat32Buffer(array) {
  return Buffer.from(new Float32Array(array).buffer)
}

The issue I'm facing is making the conversion from the Float32 Buffer back to a JS array, so I can use the same values as the original array.

I've tried

function toJSArray(buffer) {
 const newBuffer = Buffer.from(buffer) 
 const floatArray = new Float32Array(newBuffer)

 return Array.from(floatArray)
}

function toFloat32Buffer(arr) {
   return Buffer.from(new Float32Array(arr).buffer)
}

const array = [0.0028808217, -0.027968751, -0.029748825]
const bufferFromFloat32 = toFloat32Buffer(array);
const array2 = toJSArray(bufferFromFloat32);

console.log('array', array)
console.log('array2', array2)

array and array2 have different values. How should I transform back the buffer to get the same values as the original array? I'm running this in NodeJS

like image 723
Sergio Prada Avatar asked Oct 28 '25 01:10

Sergio Prada


2 Answers

Rewrite your toJsArray function to:

function toJSArray(buffer) {
     return new Float32Array(buffer.buffer);
}

The buffer property of buffer returns the underlying ArrayBuffer of the buffer. But as @Matt mentioned in his comment:

Javascript numbers are double-precision 64-bit. I don't think you can get back the precision that is removed converting to 32bit, short of storing it somewhere else. – Matt

For more details: buff.buffer

like image 170
FaitAccompli Avatar answered Oct 30 '25 17:10

FaitAccompli


This is alternative solution. Considering using alloc

 function bufferToArray(buffer, size) {
    let arr = [];
    for (let i = 0; i < buffer.length / size; i++)
      arr.push(buffer.readDoubleLE(i * size));
    return arr;
  }

  function arrayToBuffer(arr, size) {
    const buffer = Buffer.allocUnsafe(size * arr.length);
    arr.map((val, index) => buffer.writeDoubleLE(val, size * index));
    return buffer;
  }

  let array = [0.0028808217, -0.027968751, -0.029748825];
  const size = Float64Array.BYTES_PER_ELEMENT; // double-precision

  const buffer = arrayToBuffer(array, size);
  const array2 = bufferToArray(buffer, size);

  console.log(array); // [0.0028808217, -0.027968751, -0.029748825]
  console.log(array2); // [0.0028808217, -0.027968751, -0.029748825]
like image 40
Nicolas Eckell Avatar answered Oct 30 '25 15:10

Nicolas Eckell