1

我正在编写一个函数 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( (short) 0x7000, 0, 4) 但如果我用 8 替换 7 我会得到一个负值。

4

2 回答 2

2

关于 java 数据类型,有几件事需要记住,才能使这件事发挥作用。

我假设您正在使用 int 变量,因为您的表达式中没有显式转换。如果您对变量使用 int 类型:数据 start_pos 和长度;您应该使用 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))

但这当然行不通,因为有符号扩展。

我建议不要使用右移>>,而是使用旋转运算符>>>,而不是将那些附加在高位上,旋转运算符将附加低位。

例如:

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

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

于 2009-06-30T05:15:19.533 回答
1

不知道为什么需要使用short。这是一个使用 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);
}
于 2009-11-01T16:11:39.160 回答