2016-12-28 41 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

相關問題