Java 中的位移位

发布于 2024-12-06 08:31:54 字数 187 浏览 2 评论 0原文

可能是我太累了。
为什么以下不显示相同的值?

int x = 42405;
System.out.println(x << 8);  
System.out.println((x &0x00ff) << 8);  

在这两种情况下,较低位都应该是清楚的

May be I am too tired.
Why dont't the following display the same value?

int x = 42405;
System.out.println(x << 8);  
System.out.println((x &0x00ff) << 8);  

The lower bits should be clear in both cases

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

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

发布评论

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

评论(2

被你宠の有点坏 2024-12-13 08:31:55

编辑:好的,我将底部部分留给后人...

如果 xint,那么它非常简单: x << 8 的值与 x & 相同。 0xff 当且仅当“中间”16 位均未设置时:

  • x 的前 8 位将因左移而变得无关
  • x 的底 8 位 被掩码保留

如果有任何“中间”16 位设置,则x & 被保留。 0xffx 有一点不同,该位仍被移位保留,因此结果会不同。

我不明白为什么您希望它们总是给出相同的结果...


我将假设 x 的类型是 byte,并且它实际上是负面的。

没有为 byte 定义移位操作,因此首先会转换为 int...这取决于您是否拥有掩码。

因此,我们以 x 为 -1 的情况为例。那么(int) x 也是 -1 - 即位模式全为1。将其左移 8 位,最终得到 24 个 1 后跟 8 个 0 的位模式:

11111111111111111111111100000000 = -256

现在考虑第二行代码 - 即采用 x & 。 0xff,它只会采用 x 提升值的底部 8 位 - 即 255。将其左移 8 位,最终得到 16 个 0、8 个 1,然后8 个 0:

00000000000000001111111100000000 = 65280

EDIT: Okay, I'm leaving the bottom part for posterity...

If x is int, then it's pretty simple: x << 8 will have the same value as x & 0xff if and only if none of the "middle" 16 bits are set:

  • The top 8 bits of x will be rendered irrelevant by the left shift
  • The bottom 8 bits of x are preserved by the masking

If there are any of the "middle" 16 bits set, then x & 0xff will differ from x in a bit which is still preserved by the shift, therefore the results will be different.

I don't understand why you'd expect them to always give the same results...


I'm going to assume that the type of x is byte, and that it's actually negative.

There's no shift operation defined for byte, so first there's a transformation to int... and that's what can change depending on whether or not you've got the mask.

So let's take the case where x is -1. Then (int) x is also -1 - i.e. the bit pattern is all 1s. Shift that left by 8 bits and you end up with a bit pattern of 24 1s followed by 8 0s:

11111111111111111111111100000000 = -256

Now consider the second line of code - that's taking x & 0xff, which will only take the bottom 8 bits of the promoted value of x - i.e. 255. You shift that left by 8 bits and you end up with 16 0s, 8 1s, then 8 0s:

00000000000000001111111100000000 = 65280
醉酒的小男人 2024-12-13 08:31:55

下面,x是> 0xff ,在一种情况下,您屏蔽了高 3 个字节,这意味着您
你做 (0x123 & 0x00ff) << 8 ,这将是 0x23 << 8 这与 0x123 << 完全不同。 8

int x = 0x123;
System.out.println(x << 8);  //prints 74496
System.out.println((x &0x00ff) << 8); //prints 8960

如果 x 是一个字节,它会在移位之前“提升”为 int,如果它是负数,它会符号扩展,并且你会在整数中得到很多 1 位,这在一种情况下被 &0xff 屏蔽掉,而在另一种情况下则未被屏蔽掉,

即。

byte x = (byte)0xAA; //x is negative
System.out.println(x << 8);  //prints -22016
System.out.println((x &0x00ff) << 8); //prints 43520

Below, x is > 0xff , and in one case you mask away the upper 3 bytes, meaning you
you do (0x123 & 0x00ff) << 8 , which will be 0x23 << 8 And that is quite different from 0x123 << 8

int x = 0x123;
System.out.println(x << 8);  //prints 74496
System.out.println((x &0x00ff) << 8); //prints 8960

And if x is a byte, it will get "promoted" to int before the shift, and if it's negative, it'll sign extend, and you get a whole lot of 1 bits set in the integer, which is masked away with &0xff in one case, and not masked away in the other

i.e.

byte x = (byte)0xAA; //x is negative
System.out.println(x << 8);  //prints -22016
System.out.println((x &0x00ff) << 8); //prints 43520
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文