It seems so simple, but I cannot find out how to convert an Array
filled with integers to an ArrayBuffer
and back again to an Array
. There are lots of examples where strings are converted to an ArrayBuffer
like for example here.
Using these examples I created this:
/**
* Convert string to array buffer.
*
* @param {Array.<int>} array
* @returns {ArrayBuffer}
*/
self.arrayToArrayBuffer = function( array ) {
var length = array.length;
var buffer = new ArrayBuffer( length * 2 );
var view = new Uint16Array(buffer);
for ( var i = 0; i < length; i++) {
view[i] = array[i];
}
return buffer;
}
Then the array also needs to converted back again. For this I use:
var array = new Uint16Array(arrayBuffer);
This solution seems to work, but is there no easier way to do this?
It should also work for an array like:
var array = [3,7426,78921]
Yes, there's a simple way without manually writing a loop (the loop still exists somewhere in background):
new Uint16Array([1,2,3]);
That's all. Of course, floating numbers will be rounded down and big numbers will overflow.
The buffer of any typed array is accessible through .buffer
property, as anyone can read on MDN:
new Uint16Array([1,2,3]).buffer;
Be warned that mentioned Uint16Array
will only hold integers (no floating point) between zero and 65535. To hold any javascript Number1 you will want to use Float64Array
- the bigest one, taking 8 bytes total.
1: Which is unrestricted double, which appears to be 64bit IEEE 754 number
Here's a map I have created that maps some of the important information related to number data types:
var NUMBER_TYPE = [ {name: "uint8", bytes:1, max: 255, min: 0, floating: false, array: Uint8Array}, {name: "int8", bytes:1, max: 127, min: -128, floating: false, array: Int8Array}, {name: "uint16", bytes:2, max: 65535, min: 0, floating: false, array: Uint16Array}, {name: "int16", bytes:2, max: 32767, min: -32768, floating: false, array: Int16Array}, {name: "uint32", bytes:4, max: 4294967295, min: 0, floating: false, array: Uint32Array}, {name: "int32", bytes:4, max: 2147483647, min: -2147483648, floating: false, array: Int32Array}, {name: "float64", bytes:8, max: Number.MAX_VALUE, min: Number.MIN_VALUE, floating: true , array: Float64Array} ];
Float 32 is missing as I was unable to calculate necessary information for it. The map, as it is, can be used to calculate the smallest typed array you can fit a Number in:
function findNumberType(num) { // detect whether number has something after the floating point var float = num!==(num|0); // Prepare the return variable var type = null; for(var i=0,l=NUMBER_TYPE.length; i<l; i++) { // Assume this type by default - unless break is hit, every type ends as `float64` type = NUMBER_TYPE[i]; // Comparison asserts that number is in bounds and disalows floats to be stored // as integers if( (!float || type.floating) && num<=type.max && num>=type.min) { // If this breaks, the smallest data type has been chosen break; } } return type; }
Used as:
var n = 1222; var buffer = new (findNumberType(n).array)([n]);
Note that this only works if NUMBER_TYPE
is properly ordered.
You can't use an ArrayBuffer directly, but you can create a typed array from a normal array by using the from method:
let typedArray = Int32Array.from([-2, -1, 0, 1, 2])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With