数据在计算机中的表示及运算
一、计算机的存储单位
1.1 最小单位和基本单位
在计算机中,最小的存储单位是位(b),也就是bit,是二进制单位,一个位只有0和1两种情况,因为在底层电路中,多种形态容易被干扰而导致识别出错,通电状态代表1,断电状态代表0,容易被区分,因此计算机采用二进制。而如今的计算机处理数据时常用的基本单位是字节(B),也就是byte,这里的1字节=8位(1B = 8b)。
1.2 常见单位换算
除了最小单位b和基本单位B,还有其他数据单位,如KB, MB, GB, TB, PB, EB(艾字节), ZB(泽字节), YB(尧字节)和BB(亿字节)。其中常用数据单位的换算关系如下(210=1024):
单位 | 读作 | 换算关系 |
---|---|---|
B | 字节 | 1B=8bit |
KB | 千字节 | 1KB=1024B |
MB | 兆字节 | 1MB=1024KB |
GB | 吉字节 | 1GB=1024MB |
TB | 太字节 | 1TB=1024GB |
PB | 拍字节 | 1PB=1024TB |
1.3 字节和字长
这里还有一个词容易和字节混淆,就是字长。字节是数据的存储单位,而字长是指计算机进行数据处理时一次性存储、加工和传送的数据长度
,由一个或若干个字节组成。它决定了计算机数据处理的速度,是衡量计算机性能的重要指标,一般来说,字长越长,计算机的性能越好。我们常说的32位,64位,指的就是芯片处理数据的字长。
二、计算机的进制
2.1 常用计数制
计数制 | 基数 | 进位规则 |
---|---|---|
十进制D | 0~9 | 逢十进一 |
二进制B | 0~1 | 逢二进一 |
八进制Q | 0~7 | 逢八进一 |
十六进制H | 0~9 A-F | 逢十六进一 |
规律:(开始可能会不理解,但是经常和我们使用的十进制类比一下,久而久之就理所当然了~)
- 相同的基数在不同的数位上表示不同的数值。
- 每位数值=基数*位权。
- J进制左移n位后,数值=原数值✖️Jn,J进制右移n位后,数值=原数值➗Jn。
2.2 不同数制之间的转换
这里不用记口诀,重在理解,先熟练二进制和十进制之间的转换,其它的一通百通。
二进制转十进制:按权展开求和,如,
(1101.01)2=1✖️23+1✖️22+0✖️21+1✖️20+0✖️2-1+1✖️2-2=(13.25)10。
十进制整数转二进制:商一直除以2,直到除数大于被除数,商为0;其中每一步除以2的时候,取余数(0或1),排列好然后逆序输出,如,
62➗2=31…0
31➗2=15…1
15➗2=7…1
7➗2=3…1
3➗2=1…1
1➗2=0…1,此时商为0,停止
所以(62)10=(111110)2。
十进制小数转二进制:小数部分一直乘以2,直到最后结果为整数;其中每一步乘以2的时候,取整数(0或1),排列好然后顺序输出,如,
0.625✖️2=1.25,取整1
0.25✖️2=0.5,取整0
0.5✖️2=1.0,取整1,此时结果为整数,停止
所以(0.625)10=(101)2。
(为什么这么做能得到正确的结果?我的数学也不好,一下子也不能完全理解,但是结果确确实实是正确的,究竟前辈们是怎么发现这个规律和逻辑的,就需要自己去多摸索了😮💨)
综上:二进制->十进制,只需要按权展开求和;十进制->二进制,整数和小数部分分开计算,然后把结果放一块即可。(其他进制,如八进制和十六进制,他们与十进制的转换方法和二进制一样,可以自己试试🐶)
这里八进制与二进制的转换(每位八进制数可以与三位的二进制数互相替换),十六进制与二进制的转换(每位十六进制数可以与四位的二进制数互相替换)不再赘述,如果使用频繁,自己推算出的规律才能记得牢。
其实也不难理解,3个比特位的取值范围是0~7,和八进制是一样的,可以这么看,所谓八进制就是三个比特位的别称而已,因此可以直接替换,少位就补0,十六进制也一样。
注:不同进制变的只是数据的表示形式,其数据本身的大小还是一样的,万变不离其宗。
2.3 二进制的运算
2.3.1 二进制的算术运算
算术运算分为加、减、乘、除四种,计算原理和十进制是一样的,如,
加:0+0=0,0+1=1+0=1,1+1=10(逢2便向高位进1)
减:0-0=1-1=0,1-0=1,0-1=1(不够了便向高位借1当2)
乘:0✖️0=0,0✖️1=1✖️0=0,1✖️1=1
除:0➗1=0,1➗1=1(0作除数是没有意义的,因为不存在任何商与0的乘积为非0的被除数)
而在计算机内部,二进制的基本运算是加法,至于减法、乘法以及除法等运算其实都是利用加法来实现的,高级的芯片会有包装好的专门的集成电路来实现不同的运算,这会大大提高运算的速度。
2.3.2 二进制的逻辑运算
这里我理解的逻辑运算就是判断真假的运算,在二进制中,刚好有0和1两个值,其中用1表示“真”,用0表示“假”。逻辑运算中的表示如下:
逻辑乘,也就是与运算,符号为∧(&&)
逻辑加,也就是或运算,符号为∨(||)
逻辑非,符号为¬(!)
逻辑异或,符号为⊕(为什么叫异或,我也不造🤔)
它们的运算规则如下:
A | B | A∧B | A∨B | ¬A | ¬B | A⊕B |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 0 | 0 |
进行逻辑运算时,不同位之间没有任何关系,也不存在算术运算中的进位或错位问题。
三、 数值数据的表示
3.1 机器数与真值
前面我们只讲了数值在不同进制之间的转换,这里来看一下数值在计算机中具体是如何表示的。
在计算机中,表示数值的数字符号只有0和1两个。为了区分正数和负数,我们规定最高位是符号位,并用0表示正数符号,用1表示负数符号。(一般在编写程序时,默认都是有符号数,若不需要负值,要在类型前面声明unsigned,但其实机器底层的表示是没有变化的,程序改了处理方式)。这样,机器中的数值和符号就全都“数码化”了。(想到了数码宝贝🥹)
我们将一个数在机器中的表现形式称为机器数,将机器数对应的原值,即一般书写表示的数称为真值。如:机器数1
0000001,其原值/真值为-0000001,对应的十进制是-1。(这里表现出最高比特位被用来表示真值中的符号了)
注:数据的二进制形式并不等于机器数
在对机器数进行运算时,我们发现是有问题的,如,
00000001+10000010=10000011,这里1+(-2)的值变成了(-3),显然是错误的。
因此,为了计算机运算的方便,科学家们对机器数采用了不同的编码方法,称为码制
,(也就是另外制定了一套规则来规定它们的意义,这套规则是怎么实现的?不造啊🥹)。常见的码制有原码、补码、反码及移码。
3.2 原码表示法
设X为真值(二进制形式的数值),[X]原则为机器数的原码表示。也就是最原始的机器数表示,符号位用0表示正,用1表示负。如,(以字节为单位)
设 X=1100110,则[X]原=0
1100110
设 X=-1100111,则[X]原=1
1100111
0在原码中有两种表示方式:
若 X=+0,则[X]原=0
0000000
若 X=-0,则[X]原=1
0000000
原码的特点
是,容易与真值进行转换,但不方便运算。
3.3 反码表示法
正数的反码同其原码,而负数的反码是——对其原码各位取反,除了符号位。如,
设 X=1100110,则[X]原=0
1100110,[X]反=0
1100110
设 X=-1100111,则[X]原=1
1100111,[X]反=1
0011000
0在反码中也有两种表示方式:
若 X=+0,则[X]原=0
0000000,[X]反=0
0000000
若 X=-0,则[X]原=1
0000000,[X]反=1
1111111
反码的特点
是,解决了原码加减运算的不足,但未解决0的两种表示方法的不足,如今已较少使用。(*0有两种不同的表示方法是如何影响数值表示范围的???*🤔️)
3.3 补码表示法
正数的补码同其原码,而负数的补码是——对其原码各位取反(除了符号位),最后加1。如,
设 X=1100110,则[X]原=0
1100110,[X]补=0
1100110
设 X=-1100111,则[X]原=1
1100111,[X]补=1
0011001
0在补码中的表示是唯一的:
若 X=+0,则[X]原=0
0000000,[X]补=0
0000000
若 X=-0,则[X]原=1
0000000,[X]补=10
0000000(1会溢出)
补码的特点
是,不仅解决了加减运算问题,还解决了0的唯一性问题。(*解决0的唯一性问题真的只是为了要多表示一个数值的范围嘛???*🤔️)
注:用什么码制的机器数进行运算,最后的结果也是该码制。
3.4 移码
X的移码同X的补码一样,只是对补码的符号位取反。如,
设 X=1100110,则[X]原=0
1100110,[X]补=0
1100110,[X]移=1
1100110
设 X=-1100111,则[X]原=1
1100111,[X]补=1
0011001,[X]移=0
0011001
0在移码中的表示也是唯一的:
若 X=+0,则[X]原=0
0000000,[X]补=0
0000000,[X]移=1
0000000
若 X=-0,则[X]原=1
0000000,[X]补=0
0000000,[X]移=1
0000000
(*移码是做什么用的???*🤔️)
3.5 各种码制的总结&表示范围
(1) 正数的原码、反码、补码都相同,符号位是0,数值位是真值本身。
(2) 负数的原码、反码、补码的符号位都为1,数值位——原码是真值本身、反码是各位取反、补码是各位取反再在包括符号位的基础上加1(符号位溢出的情况只有一种,那就是真值本身就是0)。
(3) 0的原码和反码表示不唯一,补码和移码表示唯一。
(3) 二进制表示的整数范围(设有n位二进制位):
原码:0~2n-1(无符号,可表示2n个数),-(2n-1-1)~2n-1-1(有符号,可表示2n个数,其中0有两种表示,所以实际上只能表示2n-1个数)
反码:-(2n-1-1)~2n-1-1(不存在无符号的情况,可表示2n个数,其中0同样有两种表示,所以实际上也只能表示2n-1个数)
补码:-2n-1~2n-1-1(不存在无符号的情况,可表示2n个数,其中0只有一种表示,这里对-0补码产生进位后多出的100…00即可代表-2n-1)
注:计算机最基本的运算就是加法,其他运算都是利用加法来实现的,对于无符号整数,机器数用原码表示就够了,其他码制的出现是为了解决减法运算,所以这里只有原码才存在无符号的情况。
根据不同码制的表示范围,可知在有符号整数中,补码表示范围最大。
举个例子,在8位二进制中:(记住数据本身大小是不变的,只是表现形式变了而已)
原码:
无符号:00000000~11111111,即0~255
有符号:11111111~01111111,即-127~+127
反码:
有符号:10000000~01111111,即-127~+127(这里11111111和00000000都表示0)
补码:
有符号:10000000~10000001~01111111,即-128~-127~+127
Tips:有时间自己推算一遍是最好的,加深理解。
3.6 数的定点和浮点表示
在计算机中小数点一般有两种表示法:一种是小数点固定在某一位置
的定点表示法;另一种是小数点的位置可以任意移动
的浮点表示法。
(1) 定点表示法
机器中所有数的小数点位置是固定不变的,因而小数点就不必使用记号表示出来。实际上,小数点可固定在任意一个位置上。
(2) 浮点表示法
为了扩大数的表示范围,方便用户使用,有些计算机常采用浮点表示法。一个浮点数由两部分组成:尾数和阶码。
尾数:表示数的有效数值。
阶码:表示小数点在该数中的位置。
公式是N=2E * S:其中,E为N的阶码(Exponent),是有符号的整数;S为N的尾数(Mantissa),是数值的有效数字部分,一般规定取二进制定点纯小数形式。
如:1011101 B = 2+7 * 0.1011101,101.1101 B = 2+3 * 0.1011101,0.01011101 B = 2-1 * 0.1011101。
浮点数这里有点迷糊,可能因为平时讲得比较多的是整型,后面和问题一起在评论区补充吧~
Over!