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

发布于 2024-07-26 07:35:12 字数 391 浏览 3 评论 0原文

我正在编写一个函数 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 我会得到一个负数价值。

I am writing a function short getBits(short data, int p, int n)

I have tried:

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;
}

This works for getBits( (short) 0x7000, 0, 4) but if I were to replace the 7 with an 8 I get a negative value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

亣腦蒛氧 2024-08-02 07:35:12

为了使其正常工作,需要记住有关 Java 数据类型的一些事项。

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

另外,如果您要使用 int、short 或 byte 等整数基元类型,请记住这些基元类型是符号扩展的二进制补码,这意味着如果您对像 ~0 这样的负数进行右移(计算结果为 - 1),高位(符号位)将附加 1,而不是 0。

例如:

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

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

There are a few things to remember about java data types, to make this thing work.

I'm assuming you're using int variables because of the absence of explicit casts in your expression. If you're using an int type for your variables: data start_pos, and length; you should be using 32 instead of 16, since int's are 32-bit values.

Also if you're going to use integer primitive types like int, short or byte, remember that these primitive types are two's complement that are sign-extended, meaning that if you do a right shift on negative numbers like ~0 (evaluates to -1), ones will be appended on the higher order bit (sign bit) instead of zeroes.

For instance:

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

Now going back to your problem. The general idea is to be able to do a:

data & mask

Now, generating the mask is a bit tricky on signed data types. It would make sense to generate the mask using:

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

But this won't work of course because of the sign extension.

I would suggest that instead of using right-shift >>, use rotate operator >>> that way instead of ones being appended on the higher order bit, the rotate operator will append the lower order bit.

For instance:

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

so...

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

And your final answer would look something like:

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

The outermost rotate operation moves your masked data to the lower order bits.

孤蝉 2024-08-02 07:35:12

不知道为什么你需要使用短。 这是使用 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);
}

Not sure why you need to use short. Here is a solution using 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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文