如何将低精度数字(2-10 位)写入数组缓冲区/blob?

How to write low-precision numbers (2-10 bits) to an array buffer / blob?

问题:在视频游戏中,有大量低精度数字可以通过网络打包在一起,与发送字符串相比可以显着节省带宽。字符串分配给每个字符使用 1 个字节的 UTF-8。

理想情况下,应该有一种方法可以将这些数字写在一起:

如何将这样的低精度数字放入数组缓冲区/blob 中?

您可以使用 Uint32Array,然后使用位移和掩码操作将值存储在该数组中。

例如,如果你想存储一个 4 位数字,然后是一个 10 位数字(为更多字段留下 18 位):

array[0] = (num0 & 0x0f) << 0) |
           (num1 & 0x3ff) << 4);

并提取这些字段:

num0 = (array[0] >>> 0) & 0x0f;
num1 = (array[0] >>> 4) & 0x3ff;

数组可以作为 ArrayBuffer 通过访问其 .buffer 属性.

进行序列化

也许 MathewBarker 的 bit-stream 在这里可以提供一些帮助。

基于 Alnitak 的回答:

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

注意最后一个 binPush 如何在前面添加一个额外的 0,因为最大值是 255,正好是 8 位 而 120 是 7 位

jsfiddle