#C++ Day9 October 15 2025

//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。