编写函数:short GetBits(short data,int p,int n)

时间:2009-06-30 03:02:46

标签: java bit-masks

我正在写一个函数short getBits(short data,int p,int n)

我试过了:

public static short getBits(short data, int p, int n) {
    short bitmask = (short) ((~0 << (16 -n)) >>> p);
    short returnVal = (short) ((bitmask & data) >>> (16 - n));
    return returnVal;
}

这适用于getBits((短)0x7000,0,4)但如果我用8替换7,我会得到负值。

2 个答案:

答案 0 :(得分:2)

有一些关于java数据类型的事情需要记住,以使这件事工作。

我假设您使用的是int变量,因为表达式中没有显式的强制转换。如果你为变量使用int类型:data start_pos和length;你应该使用32而不是16,因为int是32位值。

此外,如果您要使用int,short或byte等整数原语类型,请记住这些原始类型是符号扩展的二进制补码,这意味着如果对负数进行右移,如〜0(计算结果为-1),其中1将附加在高位(符号位)而不是零。

例如:

1111 1111 1111 1111 1111 1111 1111 1000        
>>1
1111 1111 1111 1111 1111 1111 1111 1100 

现在回到你的问题。一般的想法是能够做到:

data & mask

现在,在签名数据类型上生成掩码有点棘手。使用以下方法生成掩码是有意义的:

(~0 << (32 - length) >> (32 - length - start_pos))

但是,由于符号扩展,这当然不起作用。

我建议使用旋转运算符&gt;&gt;&gt;而不是使用右移&gt;&gt;通过这种方式而不是附加在高阶位上的那些,旋转运算符将追加低阶位。

例如:

1111 1111 1111 1111 1111 1111 1111 1000        
>>>1
0111 1111 1111 1111 1111 1111 1111 1100 

所以...

mask = (~0 << 32-length >>> 32-length-start_pos)

你的最终答案看起来像是:

(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos

最外面的旋转操作会将屏蔽数据移动到低位。

答案 1 :(得分:1)

不确定为什么需要使用短片。这是一个使用long的解决方案。

public static long getBits(long data, int p, int n) {
    assert p >= 0 && p < 64;
    assert n >= 0 && n < 64;
    return (data >> p) & ((1 << n) - 1);
}