编码基础与位运算
进制转换
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 = 0b100100printf(“%d\n”, a | b); // 位或,a和b二进制均为0的位为0,反之为1,c = 0b111101printf(“%d\n”, a ^ b); // 位异或,a和b二进制位相同为0,反之为1,c = 0b010101printf(“%d\n”, ~(0x7fffffff - 1)); // 位取反,将该数储存的二进制形式每位取反return 0;
}