计算机中的进制
热身题 1)
1.32位是几个字节?
2.二进制数01011100转换成十进制数是多少?
3.二进制数00001111左移二位后,会变成原数的几倍?
4.补码形式表示的8位二进制数11111111,用十进制表示?
5.补码形式表示的8位二进制数10101010,用16位二进制数表示?
6.反转部分图形模式时,使用的是什么逻辑运算?
计算机内部是由IC(Integrated Circuit)这种电子部件构成,CPU和内存也是IC的一种。IC的所有引脚只有直流电压0V或5V两个状态。也就是说,IC的一个引脚,只能表示两个状态。
二进制由 0,1 表示。
二进制的位数一般是8位,16位,32位······ 也就是8的倍数,计算机所处理的基本单位是8位二进制数。8位二进制数为一个字节。字节为基本的信息计量单位。
如果小于存储数据的字节数,那么高位上就由 0 填补。
8位 : 100111 -> 00100111
16位: 100111 -> 0000000000100111
32位处理器则一次可以处理4字节二进制数信息
无论是十进制数还是文字等信息,最终都会转成二进制表示信息。计算机不会区分它是数值、文字、还是某种图片的模式等,具体进行何种处理,取决于程序编写方式。
什么是二进制数
原理:二进制数的值转换成十进制数的值,只需要将二进制的各位数的值和位权相乘,然后将相乘结果相加即可。
例:
39这个数值, 拆分来看是 3 * 10 + 9 * 1 。
这里各个位数的数值相乘的 10 和 1 ,就是位权。
如果放入二进制数中来表达
即第1位是2的0次幂,第2位是2的1次幂,第3位是2的2次幂。依次类推。
在十进制中 基数 为10 , 二进制中基数为 2。
二进制数00100111用十进制数表示是39,因为:
(0 * 128) + (0 * 64) + (1 * 32) + (0 * 16) + (0 * 8) + (1 * 4)
+ (1 * 2) + (1 * 1) = 39
左移运算符
“<<”,左移一位为原数值的2倍,以此类推
a = 10;
b = a << 2;
左移后空出来的位数由0进行补位,但只适合 <<,
>> 时,用来填充右移后空出来的高位值,有0,1两种形式
补数
二进制中表示负数时将最高位作为符号来使用,一般把最高位成为符号位,符号位是0表示正数,1表示负数。
0 0 0 0 0 0 0 1
最高位指向第一个位,也就是第一个0
计算机在做减法运算时,实际上内部是在做加法运算。为此,在表示负数时就需要使用 二进制的补数,补数就是用正数来表示负数。
其实获取补数其实就是对二进制的各位数值全部取反,然后结果加1,例:
0 0 0 0 0 0 0 1 原始数值
1 1 1 1 1 1 1 0 取反
1 1 1 1 1 1 1 1 加一,完成获取补数
例 1 - 1,也就是 1 + (-1),答案是0。如果将-1表示为10000001来计算,结果则不为0。
错误的运算:00000001 + 10000001 = 10000010
正确的运算:00000001 + 11111111 = 100000000
如果-1表示为11111111进行运算,出现了最高位溢出的情况,不过,对于溢出的位,计算机会直接忽略掉。
100000000 这个9位二进制会被认为是 00000000。
补数求解的变换方法就是 “ 取反 + 1 ”。
右移运算符
“>>”,区分逻辑右移和算术右移
逻辑右移:在二进制数的值表示图形模式而非数值时,移位后需要在最高位补0
算术右移:将二进制数作为带符号的数值进行运算时,移位后要在最高位填充 0 或 1。如果值为负数,那么右移后空出来的最高位补1,就可以正确实现1/2,1/4,1/8等。如果是正数,需要在最高位补0即可。
-4(11111100)右移两位
此时,逻辑右移下结果就会变为 00111111,也就是十进制63,并非为 -4的1/4。
而算术右移的情况,结果就会变为11111111,补数表示也就是-1。
只有在右移时需要区分,左移只需要补0即可。
符号扩充:在保持值不变的前提下将其转成16位和32位二进制数。
8位 : 01111111
16位 : 0000000001111111
不管是证书还是补位数表示的负数,都只需用符号位的值(0或1)填充高位即可。
逻辑运算
逻辑运算指对二进制数各数字位的0和1分别进行处理的运算,包括 逻辑非(NOT)、逻辑与(AND)、逻辑或(OR)、逻辑异或(XOR,exclusive or)
逻辑非(NOT)指的是 0 变 1, 1 变 0 的取反操作
0 -> 1
1 -> 0
逻辑与(and)两个数都是1时结果为1,其他情况为0
0 0 -> 0
0 1 -> 0
1 0 -> 0
1 1 -> 1
逻辑或(or)至少一方是1时结果为1,其他情况为0
0 0 -> 0
0 1 -> 1
1 0 -> 1
1 1 -> 1
逻辑异或(xor)排斥相同数值的运算
0 0 -> 0
0 1 -> 1
1 0 -> 1
1 1 -> 0
热身题 1) 答案
1. 4
2. 92
3. 4倍
4. -1
5. 1111111110101010
6. XOR运算
热身题 2)
1.二进制数0.1用十进制数表示是多少?
2.用小数点后又3位的二进制数,能表示十进制数0.625吗?
3.将小数分为符号、尾数、基数、指数4部分进行表现的形式成为什么?
4.二进制数的基数是多少?
5.通过把0作为述职范围的中间值,从而在不适用符号位的情况下表示负数的表示方法称为什么?
6.10101100.01010011二进制,用十六进制表示是多少?
例:
1011.0011 二进制数转换为十进制数
小数点前的部分的位权,第1位是2的0次幂,第2位是1次幂,依次类推。
小数点后面的位权,第1位是-1次幂,第2位是-2次幂,依次类推。
(1 * 8) + (0 * 4) + (1 * 2) + (1 * 1) + (0 * 0.5) + (0 * 0.25) +
(1 * 0.125) + (1 * 0.0625) = 11.1875;
那为什么计算机会计算错误呢? 因为 “有一些十进制数的小数无法转换成二进制数”。 例 0.1,就无法用二进制数正确表示,小数后面即使有几百位也无法表示。
小数点后4位用二进制数表示时的数值范围 0.0000 ~ 0.1111,因此,这里只能表示 0.5 、0.25、0.00625 这几个二进制数小数点后面的权位组合而成的小数。
例如:
二进制:0.0000 0.0001 ···
十进制:0 0.0625 ···
在 0 和 0.0625中间的小数,就无法用小数点后4位数的二进制数来表示。依次类推。 十进制数0.1转换为二进制数时会变成 1100这样的循环小数,计算机功这个功能有限的设备,无法处理循环小数,当遇到此类情况,会进行四舍五入。
浮点数由 符号、尾数、基数、指数组成
在 64位中称为双精度浮点数,符号部分 1位,指数部分 11位,尾数部分 52位。
在 32位中称为单精度浮点数,符号部分 1位,指数部分 8位,尾数部分 23位。
双精度浮点数和单精度浮点数在表示同一数值时使用的位数不同。双精度浮点数能够表示的数值范围较大。
符号
符号:使用一个数据位来表示数值的符号。该数据为1表示负,0表示 “正或者0”。数值的大小用尾数部分和指数部分来表示。这里不用纠结它们是做什么的后面接着看。
尾数
尾数部分使用正则表达式。在数学中,例如 十进制数0.75就有很多种表现形式。虽然它们表示的都是同一个数值,但因为表现方法太多,计算机处理相对麻烦,所以为了方便处理,需要定制一套规则。
例如, 十进制的浮点数应该遵循“小数点前面是0,小数点后面第1位不能是0” 这样的规定。
0.75就是 0.75 * 10 的0次幂。
当然在二进制数中也同样适用,在二进制中 ,将小数点前面的值固定为1的正则表达式。
例:
1011.0011 原始数据
0001.0110011 右移使整数部分的第一位变成1
0001.01100110000000000000000 确保小数点后面长度23位
01100110000000000000000 仅保留小数点后面的部分,完成正则表达式
指数
指数部分中使用EXCESS系统,使用这种方法主要是为了表示负数时不能使用符号位。在某些情况下,指数部分需要通过 负OO次幂的形式来表示负数。
EXCESS系统指,通过将指数部分表示范围的中间值设为0,是的附属不需要用符号来表示。
我们将EXCESS系统比作 1 ~ 13 这些值。 取中间的5这这个值当成0,7就表示+2,3就表示-2。这个规则就是EXCESS系统。
例:
static void number(){
float data;
unsigned long buff;
int i;
char s[34];
//以单精度浮点数储存
data = (float)0.75;
//将数据复制到 4 字节长度的整数变量 buff 中
memcpy(&buff, &data, 4);
for (i = 33; i >= 0; i--) {
if (i == 1 || i == 10) {
//将各个部分划分
s[i] = '-';
} else {
if(buff % 2 == 1){
s[i] = '1';
}else{
s[i] = '0';
}
buff /= 2;
}
printf("%lu\n",buff);
}
s[33] = '\0';
printf("%s\n",s);
}
输出,十进制0.75用单精度浮点数表示
0-01111110-1000000000000000000000
对应的符号部分为 0
指数部分为 01111110,十进制数为126,用EXCESS系统表现就是 -1 (126 - 127)
剩余为尾数 1.1000000000000000000000 基于正则表达式规则,将二进制数转为十进制数,结果为
(1 * 2 的 0 次幂) + (1 * 2 的 -1 次幂) = 1.5
因此 这个单精度浮点数表示的就是 “ +1.5 * 2 的 -1 次幂 ” = +0.75
热身题 2)答案
1. 0.5 二进制数的小数点后第一位位权是 2的-1次幂,也就相当于
0.1 -> 1 * 0.5 = 0.5 十进制数就是0.5
2. 可以表示,转换成二进制数为0.101
3. 浮点数 (符号 尾数 * 基数的指数次幂)
4. 基数为2
5. EXCESS
6. AC.53 整数部分和小数部分一样,二进制数的4位相当于十六进制的1位