在C++中,右移操作符(>>
)对于整数类型(如int
、long
、short
等)的行为在二进制层面上主要取决于该整数是否是有符号的。以下是关于右移操作符在二进制中数值位和符号位的知识点:
有符号整数 :
- 对于有符号整数(如
int
、long
等),右移操作符执行的是算术右移。 - 在算术右移中,符号位(最高位)会被复制到新生成的左侧空位中。这意味着如果原始数值是负数(在二进制补码表示中,最高位是1),那么右移后得到的数值仍然是负数。
- 数值位(除了符号位以外的位)向右移动指定的位数。
无符号整数 :
- C++标准库中没有内置的无符号整数类型(如
unsigned_int
),但通常有unsigned
前缀的整数类型(如unsigned int
、unsigned long
等)。 - 对于无符号整数,右移操作符执行的是逻辑右移。
- 在逻辑右移中,左侧的空位会被填充为0。
- 数值位向右移动指定的位数。
二进制补码表示:
- C++中的有符号整数通常使用二进制补码表示法。在这种表示法中,正数的二进制表示与其原码相同,而负数的二进制表示是其绝对值的二进制表示(原码)按位取反后加1。
- 因此,对于有符号整数,符号位是最高位(最左边的位),它决定了整数的正负。
示例:
假设我们有一个8位的有符号整数x = -4
(在二进制补码表示中为1111 1100
)。当我们执行x >> 1
(即右移1位)时,得到的结果是1111 1110
(在十进制中为-2),因为符号位(最高位)被复制到了新的左侧空位中。
无符号右移(>>>):
- 值得注意的是,C++并没有提供类似于Java中的无符号右移操作符(
>>>
)。在C++中,如果你想要模拟无符号右移的行为,你需要首先将整数转换为无符号类型(如果可能的话),执行右移操作,然后再转换回原来的类型(但这可能会导致数据丢失或符号解释的改变)。
右移和除法的关系:
- 对于无符号整数或正的有符号整数,右移
n
位相当于将该数除以2^n
(并向下取整)。但对于负的有符号整数,由于算术右移会保持符号位不变,因此这个关系并不总是成立。