Skip to content
无符号整数(逻辑右移)`>>`
  • 右移n的操作就是二进制右边n位舍弃,左面补n个0
  • 十进制的结果可以记为:右移n位,即为整数除以2的n次方,结果向下取整(比如19 >> 2 => 19 / 4 => 4.75 => 4)
有符号整数(算术右移)`>>>`
  • 右移n的操作就是二进制右边n位舍弃,左面补n个符号位的值(正数补 0,负数补1)
  • 十进制的结果可以记为:右移n位,即为整数除以2的n次方,结果向下取整(比如-19 >> 2 => -19 / 4 => -4.75 => -5)

为什么不只搞1个右移操作符?

  1. 可移植性与定义不明确 在 C/C++ 中,>> 用于有符号整数时,标准规定是“实现定义”
    也就是说不同编译器、不同 CPU,结果可能不同

  2. 可控性(语言语义明确 vs 智能猜测)

语言设计者倾向于:

  • 明确告诉你:你写>>,你就知道它是啥行为
  • 而不是根据类型“猜测”你想干啥(避免不确定行为)
  1. 类型推断可能不明确
cpp
auto x = foo();
x >> 2;

此时你可能都不知道 x 的类型是 int、unsigned int 还是 char,那语言怎么判断你到底是想做逻辑右移还是算术右移?强制明确操作反而更安全。

这里针对3,其实Java这种强类型语言是知道类型的,为什么不设计1个右移符号呢?
Java 的设计哲学是:语义明确、行为可预期、绝不“猜你的意图”,也就是回到第2点上
“强类型 ≠ 自动猜测操作行为”
“强类型 + 显式操作 = 安全 + 可维护性 + 无歧义”
所以Java中是没有无符号整数的,所有整数类型(int, long)都被视为有符号类型

右移的常见操作

除以2的幂次

如上

提取整数x的i位二进制

⚠️这里的i从0开始 (x >> i) & 1 可以配合数据的长度遍历每一位

java
public class BinaryBitTraversal {
    public static void main(String[] args) {
        int x = 19;
        int bitLength = Integer.toBinaryString(x).length();
        for (int i = 0; i < bitLength; i++) {
            int bit = (x >> i) & 1;
            System.out.printf("第 %d 位: %d\n", i, bit);
        }
    }
}
提取整数x的多位二进制(从i到j)
java
public class BinaryBitExtraction {
    public static void main(String[] args) {
        int x = 0b110101; // 二进制数 110101,十进制为 53
        int i = 1;
        int j = 3;
        // 右移 i 位
        int shifted = x >> i;
        // 创建掩码
        int mask = (1 << (j - i + 1)) - 1;
        // 按位与操作
        int result = shifted & mask;
        System.out.println(Integer.toBinaryString(result)); // 输出10,提取出第 1 到第 3 位
    }
}