problem: in video-games there are tons of low precision numbers that can be packed together over the network to dramatically save bandwidth compared to sending strings. Strings are allocated to UTF-8 which uses 1 byte for each character.
Ideally there should be a way to write these numbers together:
How do you take low precision numbers like this and put them in a array buffer / blob?
You can use a Uint32Array
, and then use bit shift and mask operations to store values in that array.
For example, if you wanted to store a 4 bit number, and then a 10 bit number (leaving 18 bits left over for more fields):
array[0] = (num0 & 0x0f) << 0) |
(num1 & 0x3ff) << 4);
and to extract those fields:
num0 = (array[0] >>> 0) & 0x0f;
num1 = (array[0] >>> 4) & 0x3ff;
The array can be accessed as an ArrayBuffer
for serialisation by accessing its .buffer
property.
based on Alnitak's answer:
function binPush(arr, i, num, max) {
arr[i] = arr[i] << max.toString(2).length; //shift int32 $max (in base 2) bits to the left to allow for allocation
arr[i] |= num; // OR bitwise operation, which copies the 1s from $num
}
var myArr = new Uint32Array(1);
binPush(myArr, 0, 3, 3); // push 11: 00000000000000000000000000000011
binPush(myArr, 0, 10, 15); // push 1010: 00000000000000000000000000111010
binPush(myArr, 0, 120, 127); // push 1111000: 00000000000000000001110101111000
binPush(myArr, 0, 120, 255); // push 01111000: 00000000000111010111100001111000
notice how the last binPush
adds an extra 0 to the front because the max is 255, which is exactly 8 bits whereas 120 is 7 bits
jsfiddle
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