这更多的是语言设计而不是编程问题.
以下是JLS 15.19移位运算符的摘录:
如果左手操作数的提升类型是
int,则只使用右手操作数的五个最低位作为移位距离.如果左侧操作数的提升类型是
long,则只使用右侧操作数的六个最低位作为移位距离.
这种行为也在C#中指定,虽然我不确定它是否在Javascript的官方规范中(如果有的话),但至少基于我自己的测试也是如此.
结果是以下情况属实:
(1 << 32) == 1
Run Code Online (Sandbox Code Playgroud)
据我所知,这个规范很可能受到以下事实的启发:当移位32位值(64位为6位)时,底层硬件只占用计数操作数的5位,我可以理解在例如,JVM级别,但为什么高级语言(如C#和Java)会保留这种相当低级别的行为?它们不应该提供超出硬件实现的更抽象的视图,并且行为更直观吗?(如果他们可以采取负数来表示向其他方向转移,那就更好了!)
我知道我可以使用右移执行除以2.
为简单起见,采用4位数系统
-1 - 1111
-2 - 1110
-3 - 1101
-4 - 1100
-5 - 1011
-6 - 1010
-7 - 1001
-8 - 1000
7 - 0111
6 - 0110
5 - 0101
4 - 0100
3 - 0011
2 - 0010
1 - 0001
0 - 0000
Run Code Online (Sandbox Code Playgroud)
如果我尝试表演
6 / 2 = 0110 >> 1 = 0011 = 3
-6/ 2 = 1010 >> 1 = 1101 = -3
Run Code Online (Sandbox Code Playgroud)
对+ ve和-ve数都有效
但是,当来到1
1 / 2 = 0001 …Run Code Online (Sandbox Code Playgroud) 如果移位的数字是正数>>>和>>工作相同.
如果移位的数字是负的>>>用1s填充最高有效位,而>>操作移位用0填充MSB.
我的理解是否正确?
如果负数存储时MSB设置为1而不是Java使用的2s补码方式,那么运算符的行为会完全不同,对吗?
我有这个代码:
int code = 0x92011202;
int a = (code & 0xF0000000) >> 28;
int b = (code & 0x0F000000) >> 24;
// ..
int n = (code & 0x0000000F);
Run Code Online (Sandbox Code Playgroud)
但如果最重要的位code等于1(从9到F)则为a负值.所有其他变量工作正常.
为什么会这样?
我知道这就是代码。但我无法理解它的作用
`public static int bitCount(long i){
i = i - ((i > > > 1) & 0x5555555555555555L);
i = (i & 0x3333333333333333L) + ((i > > > 2) & 0x3333333333333333L);
i = (i + (i > > > 4)) & 0x0f0f0f0f0f0f0f0fL;
i = i + (i > > > 8);
i = i + (i > > > 16);
i = i + (i > > > 32);
return (int)i & 0x7f;
}`
Run Code Online (Sandbox Code Playgroud) 我知道 JavaScript 中的数字以 IEEE-754 格式存储。但是当我们使用整数时,特别是按位运算符,它们被表示为 32 位的二进制补码。
-1也会如此0xFFFFFFFF。但是。(-1).toString(2) -1并且-1 >>> 31是 1,没错,但是-1 >>> 32必须是0,无论它是4294967295。而且-1 << 32一定是0,但确实是-1。
为什么按位运算以这种方式工作?并toString()显示带有符号的数字-,为什么这个减号不在符号位中?又何以-1 >> 0是-1,但又-1 >>> 0是4294967295?>>我知道和之间有什么区别>>>,但第二个操作数是0,所以我无法理解为什么这些操作以不同的方式工作。
在Java中,为什么-32 >>> -1 = 1?
它不仅仅是-32.它适用于所有负数,只要它们不是太大.
我发现
x >>> -1 = 1
x >>> -2 = 3
x >>> -3 = 7
x >>> -4 = 15
给定0> x>一些大的负数
是不是>>> -1与<< 1相同?但是-32 << 1 = -64.
我已经阅读了两个补充,但仍然不理解推理.
我知道>>和>>>之间的区别.但我没有得到我预期的输出.
例.
byte foo;
// this part printing -61 so no problem with this part
foo = -121; // -121 = 10000111
// foo >> 1 = 11000011 = -61
System.out.println( (byte) (foo >> 1) );
foo = -121; // -121 = 10000111
// foo >>> 1 = 01000011 = 67
System.out.println( (byte) (foo >>> 1) );
// problem: why is this part printing -61 instead of 67 ?
Run Code Online (Sandbox Code Playgroud)
谢谢.