Reputation: 198
I have been trying to work out how to use typed array's in JavaScript but something just isn't clicking yet for me. I am not understand how to read/write to the "view" properly.
var a = 23453.342;
now let's say I want to store this in a Float64Array typed array
view[0] = ??? //how do I copy the bytes that represent variable a into here.
Also let's say I want to store the integer 123456 that is in JavaScript internally as a 64Bit float:
var i = 123456;
but I would like to store it as if it was really a 4 byte integer.
var buff = new ArrayBuffer(4);
var view = new UInt32Array(buff);
view[0] = ???; //how do i determine and write the 4 bytes that would represent the value of i.
Then also in both cases once I am able to write the data there how do I read it back into local variables in JavaScript.
Upvotes: 4
Views: 1682
Reputation: 42736
If your value is smaller than the Typed Array unit than just store the value into the array, eg you have 23453.342 and using Float64, then just put it into the array
var view = new Float64Array(1);
view[0] = 23453.342;
Now if you are wanting to convert a number into its individual bytes,eg a 32bit number and get the 4 bytes that make it, you can use two TypedArray views. Put your value into the higher bit array, and read the bytes from the lower unit array.
//The argument passed to ArrayBuffer constructor
//is number of Bytes the buffer should be
var buff = new ArrayBuffer(4);
//Since buffer was made for 4 bytes, this view can read/store 1 32bit value
var view = new Uint32Array(buff);
//buffer still has 4 bytes, so this view can read/store 4 8bit values
var view2 = new Uint8Array(buff);
view[0] = 123456;
console.log(view2);
If you want to manually get the bytes, or do not have access to a higher unit typed array, than you can use the bit shifting and bitwise AND operators to get the individual bytes
var i = 123456;
var buff = new ArrayBuffer(4);
var view = new Uint32Array(buff);
var view2 = new Uint8Array(buff);
view2[0] = i & 0x000000FF;
view2[1] = (i & 0x0000FF00) >> 8;
view2[2] = (i & 0x00FF0000) >> 16;
view2[3] = (i & 0xFF000000) >> 24;
console.log( view2, view[0] );
As for getting the values back out, in the case of using the two typed arrays, you just read the array of the target unit. In this case read from the Uint32Array
var buff = new ArrayBuffer(4);
var view = new Uint32Array(buff);
var view2 = new Uint8Array(buff);
view2[0] = 64, view2[1] = 226, view2[2] = 1, view2[3] = 0;
var i = view[0];
console.log(i);
Again if you want to use the bit shifting way, you need to shift each byte from the smaller typed array and bitwise OR them together.
var buff = new ArrayBuffer(4);
var view = new Uint8Array(buff);
view[0] = 64, view[1] = 226, view[2] = 1, view[3] = 0;
var i = 0;
i |= view[3] << 24;
i |= view[2] << 16;
i |= view[1] << 8;
i |= view[0];
console.log(i);
Upvotes: 6
Reputation: 105497
When you create a TypedArray
of a certain type, say Int8Array
like this:
let my = new Int8Array(1);
and assign a value to it, like this:
my[0] = 123456;
a conversion based on the this table is performed. So, for Int8Array
the method ToInt8 is used with the last steps being:
...
Let int8bit be int modulo 2^8.
If int8bit ≥ 2^7, return int8bit − 2^8, otherwise return int8bit.
So, if we run these steps
Let int8bit be 123456 modulo 2^8 // 64
64 < 2^7 -> return int8bit, which is 64
So 64
is what you should expect:
console.log(my[0]); // 64
If you're interested in the actual bits order, check this answer for the algorithm or this article for the details of floating point.
Upvotes: 1