代码之家  ›  专栏  ›  技术社区  ›  Arti

如何将值打包为带符号的32 int

  •  2
  • Arti  · 技术社区  · 7 年前

    我有一个数组:

    [43, 44, 45, 46, 47, 2]
    

    在…上 此代码看起来像:

     varToPack = (array[0] &0x3F) +
                  ( (array[1]<<6) &0x3F) +
                  ( (array[2]<<12) &0x3F) +
                  ( (array[3]<<18) &0x3F) +
                  ( (array[4]<<24) &0x3F) +
                  ( (array[5]<<30) &3)
    

    let varToPack = arr[0]+
    (arr[1]<<6)+
    (arr[2]<<12)+
    (arr[3]<<18)+
    (arr[4]<<24)+
    (arr[5]<<30);
    

    0 1 . 将最后一个值设置为2后,得到的是负数。因此,根据这个答案:

    Bitwise operations on 32-bit unsigned ints?

    let varToPack = arr[0]+
    (arr[1]<<6)+
    (arr[2]<<12)+
    (arr[3]<<18)+
    (arr[4]<<24)+
    ((arr[5]<<30)>>>0);
    

    这是可行的,但总的来说,它会返回值 2147483648 ,因为我没有使用 &0x3F 这不会让数字大于6位。

    let varToPack = (arr[0]&0x3F)+
                    ((arr[1]<<6)&0x3F)+
                    ((arr[2]<<12)&0x3F)+
                    ((arr[3]<<18)&0x3F)+
                    ((arr[4]<<24)&0x3F)+
                    (((arr[5]<<30)>>>0)&3);
    

    它返回0。我做错了什么?

    2 回复  |  直到 7 年前
        1
  •  1
  •   dbush    7 年前

    这不起作用的原因是:

    let varToPack = (arr[0]&0x3F)+
                    ((arr[1]<<6)&0x3F)+
                    ((arr[2]<<12)&0x3F)+
                    ((arr[3]<<18)&0x3F)+
                    ((arr[4]<<24)&0x3F)+
                    (((arr[5]<<30)>>>0)&3);
    

    然后 执行逻辑AND。由于所需的位已移出AND指定的位置,因此所有内容都被屏蔽。如果要屏蔽这些值, 然后

    let varToPack = (a[0] &0x3F) |
                  ( (a[1] & 0x3f) <<6) |
                  ( (a[2] & 0x3f) <<12) |
                  ( (a[3] & 0x3f) <<18) |
                  ( (a[4] & 0x3f) <<24) |
                  (( (a[5] & 0x3) <<30) >>> 0);
    

    至于负值,Javascript对32位有符号值执行所有按位操作(然后将其结果转换为64位浮点),因此结果为负值也就不足为奇了。

    但是,存储的值会出现在结果变量中。如果您从所讨论的值中提取位,您将返回原始值:

    let b = [];
    b[0] = varToPack & 0x3f;
    b[1] = (varToPack >>> 6) & 0x3f;
    b[2] = (varToPack >>> 12) & 0x3f;
    b[3] = (varToPack >>> 18) & 0x3f;
    b[4] = (varToPack >>> 24) & 0x3f;
    b[5] = (varToPack >>> 30) & 0x3;
    
        2
  •  1
  •   rustyx    7 年前

    limited to 32-bit signed integers

    无法将输入“打包”为32位有符号整数,因为2*2 30 超过它。最大正有符号32位整数为2 31

    如果要将其打包为64位整数,则可以 第六个元素乘以2 30

    let arr=[43, 44, 45, 46, 47, 2];
    
    let varToPack =  arr[0] + 
                    (arr[1]<<6) +
                    (arr[2]<<12) +
                    (arr[3]<<18) +
                    (arr[4]<<24) +
                    (arr[5]*(1<<30));
    
    document.getElementById("result").innerHTML = varToPack;
    Result: <span id="result">