位运算
位运算主要包括按位与(&)、按位或(|)、按位异或(^)、取反(~ )、左移(<<)、右移(>>)这几种,其中除了取反(~)以外,其他的都是二目运算符,即要求运算符左右两侧均有一个运算量。
进制转换
B:二进制数
O:八进制数
D:十进制数
H:十六进制数
(1)二进制转十进制
按权展开求和
(2)十进制转二进制
整数:除以2取余,逆序输出
小数:乘以2取整,顺序输出
其他进制同理(感性理解即可)
原码、补码和反码
这个博客讲的挺好的:https://www.cnblogs.com/author/p/8954127.html
原码
是计算机中一种对数字的二进制定点表示方法。原码表示法在数值前面前面有一位符号位(即最高位为符号位),正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。
原码是有符号数的最简单的编码方式,便于输入输出,但作为代码加减运算时较为复杂,故计算机一般不采用这种编码方式存储符号数。
反码
正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外
由于-0这个问题的存在,会使得计算机需要增加额外的物理硬件配合运算,所以在计算机发展的早期就已经抛弃了使用反码储存数据。
补码
正数和+0的补码是其原码,负数则先计算其反码,然后反码加上1,得到补码。
补码换算为原码的过程中,如果补码是正数或者+0的补码,则其原码就是补码本身;如果补码是负数或者-0的补码,则其原码的计算方法是,先将补码减掉1,得到反码,再将反码取反,得到原码。
按位与(&)
参加运算的两个数,换算为二进制(0、1)后,进行与运算。只有当相应位上的数都是1时,该位才取1,否则该位为0。
按位或(|)
参加运算的两个数,换算为二进制(0、1)后,进行或运算。只要相应位上存在1,那么该位就取1,均不为1,即为0。
按位异或(^)
参加运算的两个数,换算为二进制(0、1)后,进行异或运算。只有当相应位上的数字不相同时,该为才取1,若相同,即为0。
任何数与0异或,结果都是其本身。
异或还可以交换两个数
a = a ^ b;
b = b ^ a;
a = a ^ b;
取反(~)
参加运算的两个数,换算为二进制(0、1)后,进行取反运算。每个位上都取相反值,1变成0,0变成1。
左移(<<)
在二进制表示下把数字同时向左移动,低位以0填充,高位越界后舍弃
1 << n = 2 ^ n
n << 1 = 2n
右移(>>)
在二进制补码表示下把数字同时向右移动,高位以符号位填充,低位越界后舍弃(算术右移)
算术右移等于除以2向下取整
注意
c++中,两个数值执行算术运算时,以参与运算的最高数值类型为基准,与保存结果的变量类型无关,所以要用到强制转换。
快速幂
long long Pow(long long x, long long y)
{
long long t = 1;
while (y)
{
if (y & 1) t = t * x % mod;
y /= 2;
x = x * x % mod;
}
return t % mod;
}