为什么 (52 & (1 << 37)) return 0?
Why doesn't (52 & (1 << 37)) return 0?
我正在尝试制作一个算法,给定一个整数,吐出其二进制形式的字符串表示形式。
现在,我基本上是在比较掩码以查看在何处附加 1/0 位。这工作正常,直到出现稍大的数字,例如:(52 & (1 << 37))
如果我正确理解位移运算符(显然我没有理解)应该 return 0,因为 (1 << 37)
= 1
和 37 * 0
的。上次我查了一下,二进制格式的小数点第38位52
没有1,为什么这个return32?
整个表达式使用 32 位数执行,因为所有操作数都是 int
值。
因此 1 << 37
不是“一”后跟 37 个“零”位。
事实上,JLS 15.9 表示移位计数被 0x1f
屏蔽(对于 32 位移位运算符)。因此 1 << 37
实际上与 1 << 5
意思相同;即“一”后跟 5 个“零”位。
如果要在移位表达式中使用64位整数,第一个操作数必须是long
;即 (52 & (1L << 37))
.
在java中,Integer是32
位表示(不考虑32位或64位架构)。
当使用 long
时,以下将按预期给出 0
(37
< 64
):
(52 & (1L << 37))
对于 long
,对于大于 63
(更具体地说大于 (1 << 63) - 1)
)的移位,同样的问题会出现
现在考虑为什么答案是 32
整数:
1 << 31 == Integer.MIN_VALUE
(1 << 32) - 1 == 0
1 << 32 == 1 == 2^(32 - 32) == 2^0
1 << 33 == 2 == 2^(33 - 32) == 2^1
1 << 34 == 4 == 2^(34 - 32) == 2^2
1 << 37 == 32 == 2^(37 - 32) == 2^5
因为 Java 语言规范说 left-shifting(旧的,但这些东西变化不大)
If the promoted type of the left-hand operand is int, then only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.
所以在32位int
s上操作时,你代码中的<< 37
变成了<< 5
,而52 & (1 << 5)
实际上是32
。
我正在尝试制作一个算法,给定一个整数,吐出其二进制形式的字符串表示形式。
现在,我基本上是在比较掩码以查看在何处附加 1/0 位。这工作正常,直到出现稍大的数字,例如:(52 & (1 << 37))
如果我正确理解位移运算符(显然我没有理解)应该 return 0,因为 (1 << 37)
= 1
和 37 * 0
的。上次我查了一下,二进制格式的小数点第38位52
没有1,为什么这个return32?
整个表达式使用 32 位数执行,因为所有操作数都是 int
值。
因此 1 << 37
不是“一”后跟 37 个“零”位。
事实上,JLS 15.9 表示移位计数被 0x1f
屏蔽(对于 32 位移位运算符)。因此 1 << 37
实际上与 1 << 5
意思相同;即“一”后跟 5 个“零”位。
如果要在移位表达式中使用64位整数,第一个操作数必须是long
;即 (52 & (1L << 37))
.
在java中,Integer是32
位表示(不考虑32位或64位架构)。
当使用 long
时,以下将按预期给出 0
(37
< 64
):
(52 & (1L << 37))
对于 long
,对于大于 63
(更具体地说大于 (1 << 63) - 1)
)的移位,同样的问题会出现
现在考虑为什么答案是 32
整数:
1 << 31 == Integer.MIN_VALUE
(1 << 32) - 1 == 0
1 << 32 == 1 == 2^(32 - 32) == 2^0
1 << 33 == 2 == 2^(33 - 32) == 2^1
1 << 34 == 4 == 2^(34 - 32) == 2^2
1 << 37 == 32 == 2^(37 - 32) == 2^5
因为 Java 语言规范说 left-shifting(旧的,但这些东西变化不大)
If the promoted type of the left-hand operand is int, then only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.
所以在32位int
s上操作时,你代码中的<< 37
变成了<< 5
,而52 & (1 << 5)
实际上是32
。