进制基础及位运算
编码基础与位运算
进制转换
1. \(k\) 进制转十进制
幂乘法
\[(a_{n-1} a_{n-2} … a_0)_k = (\sum_{i=0}^{n-1} a_i \times k^i)_{10}
\]
2. 十进制转 \(k\) 进制
短除法
| 被除数 (除以2为例,替换成\(k\)) | 余数 |
|---|---|
| 123 | 1 |
| 61 | 1 |
| 30 | 0 |
| 15 | 1 |
| 7 | 1 |
| 3 | 1 |
| 1 | 1 |
将余数列颠倒得到结果:
\[(123)_{10}=(1111011)_{2}
\]
3. 十六/八进制转二进制
拼接法
| 1 | 2 | 7 |
|---|---|---|
| 001 | 010 | 111 |
连接去除前导零后得:
\[(127)_{8}=(1010111)_{10}
\]
| 1 | 2 | 7 |
|---|---|---|
| 0001 | 0010 | 0111 |
同理连接去除前导零后得:
\[(127)_{16}=(100100111)_{10}
\]
4. 二进制转十六/八进制
分割法
| 001 | 010 | 111 |
|---|---|---|
| 1 | 2 | 7 |
从最后\(3\)位起每\(3\)位转换成八进制,最后不足\(3\)位补前导零:
\[(1010111)_{10}=(127)_{8}
\]
| 0001 | 0010 | 0111 |
|---|---|---|
| 1 | 2 | 7 |
从最后\(4\)位起每\(4\)位转换成八进制,最后不足\(4\)位补前导零:
\[(100100111)_{10}= (127)_{16}
\]
5.不同进制在c语言中的表示。
无前缀表示十进制,0前缀表示八进制,0x前缀表示十六进制,0b前缀表示二进制。
#include <stdio.h>
int main() {
int a = 11, b = 011, c = 0x11, d = 0b11;
printf("%d %d %d", a, b, c);
return 0;
}
无符号整数的表示
直接转换二进制
有符号整数的表示
以\(32\)位的有符号整数为例。
我们用第一位作为符号位表示正负,0正1负,余下的位表达数字。
我们确定符号位后将数字转换为\(31\)位的二进制,如果是正数保持原样,如果是负数。将其+1后除符号位取反。
布尔的表示
一般情况下以一个字节储存,只有0,1两个值,分别表示真,假。对于其他类型转换bool时,二进制非全0为1,反之为0。
字符的表示
采用ascii编码。
位运算
基本运用
#include <stdio.h>
int main() {
int a = 0b110101, b = 0b101100;
printf("%d\n", a & b); // 位与,a和b二进制均为1的位为1,反之为0,c = 0b100100
printf("%d\n", a | b); // 位或,a和b二进制均为0的位为0,反之为1,c = 0b111101
printf("%d\n", a ^ b); // 位异或,a和b二进制位相同为0,反之为1,c = 0b011001
printf("%d\n", ~(-2)); // 位取反,将该数储存的二进制形式每位取反
printf("%d\n", a >> 1); // 位右移,将二进制整体向右移动一位,在前方补0
printf("%d\n", a << 1); // 位左移,将二进制整体向左移动一位,在后方补0
return 0;
}
位左移运用
a << k // 将a乘以2^k
1 << n // 快速计算2^n,或获取一个仅第n位为1其他位为0的二进制数
(1 << k) - 1 // 获取一个仅含k个1的二进制数
位右移应用
\[(n >> k) \Leftrightarrow \lfloor \frac{n}{2^k} \rfloor
\]
位与应用
取出
\[n \& 1 \Leftrightarrow n \ mod \ 2
\]
(n >> k) & 1 // 获取二进制下第k位
n & ((1 << k) - 1) // 获取二进制后k位
位或应用
设1
n | (1 << k) // 将二进制第k位设为1
n | ((1 << k) - 1) // 将二进制后k位设为1
异或运算
交换
有\(0 \ xor 1=1\) ,\(1 \ xor 1=0\)
n ^ (1 << k) // 将二进制第k位取反
n ^ ((1 << k) - 1)) // 将二进制后k位取反
void swap(int &a, int &b) {
a ^= b ^= a ^= b;
} // 交换a,b的值
位非的应用
\(~(-1)=0\)
~(1 << k) // 获取一个除第k位为0,其他位为1的二进制数
n & (~(1 << k)) // 将二进制第k位设0
快速幂
int quickpow(int a, int b) {
int ans = 1;
for (; b; b >>= 1) {
ans *= a;
a *= 2;
}
return ans;
}

浙公网安备 33010602011771号