问题:在视频游戏中,有大量的低精度数字可以通过网络打包在一起,与发送字符串相比可显着节省带宽。字符串被分配给每个字符使用1个字节的UTF-8。如何将低精度数字(2-10位)写入数组缓冲区/ blob?
理想情况下,应该写这些数字相加的方式:
- 玩家ID的游戏 - 精准0-1023范围,10位
- 球员rotation- quaternion-几号结束为24位经过一些数学简化
- 播放器输入-0-1范围x2,2位
你如何将低精度的数字这样并将它们放入数组缓冲区/ blob?
问题:在视频游戏中,有大量的低精度数字可以通过网络打包在一起,与发送字符串相比可显着节省带宽。字符串被分配给每个字符使用1个字节的UTF-8。如何将低精度数字(2-10位)写入数组缓冲区/ blob?
理想情况下,应该写这些数字相加的方式:
你如何将低精度的数字这样并将它们放入数组缓冲区/ blob?
您可以使用Uint32Array
,然后使用位移和掩码操作将值存储在该数组中。
例如,如果你想存储4位数字,然后有10比特数(留下遗留下来的多个字段18个比特):
array[0] = (num0 & 0x0f) << 0) |
(num1 & 0x3ff) << 4);
,并提取这些字段:
num0 = (array[0] >>> 0) & 0x0f;
num1 = (array[0] >>> 4) & 0x3ff;
可以通过访问其.buffer
属性来访问数组,作为ArrayBuffer
进行序列化。
也许MathewBarker的bit-stream可能有一些帮助,在这里。
基于参宿一的回答是:
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位
*“字符串分配给每个字符使用1个字节的UTF-8”*或者两个或三个或四个字符,具体取决于字符。例如,'ç'(如在François中)是UTF-8中的两个字节,'£'(英镑符号)和'¥'(日元)也是。 '€'(欧元符号)是三个字节。 –
请注意,OP示例中的总位数是36,这使问题稍微复杂一些(如果紧凑存储是目标,那就是)。 – K3N
是的,数字必须正确对齐,尽管位收缩太多,所以需要一些方法来确保固定长度 – hydrix