计算原理
现代计算机只能处理二进制数据。包括基本的加减乘除都是通过二进制运算来完成的。
只是二进制不方便程序猿→_→记忆,后来各位仙人大佬就各出奇招。汇编语言出现,A、B、C语言等相对高级的语言也相继出现。
由于二进制更加贴近硬件,能更好的针对硬件优化,这就是为什么汇编大部分时候会快于C等高级语言的原因。 当然在高级语言中,我们也可以适当的运用位运算来提高程序的性能。
void test(int x)
{
if (x & 1) {
printf("奇数");
} else {
printf("偶数");
}
}
具体原理看下面
位运算符
| 运算 | 操作符 | 示例 |
|---|---|---|
| 左移(低位补0) | << | 0011 => 0110 |
| 右移(正数右移,高位用补0,负数右移,高位用补1) | >> | 0110 => 0011 |
| 无符号左移(低位补0) | <<< | 1111 => 1110 |
| 无符号右移(高位补0) | >>> | 1111 => 0111 |
| 按位或 | | | 0011 | 1011 => 1011 |
| 按位与 | & | 0011 & 1011 => 1011 |
| 按位取反 | ~ | 0011 => 1100 |
| 按位异或 (相同为零不同为一) | ^ | 0011 ^ 1011 => 1000 |
求绝对值
int v;
unsigned int r; // 绝对值
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
r = (v + mask) ^ mask;
例如+7(00000111) 8位, 计算出mask=00000000;
(00000111 + 00000000) ^ 00000000 => 00000111
正数的绝对值是它本身!
如果是-7(11111001), 计算出mask=11111111;
(11111001 + 11111111) ^ 11111111 => 00000111
负数绝对值等于正数!
判断奇偶性
void test(int x)
{
if (x & 1) {
printf("奇数");
} else {
printf("偶数");
}
}
1的二进制是 000...00001; 任何数和它进行 & 操作第一位以上的位都会变成0, 由于x是进行二进制运算, 所以最低位1为奇数,0为偶数。
交换值
// 不使用中间变量交换变量值
void swap(int x , int y)
{
x ^= y;
y ^= x;
x ^= y;
}
取模运算
int mod(int n, int s)
{
unsigned int d = 1 << s; // d是2的幂次方 1, 2, 4, 8, 16, 32, ...
return n & (d - 1); //等价于 n % s
}
参考
en.wikipedia.org/wiki/Assemb…
graphics.stanford.edu/~seander/bi…