在 Java 中对 long 进行位移
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22330107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bitshifting a long in Java
提问by Dori
Im sure this is an easy one for whoever sees it first!
我敢肯定,对于第一个看到它的人来说,这很容易!
Why in Java does code like
为什么在 Java 中代码像
long one = 1 << 0;
long thirty = 1 << 30;
long thirtyOne = 1 << 31;
long thirtyTwo = 1 << 32;
System.out.println(one+" = "+Long.toBinaryString(1 << 0));
System.out.println(thirty+" = "+Long.toBinaryString(1 << 30));
System.out.println(thirtyOne+" = "+Long.toBinaryString(1 << 31));
System.out.println(thirtyTwo+" = "+Long.toBinaryString(1 << 32));
打印
1 = 1
1073741824 = 1000000000000000000000000000000
-2147483648 = 1111111111111111111111111111111110000000000000000000000000000000
1 = 1
This does not make sense to me. long
is a 64 bit number - whereas it seems to act like an int
in the above. I know bitshifted byte
s undergo int promotion but I dont see whats going on in this case.
这对我来说没有意义。long
是一个 64 位数字 - 而它的作用似乎类似于int
上面的 。我知道 bitshifted byte
s 进行 int 升级,但我不知道在这种情况下发生了什么。
Any pointers on whats going on here would be good :)
任何关于这里发生的事情的指示都会很好:)
Thx
谢谢
EDIT: thanks for all the answers - i realised what was going on as soon as I clicked 'submit' but SO went into readonly
mode and I couldnt delete! Many thanks!
编辑:感谢所有的答案 - 我一点击“提交”就意识到发生了什么,但进入readonly
模式,我无法删除!非常感谢!
采纳答案by Bathsheba
It's because 1 is an int
literal, so <<
is applied to an integer. The result is cast to a long
, but by then it's too late.
这是因为 1 是一个int
文字,所以<<
适用于一个整数。结果被转换为 a long
,但为时已晚。
If you write 1L << 32, etc., then all will be well. L
is used to denote a long
literal.
如果你写 1L << 32等,那么一切都会好起来的。L
用于表示long
文字。
回答by arshajii
Well you're using int literals, which behave like ints. Use a long literal (i.e. 1L
) instead:
好吧,您正在使用 int 文字,其行为类似于 int。改用长文字(即1L
):
System.out.println(1 << 31);
System.out.println(1L << 31); // <--
-2147483648 2147483648
When you have an expression like 1 << 31
, it evaluates to a fixed value irrespective of what it's being assigned to, be it int
or long
.
当你有一个像 的表达式时1 << 31
,它的计算结果是一个固定的值,而不管它被分配给什么,是它int
还是long
。
回答by DanielBarbarian
This is because the number 1
in the line long thirtyTwo = 1 << 32;
is an int
by default. You need to explicit mark it as a long before you do the shift operation. What happens now is that you do a shift on an int
which then after the shift is done is casted from an int
to a long
.
这是因为该1
行中的数字默认long thirtyTwo = 1 << 32;
为 an int
。您需要在执行移位操作之前将其显式标记为 long。现在发生的事情是,您对 an 进行了转换int
,然后在转换完成后将其从 an 转换int
为 a long
。
long one = 1l << 0;
long thirty = 1l << 30;
long thirtyOne = 1l << 31;
long thirtyTwo = 1l << 32;
回答by Tillerino
The problem is that 1
is an integer. It will be converted to a long afterthe shift. Try
问题是这1
是一个整数。它将在移位后转换为 long 。尝试
long one = 1l << 0;
long thirty = 1l << 30;
long thirtyOne = 1l << 31;
long thirtyTwo = 1l << 32;
回答by Jesper
First of all:
首先:
Java Language Specification paragraph 15.19
Java 语言规范第 15.19 段
Shift Operators
If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are usedas 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.
If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand operand are usedas 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 0x3f (0b111111). The shift distance actually used is therefore always in the range 0 to 63, inclusive.
移位运算符
如果左侧操作数的提升类型为 int,则仅将右侧操作数的最低 5 位用作移位距离。就好像右手操作数受制于掩码值为 0x1f (0b11111) 的按位逻辑 AND 运算符 &(第 15.22.1 节)。因此实际使用的移动距离总是在 0 到 31 的范围内,包括 0 到 31。
如果左侧操作数的提升类型为 long,则仅将右侧操作数的 6 个最低位用作移位距离。就好像右手操作数受制于掩码值为 0x3f (0b111111) 的按位逻辑 AND 运算符 &(第 15.22.1 节)。因此,实际使用的移位距离始终在 0 到 63 的范围内,包括 0 到 63。
So, why does it work as if you are shifting int
s instead of long
s? Because you are shifting int
s! Try using a long
literal instead:
那么,为什么它会像移动int
s 而不是long
s 一样工作?因为你在换int
s!尝试使用long
文字代替:
long thirtyTwo = 1L << 32;
回答by mauretto
literal 1 is an int. Use 1L (L as long) and retry.
文字 1 是一个整数。使用 1L(L 一样长)并重试。
回答by Pierre Rust
It acts like an int
because you are shifting ints ! To shift a long, you must suffix all your number with l
.
它的行为就像是int
因为你正在转移整数!要移动 long,您必须在所有号码后加上l
.
long one = 1l << 0;
long thirty = 1l << 30;
long thirtyOne = 1l << 31;
long thirtyTwo = 1l << 32;
System.out.println(one+" = "+Long.toBinaryString(1l << 0));
System.out.println(thirty+" = "+Long.toBinaryString(1l << 30));
System.out.println(thirtyOne+" = "+Long.toBinaryString(1l << 31));
System.out.println(thirtyTwo+" = "+Long.toBinaryString(1l << 32));
Which gives the following result :
这给出了以下结果:
1 = 1
1073741824 = 1000000000000000000000000000000
2147483648 = 10000000000000000000000000000000
4294967296 = 100000000000000000000000000000000