2016-12-28 37 views
6

问题:在视频游戏中,有大量的低精度数字可以通过网络打包在一起,与发送字符串相比可显着节省带宽。字符串被分配给每个字符使用1个字节的UTF-8。如何将低精度数字(2-10位)写入数组缓冲区/ blob?

理想情况下,应该写这些数字相加的方式:

  • 玩家ID的游戏 - 精准0-1023范围,10位
  • 球员rotation- quaternion-几号结束为24位经过一些数学简化
  • 播放器输入-0-1范围x2,2位

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

+1

*“字符串分配给每个字符使用1个字节的UTF-8”*或者两个或三个或四个字符,具体取决于字符。例如,'ç'(如在François中)是UTF-8中的两个字节,'£'(英镑符号)和'¥'(日元)也是。 '€'(欧元符号)是三个字节。 –

+0

请注意,OP示例中的总位数是36,这使问题稍微复杂一些(如果紧凑存储是目标,那就是)。 – K3N

+0

是的,数字必须正确对齐,尽管位收缩太多,所以需要一些方法来确保固定长度 – hydrix

回答

2

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

例如,如果你想存储4位数字,然后有10比特数(留下遗留下来的多个字段18个比特):

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

,并提取这些字段:

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

可以通过访问其.buffer属性来访问数组,作为ArrayBuffer进行序列化。

+0

您的意思是使用位掩码来添加值,然后移位分配的位数来滑动它?由于按位运算符仍然是32位,我假设这是正常删除前面的零的唯一方法 – hydrix

+1

您仍然应该使用固定宽度的字段,但只需使用尽可能多的位来存储数字的全部范围题。 – Alnitak

0

也许MathewBarker的bit-stream可能有一些帮助,在这里。

1

基于参宿一的回答是:

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

相关问题