第二章 计算机的数据表示
目录
0x00 数据编码的概念
数据是计算机处理的对象
分类:
- 数值数据
- 非数值数据
数据必须经过编码才能被计算,处理,存储,传输
编码是采用少量基本符号(0,1)规定一系列组合规则来表示大量复杂的信息。
基本符号:
位:bit
最基本的存储单元
位运算:与& 或| 非^ 异或
思想:
两个数相加求全集,全集中减去自己就是对方。
异或可以理解为二进制加法。
自己异或自己=0
问题:
第一种如果两个地址相同就完蛋了
第二种如果两个数相等就完蛋了
字节:8bit
int x = 0x ff 11 22
小端系统:数值高位 放在 内存地址高位
数值地位放在 内存地址低位
大端系统:正好相反
字:2个字节或者4个字节
作业5.14
(2)
3
(3)
大端系统:
0x01 数值数据的编码
(1)定点数的存储形式:小数点固定的数
分为纯整数和纯小数
如果将小数点约定到最低位之后,那就是纯整数
并且如果约定最高为表示符号,可以表示正负。
如果没有约定最高位表示符号,则只能表示正
如果将小数点约定到最高位之前,那就是纯小数,即只能存小数点之后的数据。
如果想表示负的纯小数,则将最高位作为符号位,小数点位于符号位之后。
表示定点数的四种编码:
1.原码:
符号数值表示法
定点小数的原码:
特点:
0有两种编码:正0和负0,这会为数学运算造成问题
负数原码的码值>正数原码的码值(码值=符号位+数据位)
2.反码:
正数和0 的反码 = 原码
负数的反码 = 符号位为1 其余位 取反
特点:
- 最高位是符号位 0表示正 1表示负
- 0的反码是不唯一的,
- 负数反码的码值>正数反码的码值
3.补码:
正数和0的补码=原码
负数的补码 = 符号位为1,数值位取反+1(取反加1操作称为求补运算)
如何由负数的补码求原码呢?对负数的补码的数值位再次求补运算即可。
求补运算的特点:就像开关一样,按两次就回到原来的状态
特点:
最高位是符号位 0表示正 1表示负
0的补码是唯一的:
【-0】补=1 111 1111 +1 = 0000 0000
虽然是数值位+1,但是计算机中符号位和数值位是连续存储的,所以+1进位会影响到符号位,并且最后会溢出
符号位的扩展:
在将两个8位补码相加的时候,我们担心结果溢出,所以需要先将8位补码扩展成16位
如何将8位补码扩展成16位的补码:
将符号位扩展8位!因为最后解释16的补码的时候,将最高位解释为符号位,其余的15位是数值位,求补运算后得到真值。
而符号位后的7个1,正好在对补码进行求补运算求真值的时候
7个1全部变成0!这样得到的真值才是正确的!
注意:
-128 转化为二进制为-1000 0000
补码符号位为1 数值位=二进制的后7位 取反加1,溢出部分舍弃
所以-128的补码 = 1000 0000
1000 0000在解释的时候1解释为负
000 0000 求补运算 = 111 1111 + 1 = 1000 0000=128
所以为-128
移码:
正数和0 的移码,符号位为1 数值位不变
负数的移码,符号位为0,数值位求补运算
特点:
最高位为符号位,1表示正,0表示负
0的移码唯一 = 0000 0000
正数的码值 > 负数的码值 可以一眼看出正负数的大小,浮点数的指数用移码
移码和补码的转换:符号位取反即可
移码的本质:移码相当于将真值在数轴上移动了128位,如上图真值0移动到了真值128的位置,移动了128
作业:
定点整数的补码的范围的推导方法:
正数:0111 1111=+(111 1111)=127 数值位取全1最大
负数:1000 0000= -(111 1111+1)=-128数值位取全0最大
定点小数的补码的范围的推导:
(2)浮点数的编码表示:
非标准浮点数的表示:
浮点数=尾数*基数^阶数
二进制浮点数的表示形式:v=(-1)^s * F * 2^E
s用来控制正负(要么是0要么是1)。叫做 尾符
F是尾数
2是基数
E是阶数
如何将v存入计算机呢?
需要将s,f,e存起来,有了这三部分就能还原出浮点数,而公式中的-1和2已经约定好了,所以不用存
s尾符占1位(要么是0要么是1)将f对补码进行编码,将e用移码进行编码
首先,存储一个浮点数的总位数是事先固定好的,例如C语言中float是4字节,double是8个字节。
f来控制浮点数的精度,f位数多则这个数的精度就高
e来控制浮点数的大小,e的位数多则能存的浮点数的范围大
也就是说f占的位数多了,e占的位数就少了。
<1>浮点数尾数的规格化:
因为浮点数小数点可以浮动,所以浮点数有无数种表示形式
为了让浮点数有唯一的存储形式,所以需要尾数的规格化
即将F的值如下限制:
因为F是用补码表示的,1/2补码表示如下(定点小数补码表示)
这样一来,如果f大于0,则补码的表示为0.1xxxxx
如果f小于0,则补码的表示为1.0xxxxx
即规格化的f的二进制形式要么是0.1xxxxx
要么是1.0xxxxx
<2>计算机存储浮点数的步骤:
例如:25.5存入计算机
因为11001.1不是规格化形式,右移五位后0.1xxxxx是规格化的形式
然后,只需要将f的小数部分存起来就可以了。
而e用移码表示,所以5的移码是10101,最高位1是符号位表示正
注意:第一问因为符号位是0,所以f转补码就是小数点后的部分原码
第二问由于符号位是1,所以f的补码等于小数点后的部分求补运算。
<3>n位浮点数的表示范围:
例题:一个24位的浮点数的表示范围是多少?
e的范围:8位移码 -2^7<=E<=2^7-1
f的范围:
f是用定点小数的形式的存储的,所以小数点前的0和1表示符号位。
0.1xxxx:
+.1000... 到+.11111....
+0.5 <=F<=1-2^(-15)
1.0xxxx: -1<F<
注:
0.1怎么转10进制?0.1+0.1=1 所以0.1 = 1-2^-1
同理0.11111..后面15个1怎么转10进制呢?当然是加上0.0000...1 凑成1,所以0.11111= 1- 2^(-15)
<4> IEEE754标准浮点数的表示:
单精度扩展,C语言没有实现,一定比单精度精度高,但是不一定比双精度高
例如:
存储步骤仍然是相同的:
单精度编码:
上图(-1)是^1,写错了
754标准的规格化:
1.xxxxx 即小数点前是1,小数点后任意
754规定对f的编码:就是用真值。把小数点后抄下来即可,位数不够则在末尾补0,小数点前的1是数值,不表示符号,不存(因为是规格化好的)
754对e的编码:用移码表示
n为分配给e的长度(754规定为8位),E是10进制的e,即上文中的6
e=E+(2^(n-1)-1)
754的移码:将真值移动了127位,(原来的移码是将真值移动了128)
双精度编码:
作业:IEEE754标准的浮点数:2.22①②
以迷你精度的754浮点数为例:
s用1位表示,e用4位表示,f用3位表示,所以:e = E +(2^(4-1)-1) =E +7 即 E = e-7
f非规格化时和f规格化时:
f非规格化:小数点前是0
f规格化:小数点前是1
非规格化向规格化数的过度是平滑的
离原点越近码点约密集,离原点约远码点约稀疏。
来源:CSDN
作者:无在无不在
链接:https://blog.csdn.net/weixin_43415644/article/details/104552710