Search code examples
javascriptbitwise-operatorsarraybuffer

Translate array of bits to bytes and to float number


I'm trying to read floating numbers (float 32 bits each) out from an array (that contain only the bits) While I try to do it with ArrayBuffer and DataView I got strange values at the end. I'm expecting to have back 2 floating numbers, but i see that all the numbers are 0.

What am I missing here? I expect 2 floats (firsNum,secNum) each from 4 byes by the order

// Simple array contain 8 bytes
var myBitsArr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0];

// Array buffer with size of 8 bytes
const buffer = new ArrayBuffer(8);

// Loop all the data to the array buffer add 8 bits at each time
for (var i = 0; i < myBitsArr.length / 8; i++) {
  var byteCounter = i * 8;
  var b_0 = myBitsArr[byteCounter + 0] << 0;
  var b_1 = myBitsArr[byteCounter + 1] << 1;
  var b_2 = myBitsArr[byteCounter + 2] << 2;
  var b_3 = myBitsArr[byteCounter + 3] << 3;
  var b_4 = myBitsArr[byteCounter + 4] << 4;
  var b_5 = myBitsArr[byteCounter + 5] << 5;
  var b_6 = myBitsArr[byteCounter + 6] << 6;
  var b_7 = myBitsArr[byteCounter + 7] << 7;

  buffer[i] = (b_0 + b_1 + b_2 + b_3 + b_4 + b_5 + b_6 + b_7);
}

console.log(buffer)

// View the floating numbers
var viewNumbers = new DataView(buffer);
var firsNum = viewNumbers.getFloat32(0); // get 0 back and not float number
var secNum = viewNumbers.getFloat32(1); // get 0 back and not float number
console.log(firsNum, secNum)


Solution

  • Besides the remarks: ArrayBuffer is not an array, that is why buffer[i] does not do anything useful. You need a typedarray, most probably an Uint8Array, called uint8 below:

    // Simple array contain 8 bytes
    var myBitsArr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0];
    
    // Array buffer with size of 8 bytes
    const buffer = new ArrayBuffer(8);
    const uint8 = new Uint8Array(buffer);
    
    // Loop all the data to the array buffer add 8 bits at each time
    for (var i = 0; i < myBitsArr.length / 8; i++) {
      var byteCounter = i * 8;
      var b_0 = myBitsArr[byteCounter + 0] << 0;
      var b_1 = myBitsArr[byteCounter + 1] << 1;
      var b_2 = myBitsArr[byteCounter + 2] << 2;
      var b_3 = myBitsArr[byteCounter + 3] << 3;
      var b_4 = myBitsArr[byteCounter + 4] << 4;
      var b_5 = myBitsArr[byteCounter + 5] << 5;
      var b_6 = myBitsArr[byteCounter + 6] << 6;
      var b_7 = myBitsArr[byteCounter + 7] << 7;
    
      uint8[i] = (b_0 + b_1 + b_2 + b_3 + b_4 + b_5 + b_6 + b_7);
    }
    
    console.log(buffer)
    
    // View the floating numbers
    var viewNumbers = new DataView(buffer);
    var firsNum = viewNumbers.getFloat32(0,true); // get 0 back and not float number
    var secNum = viewNumbers.getFloat32(4,true); // get 0 back and not float number
    console.log(firsNum, secNum);

    Then it does something, displays "4.600743118071239e-41 4.027191656623092e-41" without the true-s (big endian), and "4 240" at the moment (little endian, which still may be wrong). With flipped bit order it produces weird numbers in general, but one constellation gets -35.5 for the second one.