>> 5 expected 6, actual", String.valueOf((byte)(--6ren">
gpt4 book ai didi

java - 有符号和无符号右移似乎具有相同的行为

转载 作者:行者123 更新时间:2023-12-02 09:55:51 28 4
gpt4 key购买 nike

为什么无符号右移(逻辑右移)和有符号右移(算术右移)对于负数产生相同的结果?

Log.v("-59 >>> 5 expected 6, actual", String.valueOf((byte)(-59 >>> 5)));
Log.v("11000101 >>> 5 expected 00000110, actual",Integer.toBinaryString( -59 >>> 5));
Log.v("11000101 >> 5 expected 00000110, actual",Integer.toBinaryString( -59 >> 5));

Android Studio Logcat 输出

-59 >>> 5 expected 6, actual: -2

11000101 >>> 5 expected 00000110, actual: 111111111111111111111111110

11000101 >> 5 expected 00000110, actual: 11111111111111111111111111111110

最佳答案

这是正常行为。任何具有负值的整数都具有以无限 1 开头的二进制表示形式。

因此,如果您一开始就说:-3,则二进制表示形式如下所示:

...11 1101

因此,如果我们将其右移 2,我们会得到

...11 1111

现在进行未签名/签名右移。这依赖于我们的整数中没有无限位数的事实。假设我们有一个 8 位整数分配为 -3,它看起来像这样:

1111 1101

如果我们进行有符号移位,它将查看 MSB(最高有效位,最左边的位)并在移位时保留该值。所以有符号右移 3 看起来像这样:

1111 1111

相反,无符号右移不会检查 MSB,只是右移并用零填充,结果如下:

0011 1111

这正是您所看到的,但输出将前面的零截断。

<小时/>

如果您不知道为什么负整数以这种方式存储,check this answer .

<小时/>

至于为什么 (b & 0xff) >>> 5 表现不同

java中的整数是32位的,这意味着二进制表示将有32位数字。您的 -59 将类似于以下二进制表示形式:

1111 1111 1111 1111 1111 1111 1100 0101 == -59
0000 0111 1111 1111 1111 1111 1111 1110 == -59 >>> 5

如果您现在将其与 0xff 一起,您将得到以下结果:

1111 1111 1111 1111 1111 1111 1100 0101 == -59
0000 0000 0000 0000 0000 0000 1111 1111 == 0xff
0000 0000 0000 0000 0000 0000 1100 0101 == -59 & 0xff
0000 0000 0000 0000 0000 0000 0000 0110 == (-59 & 0xff) >>> 5

关于java - 有符号和无符号右移似乎具有相同的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56018978/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com