二进制和位运算

二进制和位运算

1.有符号数和无符号数

有符号数

有符号数最高位表示符号位,最高位为0表示非负数(注意:最高位为0不一定表示正数,还可能表示0),最高位为1表示负数.

int x=1;//x为有符号数,在内存中表示为0x00000001,最高位为0
int y=-1;//y为有符号数,在内存中表示为0xffffffff,最高位为1

无符号数

无符号数所有位都表示数值,无符号数均为非负数

unsigned int num = 0B11111111'11111111'11111111'11111111;
cout << num << endl;//4294967295

2.负数的补码与二进制表示

有符号数在计算机中以补码的形式存储,对于正数而言,将其转化为对应的二进制即为补码,对于负数而言,一种简单的补码计算方案如下:

  1. 获取负数绝对值的二进制表示
  2. 将获取到的二进制取反后加1

以-3为例:

  • 获取绝对值的二进制表示:00000000’00000000’00000000’00000011
  • 将该二进制表示按位取反后加上1:11111111’11111111’11111111’11111101

已知数据在内存中的二进制表示,获取数据的十进制解释

如果数据在内存中二进制表示形式的最高位为0,按照一般正数的逻辑进行解释,如果最高位为1,表示该数据为负数,然后将二进制表示取反后在加1得到数值大小,例如数据在内存中显示为11111111’11111111’11111111’11111101,按照规则将其解释为-3

3.打印一个数在内存中的二进制表示

利用与运算的特点,可以判断一个数的某一位是否为0

void printBinary(int num) {
    for (int i = 31; i >= 0; i--) {
        cout << (((1 << i) & num) ? '1' : '0');
    }
    cout << endl;
}

通过二进制和16进制直接定义一个数

通过二进制或16进制定义数时,如何进行定义底层就会如何进行存储,不会做转化

int a = 0b10101101'00000000'01010101'01110011;
printBinary(a);//10101101000000000101010101110011
int b = 0xffffffff;
printBinary(b);//11111111111111111111111111111111

4.常见的位运算

  • 与运算(&):2位均为真,结果才为真
  • 或运算(|):任意1位为真,结果为真
  • 异或运算(^):符号不同为真,可以理解为无进位相加
  • 按位取反(~):0变1,1变0
  • 左移(<<):左移时低位补0
  • 有符号右移(>>):高位补符号位
  • 无符号右移(>>>):高位补0,在Java中,存在无符号右移,C/C++中只有有符号右移

&、&&、|、||的区别

&&和||没有"穿透性",在进行逻辑与判断时,只要左边为false,右边便不在进行计算,在进行逻辑或判断时,只要左边为true,右边便不在进行计算

bool returnTrue() {
    cout << "returnTrue被执行" << endl;
    return true;
}
bool returnFalse() {
    cout << "returnFalse被执行" << endl;
    return false;
}
returnTrue() || returnFalse();//returnTrue被执行
returnFalse() && returnTrue();//returnFalse被执行

&和|具备穿透性,&和|一定会将整个结果计算完成,因为其计算结果表示的含义不一定为bool

returnTrue() | returnFalse();
returnFalse() & returnTrue();

5.相反数

相反数与按位取反是不同的概念

int a=-b//完全等价于int a=~b+1

INT_MIN的相反数还是自己,因为~INT_MIN+1还是自身

6.负数的设计

负数的存储比正数复杂许多,负数采用这种设计可以保证加法运算的正确性,以-1±1为例:

printBinary(-1);//11111111111111111111111111111111
printBinary(-2);//11111111111111111111111111111110

虽然在计算过程中出现了溢出,但是因为负数巧妙的设计,计算结果依然是正确的,使用正数加上负数时也有这样的效果,虽然计算过程中可能出现溢出,但是只要保证自己的调用得到的结果不溢出,计算机依旧可以正确的计算出来

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值