我正在写一个简单的程序来确定字符串中唯一的字符。我可以用一种更简单、效率更低的方法来使用数组,但我正在尝试用位向量来实现它。我可以得到正确的输出罚款,但我不确定为什么我得到正确的输出。
我的代码:
class Main {
public static void main(String args[]) {
System.out.println(isUniqueChars("Robert"));
}
public static boolean isUniqueChars(String str) {
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
System.out.println("Val: " + val); //Val = -15 First Iteration
System.out.print("1 << val: "); //Equals 131072
System.out.println(1 << val);
if ((checker & (1 << val)) > 0) {
return false;
}
System.out.print("Checker: ");
checker = checker | (1 << val);
System.out.println(checker); //Equals 131072
System.out.println();
}
return true;
}
}
我想弄明白为什么1<<-15产生131072。我在网上搜索了一下,看了几个关于移位运算符的教程,但没有一个能解释负移位值。
2条答案
按热度按时间zte4gxcn1#
一种看它的方法是位以正数移位
modulo 32
时尚。那么两者之间的正数是多少呢0 and 32
与…一致-15 mod 32
? 通过添加32
至-15
你得到了吗17
. 所以这和你的车一样17
. 事实上,转移-15 + k*32
哪里k
是一个整数,它将移动如下所示的相同数量的位。印刷品
这也意味着不能通过
<< 32
. 你得左转31
然后左移1
. 或者更一般地说,左移k
然后左移32-k
哪里1 <= k < 32
.印刷品
同样的规则也适用于长带
32
被替换为64
.tf7tbtn22#
来自jls:
如果左侧操作数的提升类型为int,则仅将右侧操作数的五个最低阶位用作移位距离。这就好像右操作数接受了位逻辑“与”运算符&(§15.22.1),掩码值为0x1f(0b11111)。因此,实际使用的移动距离始终在0到31之间(包括0到31)。
如果左侧操作数的提升类型为long,则仅将右侧操作数的六个最低阶位用作移位距离。这就好像右操作数接受了位逻辑“与”运算符&(§15.22.1),掩码值为0x3f(0b111111)。因此,实际使用的移动距离始终在0到63之间(包括0到63)。
常数
1
是一个int
,所以-15
,即0xfffffff1
伪装成0x00000011
表示左移17位131072
.