位运算
注:以下大部分内容来源于 coursera 课程《C++程序设计》
基本概念:
- 低八位,高八位:
0x4455 二进制形式-->0100 0100 0100 0101
从右往左数是从第0位到第15位,0100 0100 是高八位,0100 0101是低八位。
由于计算机仅识别二进制描述的数字,所以对一个内存地址,也就是8位二进制,如:0000 0001,0000就是高四位,0001就是低四位,当然2个内存地址,就是16位二进制,也就是:0000 0001 0000 0002。0000 0001 就是高八位,0000 0002就是低八位,每个八位中又分成高低四位。如:1010 0001 1111 0101,换算成16进制就是:1010–10(10进制)—A(16进制),0001–1(10进制)—1(16进制)所以他的高八位就是A1,同样它的低八位就是F5。
2.负数的2进制:
负数以原码的补码形式表达。
一个负数按照绝对值大小转换成的二进制数,然后最高位补1,称为原码。负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1。
8位有符号的整数取值范围的补码表示:1000 0000 到 0000 0000, 再到 0111 1111,即 -128 到 0, 再到 127,最终 -128 ~ +127。
-15:原码:10001111 补码:11110001
与运算&
作用:通常可以用来将某些变量中的某些位清零且同时保持其他位不变,也可以用来获取某变量中的某一位。
如果需要将int型的变量n的低八位全置成0,而其余位不变,则可以这样做:
n = n & 0xffffff00;
低八位置成0,高二十四位保持不变。
也可以写成:
n &= 0xffffff00;
如果n是short类型的,short只有16位,那么则写成
n &= 0xff00;
如果要判断一个int型变量n的第7位(从右往左,从0开始数)是否为1,那么,则可以这样:
n &= 0x80;
或运算|
作用:将某变量中的某些位置置1且保留其他位不变。
例如,要将int类型的变量n的低八位置成1,其余位保持不变,那么可以这样做:
n |= 0xff;
异或运算^
不相同为1,相同为0
作用:将某些变量中的某些位取反,并保持其他位不变。
例如,要将int类型的变量n的低八位取反1,其余位保持不变,那么可以这样做:
n ^= 0xff;
性质:
1. A ^ 0 = A;
2. 若a^b = c,则c^b=a, c^a = b;
3. a = a^b, b = a^b,a = a^b;
性质2: 列举a和b可能的四种情况,穷举法可证。且此规律可以用来加密和解密:b用作密钥,a^b生成密文c。反之由密文c解出a,则可以用c^b=a。
性质3:不通过临时变量,交换a,b的值,穷举法可证。
性质3举例:
a = 5, b = 7
a = 0101, b = 0111
a = a^b = 0010
b = a^b = 0101
a = a^b = 0111
非运算~
左移运算<<
a<<b的过程是将a各二进位全部左移b位得到的值,高位丢弃,低位补零。a的值不因运算而改变。
例子:
9<<4:
00001001
10011001 = 144
性质:左移操作相当于乘以2^n, 并且左移操作快于乘法。
右移运算>>
a>>b的过程是将a各二进位全部右移b位得到的值,右边的位丢弃。
左边的数有讲究:
1.如果是有符号的数,l例如int, long, short,char这些类型的变量。右移时,符号位(即最高位)一起移动。
2.如果原符号位为1,那么左边补的那些位都为1。
性质:移移操作相当于除以2^n
-25>>4 = -2 (往小里取)
-2>>4 = -1
例子截图
思考题1:有两个int型的变量a和n(0<=n<=31),要求写一个表达式,使该表达式的值和a的第n位相同。
思路:出题意图是看a的第n位是0还是1,这里可以将a的第n位取出来,和1做与运算。1只有最右一位是1,其余位都是0。
答案: (a>>n)&1
思考题2:有两个int型的变量a和n(0<=n<31),要求写一个表达式,使该表达式的值和a的第n位相同。
答案:(a&(1<<n))>>n
布尔运算符
c++里加一句: boolalpha,就会输出true false,否则会输出 01。
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
bool flag = true;
cout << boolalpha;
cout << "15大于88吗?"<< (15>18)<<endl;
return 0;
}
`