为什么在有十进制的情况下选择使用二进制? 计算机(CPU)由很多的集成电路(IC)构成。集成电路上有许多引脚,一个引脚只有两种状态(高电平和低电平)。高电平(5V),低电平(0V),使用二进制表示引脚的状态更为方便。
二进制可以表达的含义:字符,图片,视频,音频,数值,小数。
字符:英文字母26个 , 大小写52个 ,用特定编号,每个编号对应相应字母。图片:把图片分解为点阵(黑白色);用几个bit来表示其中某个点是某颜色(彩色,8位色,32位色)。音频:通采样形成高低波的点。视频:轨道加图片一帧一帧的播放,原理和图片一样(各种格式是内部的数据排列不同)。字符、图片、音频、视频都是通过固定的格式表达。 数值和二进制之间可以完美的转换。
二进制和十进制之间的转换:
十进制二进制00112103114100510161107111810009100110101011101112110013110114111015111116100001字节=8位(bit)
0011+1100=3+12=15; 1101+0011=13+3=16
因为计算机只能增位,所以计算机只能做加法运算。如果计算机要做减法运算,要把被减数转换为负数,进行加法运算。
如:1101-0011——>1101 +(-0011)
如何将转换为负数? 每一个引脚可以存储一个二进制的值,我们规定一个固定的长度(8,16,32位)来表示一个数值,拿它最前面的一位来表示符号。0代表正数,1代表负数。
如:11000101=-69;第一个1代表的是符号“—”
但是,如果直接这样做加法运算,是会出错的:
如:0011+1001不等于3+(-1)
所以,这个时候我们引进了补码,在运算减法的时候先计算出补数再进行相加。
补数=取反+1; 如:0001(1)——>1110(取反)——>1110+1——>1111(-1)
计算机确定一个数时,首先确定长度,然后确定是正数还是负数(正数全部表示数值,负数首位表示符号,余位表示数值,1后面以补码的形式存储)。
0没有补码,0不是正数也不是负数。
乘法(左移): 0001(1)左移两位0100(4);122=4 0010(2)左移两位1000(8);222=8 0011(3)左移一位0110(6);3*2=6
乘法结果=原数值X2的移位次幂。
除法(右移): 0100(4)右移一位0010(2);4/2=2 111000(56)右移两位001110(14);56/4=14
逻辑右移:不管正负,右移补0; 除法结果=原数值/2的移位次幂。
10000000(-128)右移两位11100000(-32);-128/2/2=(-32)
算式右移:右移时,根据符号位决定补0还是补1; 除法结果=原数值/2的移位次幂。
运行以上程序,结果为10.000002,而不是10。 这是为什么呢?
二进制表示小数时 ,会丢失一定的数据,计算机计算浮点数不可能准确的。
如何解决这种问题呢?
不去处理,只要对程序不产生影响 忽略掉精度不对的情况;不拿小数运算 (不把它当作小数,极端情况),乘以相应的倍数,得到结果后再 除以相应倍数。 int main() { float sum =0; for(int i =0;i<100;i++) { sum += 0.1 *10; } printf("%f",sum/10); return 0; }