//5 – 6 – 5 left shift operator
#include <iostream>
using namespace std;
/*
x << y = x * 2^y
binary operator (二元运算符)
*/
int main() {
//1.positive number’s left shift
int x = 0b11; //3
x = (x << 1); // 6;0b110;left shift one bit, it will be multiple 2
cout << x << endl;
cout << “—————–” << endl;
cout << (x<<4) << endl;//x*2^4
cout << “—————–” << endl;
//2.negative number’s left shift
int y = -1;
y = (y << 1);//-1*2^1
cout << y << endl;
cout << “—————–” << endl;
//3.left shift negative’s bits
int z = 64;
z = (z << (-1));//it don’t allow the left shift’s right value is a negative number;despite some decoder can output it
cout << z << endl;
cout << “—————–” << endl;
//4.left shift overflow
int a = 64;
a = (a << 10);//it don’t allow the left shift’s right value is a negative number;despite some decoder can output it
cout << a << endl;
//64=0b1000000
//31 = 0b1…0000000000000000000000000000000000000
//the int only can store 4bytes,so that the 1 will be cut out(截断)
//left shift = *2 ;unstoppable *2 must be overflow
cout << “—————–” << endl;
return 0;
}
//5 – 6 – 6 right shift operator
#include <iostream>
using namespace std;
/*
x>>y right shift = x/2^y
*/
int main() {
//1.postive number’s right shift
int a = 0b111; //7
a = (a >> 1); // 7/2^1=3;cut out the rightest 1,and the remaining 0b11 will be 3
cout << a << endl;
cout << “——–” << endl;
//2.negative number’s right shift
int b = -1;
cout << (-1 >> 1) << endl;//-1
//11111111 11111111 11111111 11111111 this is -1-> right shift 1 bit–>//01111111 11111111 11111111 1111111 –> 11111111 11111111 11111111 1111111(finally it will be 1 on the symbol bit)
cout << “——–” << endl;
//3.remove the lower k’s bits
int c = 0b10000101;
cout << (c >> 7) << endl;//removed 0000101
cout << “——–” << endl;
//4.retrive the lower k’s bits’ value
int d = 0b101010101;
// 1
cout << ((d >> 4) & 1) << endl;//if the fourth bit is 1,after the bitwising,there will be output 1
return 0;
}
AI:
要理解 “11111111 11111111 11111111 11111111” 为何代表 – 1,核心在于计算机中整数的二进制表示规则—— 尤其是 “补码(Two’s Complement)” 编码方式。计算机为了统一处理正数和负数的加减运算,规定了带符号整数的存储格式,32 位(4 个字节,每个字节 8 位)带符号整数的表示逻辑如下:
1. 先明确前提:这是 32 位 “带符号整数” 的二进制
计算机中的整数分为两类:
- 无符号整数(unsigned):仅表示非负数,所有二进制位都用于存储数值(范围:0 ~ 2³²-1);
- 带符号整数(signed):需区分正负,规定最高位(第 31 位,从 0 开始计数)为符号位:
- 符号位 = 0 → 正数;
- 符号位 = 1 → 负数。
你给出的 “11111111 11111111 11111111 11111111” 是 32 位二进制,且最高位为 1,因此它是一个带符号负数,需用 “补码” 规则解析其实际值。
2. 关键规则:负数用 “补码” 存储
为了避免 “正 0” 和 “负 0” 的重复(如 8 位二进制中,00000000 和 10000000 都表示 0),同时让 “正数 + 负数” 的运算等同于普通二进制加法(无需额外处理符号),计算机规定:
正数的原码、反码、补码完全相同;负数的补码 = 其 “绝对值的原码” 按位取反(反码) + 1。
反过来,若已知一个负数的补码,要计算其实际值,需执行逆操作:
负数的绝对值 = (补码 按位取反) + 1,再加上负号。
3. 一步步计算:32 位全 1 补码对应的值
对 “11111111 11111111 11111111 11111111” 执行逆操作:
- 补码按位取反:将所有 1 变为 0,所有 0 变为 1。
32 位全 1 的补码取反后,结果是 00000000 00000000 00000000 00000000(32 位全 0)。 - 取反后 + 1:00000000…00000000 + 1 = 00000000 00000000 00000000 00000001(即十进制的 1)。
- 加上负号:由于原补码的符号位为 1(表示负数),因此最终值为 -1。
4. 延伸验证:8 位带符号整数的例子
若将范围缩小到 8 位(1 字节),“11111111” 同样是 – 1,逻辑完全一致:
- 8 位全 1 的补码 → 符号位 = 1(负数);
- 按位取反:00000000 → +1 后 = 00000001(十进制 1);
- 最终值:-1。
而 8 位带符号整数的范围是 -128 ~ +127(正是补码规则的结果),32 位带符号整数的范围则是 -2³¹ ~ +2³¹-1,其中 “11111111 11111111 11111111 11111111” 恰好是这个范围中的 “-1”。
总结
“11111111 11111111 11111111 11111111” 代表 – 1,本质是计算机用32 位带符号整数的补码规则存储负数的结果:
符号位为 1(表示负数),其补码对应的绝对值为 1,因此最终值为 – 1。