第二课:二进制数据(计算机科学——po学院)

mac2024-05-25  40

第二课:二进制数据

二进制

为什么在有十进制的情况下选择使用二进制? 计算机(CPU)由很多的集成电路(IC)构成。集成电路上有许多引脚,一个引脚只有两种状态(高电平和低电平)。高电平(5V),低电平(0V),使用二进制表示引脚的状态更为方便。

二进制可以表达的含义:字符,图片,视频,音频,数值,小数。

字符:英文字母26个 , 大小写52个 ,用特定编号,每个编号对应相应字母。图片:把图片分解为点阵(黑白色);用几个bit来表示其中某个点是某颜色(彩色,8位色,32位色)。音频:通采样形成高低波的点。视频:轨道加图片一帧一帧的播放,原理和图片一样(各种格式是内部的数据排列不同)。

字符、图片、音频、视频都是通过固定的格式表达。 数值和二进制之间可以完美的转换。

二进制和十进制之间的转换:

十进制二进制0011210311410051016110711181000910011010101110111211001311011411101511111610000

1字节=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的移位次幂。

二进制的逻辑运算

非(not):1 ->0;0->1;与(and):两者都为1(真) 时 为 1(真);或(or): 两者都为0(假) 时 为 0(假);异或(xor):不同为1。

二进制表示浮点数

int main() { float sum =0; for(int i =0;i<100;i++) { sum += 0.1; } printf("%f",sum); return 0; }

运行以上程序,结果为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; }
最新回复(0)