进制的本质是查数
n进制有n个符号表示,n个符号可以自己定义
加1/进1的本质是向后查一个数。
进制运算无需转化成十进制,每一种进制方式都是完美的,你之所以不会算是因为头脑中没有对应的加法表,减法表,乘法表,除法表
八进制:0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27
1+1=2 | ||||||
1+2=3 | 2+2=4 | |||||
1+3=4 | 2+3=5 | 3+3=6 | ||||
1+4=5 | 2+4=6 | 3+4=7 | 4+4=10 | |||
1+5=6 | 2+5=7 | 3+5=10 | 4+5=11 | 5+5=12 | ||
1+6=7 | 2+6=10 | 3+6=11 | 4+6=12 | 5+6=13 | 6+6=14 | |
1+7=10 | 2+7=11 | 3+7=12 | 4+7=13 | 5+7=14 | 6+7=15 | 7+7=16 |
0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
熟记此对应关系,立即反应。看到A就立即反应1010,看到6就立即反应0110。
对于二进制,十六进制要如同十进制一般敏感。
忘掉十进制,十进制就是一块绊脚石。
数据宽度:数学上的数字,是没有大小限制的,可以无限大,但是计算机中,由于受到硬件的制约,数据都是有长度限制的(我们称为数据宽度),超过最大宽度的数据会被丢弃。
计算机常见数据宽度:
- 位(bit) 0~1
- 字节(byte)=8bit 即能储存8个0或1 存储范围:0~~1111 1111 =FF
- 字(word)=16bit 0~FFFF
- 双字(doubleword)=32bit 0~FFFF FFFF
编码规则:不同文件有不同的编码规则。
无符号数
1001 1010=9A
有符号数:
0001 1010 当符号位为0时,为正数,和无符号数编码规则相同=1A;
原码:最高位为符号位,其余各位为数值本身的绝对值
反码:正数的反码与原码相同,负数:符号位为1,其余位对原码取反。
补码:正数的补码与原码相同,负数:符号位为1,其余位对原码取反+1
例如:(以下数据宽度为字节 8bit)
原码 | 反码 | 补码 | |
1 | 0 000 0001 | 0 000 0001 | 0 000 0001 |
6 | 0 000 0110 | 0000 0110 | 0000 0110 |
-1 | 1 000 0001 | 1 111 1110 | 1 111 1111(FF) |
-2 | 1 000 0010 | 1 111 1101 | 1 111 1110(FE) |
-3 | 1 000 0011 | 1 111 1100 | 1 111 1101(FD) |
-4 | 1000 0100 | 1111 1011 | 1111 1100 (FC) |
-5 | FB | ||
-6 | FA | ||
-7 | 1 000 0111 | 1 111 1000 | 1 111 1001(F9) |
-8 | (F8) | ||
-9 | (F7) |
总结:内存中正负数都是以补码形式储存。
无符号数:00~FF=00~7F(正数)+FF~80(负数)假设数据宽度为8bit
假设数据宽度为doubleworld32bit 0000 0000~FFFF FFFF=0000 0000~7FFF FFFF(正数)+8000 0000~FFFF FFFF
计算机如何运算?
计算机只认识0和1,能做的运算归根结底也就是直接对0和1做运算(通常称为位运算)
为什么要学位运算?
有些功能必须通过位运算才能实现:比如写调试器,判断CPU的各种状态位。
大公司面试题:比如2*8效率最高的方式。
- 与运算(汇编:and C语言: &):两个位都为1时,结果才为1。
- 或运算(or |):只要有一个为1就是1。
- 异或运算(xor ^):不一样的时候是1。
- 非运算(not ~):(单目)0就是1,1就是0。
- 左移(shl <<):各二进制位全部向左移动若干位,高位丢弃,低位补0。
- 右移:各二进制位全部右移若干位,低位丢弃,高位补0或者补符号位。
- shr 1101 0101 0011 0101 补0 对应C语言中
unsigned int a=10;//有unsigned则补0 printf("%d\n",a>>2); int a=10;//无unsigned则补符号位 printf("%d\n",a>>2);
- sar 1101 0101 1111 0101 补符号位
- shr 1101 0101 0011 0101 补0 对应C语言中
总结:计算机只会做位运算!
4+5=?运算过程
4+5=?运算过程
0000 0100
0000 0101
加------------
0000 1001
0000 0100
0000 0101
异或----------
0000 0001
在忽略进位的情况下,异或的结果是相同的
1)异或
0000 0100
0000 0101
异或----------
0000 0001
2)判断是否有进位(通过与运算来判断,如果与完=0说明没有进位,为1说明该位向前进位)
0000 0100
0000 0101
与------------
0000 0100
3)继续异或
0000 0001//第一次异或的结果
0000 1000//与运算结果左移1位的结果
异或----------
0000 1001
4)判断是否有进位
0000 0001
0000 1000
与------------
0000 0000
0000 1001->9;
4-5=?的运算过程
=4+(-5)
1)异或
0000 0100
1111 1011
异或--------------
1111 1111
2)判断是否有进位
0000 0100
1111 1011
与--------------
0000 0000
1111 1111=FF=-1
乘法的运算过程:X*Y的本质就是加法,Y个X相加
除法的运算过程:X/Y的本质就是减法,X能减去多少个Y