2009-06-30 32 views
1

我写一个函数短getBits(短数据,INT P,INT N)写一个函数:短GetBits(短数据,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,我会得到一个负值。

回答

2

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

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

另外,如果你打算使用像int,short或者byte这样的整数基本类型,请记住这些基元类型是二进制补码,它们是符号扩展的,这意味着如果你对负数进行右移(评估为-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 

最外面的旋转操作移动您的屏蔽数据来低位。

+0

非常感谢!在澄清我的问题和使用你的答案后,我想出了这个: return(short)((data >>>(16-p-n))&((1 << n)-1)) 这是完美的! – powerj1984 2009-06-30 16:03:34

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); 
} 
相关问题