了解java中的位移位是如何处理负移位值的

zengzsys  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(462)

我正在写一个简单的程序来确定字符串中唯一的字符。我可以用一种更简单、效率更低的方法来使用数组,但我正在尝试用位向量来实现它。我可以得到正确的输出罚款,但我不确定为什么我得到正确的输出。
我的代码:

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。我在网上搜索了一下,看了几个关于移位运算符的教程,但没有一个能解释负移位值。

zte4gxcn

zte4gxcn1#

一种看它的方法是位以正数移位 modulo 32 时尚。那么两者之间的正数是多少呢 0 and 32 与…一致 -15 mod 32 ? 通过添加 32-15 你得到了吗 17 . 所以这和你的车一样 17 . 事实上,转移 -15 + k*32 哪里 k 是一个整数,它将移动如下所示的相同数量的位。

int k = 4;
int v = 1; 
for (int i = -15+(32*-k); i < -15+(32*k); i+= 32) {
  int res = v << i;
  System.out.printf("1 << %4d == %d%n", i, res );
}

印刷品

1 << -143 == 131072
1 << -111 == 131072
1 <<  -79 == 131072
1 <<  -47 == 131072
1 <<  -15 == 131072
1 <<   17 == 131072
1 <<   49 == 131072
1 <<   81 == 131072

这也意味着不能通过 << 32 . 你得左转 31 然后左移 1 . 或者更一般地说,左移 k 然后左移 32-k 哪里 1 <= k < 32 .

int k = 98;
System.out.println(k<<32); // really shifts by 0
System.out.println((k<<31)<<1));

印刷品

98
0

同样的规则也适用于长带 32 被替换为 64 .

tf7tbtn2

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 .

相关问题