• 计算机系统基础:数据的表示和存储


    数据的表示和存储


    信息的二进制编码

    数据:
     数值数据:无符号整数、有符号整数;浮点数;(可以在数轴上表示出来,可比较大小的)
     非数值数据:逻辑数(包括01序列),字符等

    计算机内部所有信息都使用二进制进行编码,原因:

    • 具有两个稳定态的物理器件容易制造(电位高/低,脉冲有/无,正/负极,表示1和0)
    • 二进制编码,计数,运算规则简单,也易于电路实现
    • 与逻辑值真/假对应,便于逻辑运算
    • 易使用逻辑电路实现二进制算术运算

    真值和机器数

    • 机器数:计算机内部用0和1编码的01序列
    • 真值:机器数所表示的真实的值

    如 char 型变量 c 的真值为-128,其机器数为1000 0000

    要确定一个数值数据的值,必须先确定三个要素:

    • 进制(最基本的表示方式)
    • 定、浮点表示(解决小数点问题)
    • 编码方式(解决正负号问题)

    进制:
      十进制,二进制,八进制,十六进制
    定/浮点表示:
      计算机中并没有小数点的直接表示,只能约定小数点的位置,
      由此产生定点数(定点整数、定点小数),
      浮点数(可用一个定点小数和一个定点整数表示,小数点的位置用一个数值表示)
    编码方式:
      计算机中也没有正负号的直接表示,因此用一位二进制数表示正负,
      并且使用原码、补码、反码(少见)、移码等编码方案表示真值

    定点数和浮点数
    定点数:小数点位置约定在固定位置
    浮点数:小数点位置约定为可浮动的数

    任何实数X,可以写为 X = (-1)S × M × RE
    其中,S 取值为0或1,决定 X 的符号;M 是一个二进制定点小数,称为数 X 的尾数
    E 是一个二进制定点整数,称为数 X 的指数,指示尾数中的小数点位置;
    R 是进制的基数(现代计算机为2,早期为4和16);
    只要表示 S、M 和 E 三个信息,就可以确定 X 的值,称为浮点数
    在这里插入图片描述
    因此浮点数也是用定点数表示的

    因此数值的表示问题就是定点数的表示问题


    定点数的表示

    定点数的进制、小数点位置都已确定,还需要确定的是编码方式

    原码:最高位为符号位,0表示正数,1表示负数,其余位表示数值
    在这里插入图片描述
    看起来像把整个编码空间平分,正负数的映射各占一半
    原码的问题

    • 0的表示不唯一,0:0000 000;-0:1000 0000;
    • 无法用加法实现减法,需要时时考虑符号
    • 要额外考虑符号位,不利于硬件设计
    • 特别当 a < b 时,实现 a - b 比较困难

    从50年代开始,整数都采用补码进行表示(浮点数的尾数用原码定点小数表示

    移码(增码):将每一个数值加上一个偏置常数(Excess/bias),或者说二进制表示的数减去偏置常数
    通常编码位数为 n 时,bias 取 2n-1 或 2n-1-1(IEEE 754)
    在这里插入图片描述
    即,将所能表示的数从小到大依次映射到编码空间
    移码的特性:当 bias 取 2n-1 时,移码和补码只有第一位不同
    移码用来表示浮点数的阶:便于浮点数加减运算时的对阶操作(比较大小),
    例:1.01×2-1 + 1.11×23,运算时,要将较小的 1.01×2-1 转换为 23 的表示
    此处的阶使用移码进行存储,通过比较 0111(-1) < 1011(3),得到指数的大小关系

    补码:补码的概念基于模运算,在模运算系统中,mod 模数 的结果相同的数是等价的(同余的数等价)
    负数的补码等于模数加上该数,或者将数值位按位取反再加1
    正数的补码等于该数本身
    在这里插入图片描述
    即编码空间分为两部分,非负数与负数首尾相接,且 min = -max-1,因为负数部分不再表示0

    减去一个数相当于加上这个数的相反数的补码
    例:7 - 7 = 7 + (-7) = 0111 + 1001 = 0000
    在这里插入图片描述
    或者说逆时针减7相当于顺时针加上-7对 24 的补码9
    补码的便利:统一了加操作与减操作

    变形补码:使用两位作为符号位,后一个符号位可表示数据
    在这里插入图片描述


    C语言支持的基本数据类型

    (无符号)整数和浮点数,无符号整数没有符号位,所有位都用来表示数据
    在这里插入图片描述

    int x = -1;
    unsigned u = 2147483648;
    printf("x=%u=%d
    ",x,x);
    printf("u=%u=%d",u,u);
    

    结果为
    x=4294967295=-1
    u=2147483648=-2147483648
    由机器码解释,x = 0xFFFF,u = 0x8000
    因此 x 作无符号数解释时,x = 232-1;u 作有符号数解释时,为 -231

    编译器处理常量时的默认类型

    在这里插入图片描述
    Integer Promotion当表达式中存在无符号数与有符号数的运算时,有符号数按无符号数处理

    因此,ISO C90标准的某些情况下,表达式 -2147483648 < 2147483647 的结果为0
    因为 -2147483648 被当做 -2147483648u 、-(unsigned)2147483648 处理,且对无符号数取负是无效的
    在这里插入图片描述
    MSVC的报错信息(GCC可以通过):
    在这里插入图片描述
    最终两边按照无符号数比较大小,结果为0

    但如果写为 -2147483647-1 < 2147483647,等式左边就会正常解析为 int 型,得到结果为1

    浮点数的表示及范围

    前面说过,实数 X 表示为类似科学计数法的形式 (-1)S× M × 2E,确定S、M 和 E 即可表示一个实数
    以 32 位浮点数为例,
    在这里插入图片描述
    第 0 位符号位;1~8 位表示阶码E(移码存储,偏置常数128);9~31 位为 23 位的二进制原码小数 xxxx
    约定尾数 M 的整数位始终为1(为 0 则 E 的变化范围变小了),完整的尾数为 1.xxxx,这种尾数的整数部分始终为1的形式称为规格化形式(Normalized form)

    这样,最大正数 = 1.1111 1111…111 × 2127 = (1-2-24) × 2128
       最小正数 = 1.1111 1111…111 × 2-128 = (1-2-24) × 2-129
    由于表示正负数的 M 是相同的,符号仅由 S 位控制,所以正负数的表示范围是关于0对称的
    在这里插入图片描述
    下溢附近的值可近似表示为0
    机器0:尾数 M 全零

    浮点数表示范围比定点数大,但是编码个数没有变多,因此数之间更稀疏、且不均匀、不准确

    IEEE754

    早期计算机有各自定义的浮点数格式,因此在不同计算机之间进行程序移植时,需要考虑浮点数格式之间的转换
    因此1985年IEEE制定了浮点数标准IEEE 754,现在所有通用计算机都采用该标准表示浮点数
    IEEE 754 中,阶码的全0和全1用来表示特殊值,且偏置常数选择 2阶码位数-1-1,
    (若选择 2阶码位数-1,以32bit为例,阶数范围为-127~126,偏置常数-1后,阶数范围为-126~127,扩大了数的表示范围)
    对于单精度浮点数(single)和双精度浮点数(double),bias分别为127,1023
    single:1+8+23 = 32 bits double:1+11+52 = 64 bits
    例:float型变量的机器数为 BEE00000H
    1011 1110 1110 0(repeats 20) → 1 0111 1101 110(repeats 21) = -1.11×2125-127B = -111/24B = -7/16 = -0.4375

    全0阶码、全1阶码表示的特殊值:

    • 阶码全0,尾数全0,表示0,按符号位,分为+0、-0
    • 阶码1~254,尾数任意,表示规格化数(E,[-126,127])
    • 阶码全1,尾数全0,按符号位分为±∞
      所以,浮点数除以0的结果是 ±∞,而不会出现异常
    • 阶码全1,尾数非0,表示NaN,非数值
    • 阶码全0,尾数非0,表示非规格化数,(-1)S × 0.xxxx × 2-126,填补0与±2-126间的空白
      非规格化非在,现在整数位约定为0了
      在这里插入图片描述
      很容易看出,规格化数是不均匀的,阶码全0,尾数非0表示的非规格化数是均匀的
      有些十进制数是无法精确地按照这种编码方式表示的,比如61.420001,此时计算机中存储的是最接近的可表示数

    非数值数据的编码表示

    逻辑数据:真/假恰好映射为1/0,按照逻辑运算规则运算
    西文字符:字符数量较少,常用编码为ASCII码,1个字节,略
    汉字及国际字符的编码表示:数量巨大,总数超过六万

    • 输入码:对汉字用相应按键进行编码表示,用于输入,比如拼音码
    • 内码:用于在系统中进行存储、查找、传送等处理的01序列
    • 字模点阵或轮廓描述:描述汉字字模点阵或轮廓,用于显示/打印
      西文字符没有输入码,内码即ASCII码,同样有用于显示/打印的字模点阵或轮廓描述
    • GB2312-80字符集
      • 包括字母,数字和各种符号,包括英文、俄文、日文平假名与片假名、罗马字母,汉语拼音等共678个
      • 一级常用汉字,共3755个,按汉语拼音排列
      • 二级常用汉字,共3008个,较少使用,按偏旁部首排列
      • 汉字的区位码
      1. GB2312-80编码表由94行、94列组成,行号为区号,列号为位号,各占7位
      2. 区位号确定汉字在码表中的位置,共14位,区号在左,位号在右
      • 汉字的国标码
      1. 每个汉字的区号位号各自加上32(20H),及该字的国标码
      2. 为方便处理,在区号,位号前各加一位0,构成一个字节
      • 在GB2312国标码基础上产生的汉字内码
        • 每个汉字占两个字节(因为字符集规模,一个字节不够)
        • 为与ASCII码区别,将国标码的每个字节的第一位置1,得到一种汉字内码(汉字内码有很多种方案)
          在这里插入图片描述
          如上图中的字符代码

    多媒体信息的表示

    图形、图像、音频、视频等信息在机器内部也用0和1表示
    只不过多媒体信息用复杂的数据结构描述或编码方式编码,本质上都是01序列


    数据宽度和存储容量单位

    数据的基本宽度

    比特(bit,位):是计算机中处理、存储、传输信息的最小单位
    字节(byte):二进制信息最基本的计量单位;
           现代计算机中,存储器按字节编址
           字节是最小的可寻址单位;
           若以字节为一个排列单位,LSB标识最低有效字节,MSB标识最高有效字节
    (word):表示被处理信息的单位,用来度量数据类型的宽度;
          两个字称为双字(DWORD),同理还有QWORD
    字长:字的位数称为字长,指数据通路的宽度;
       字长等于CPU内部总线宽度、运算器的位数、通用寄存器的宽度,即计算机能直接处理的二进制数据的位数
    字长概念还可以细分为:

    • 机器字长:即一般提到的字长概念,也是CPU单次可以处理的最大数据长度
    • 指令字长:一个指令字中包含的二进制代码的位数
    • 存储字长:一个存储单元存储二进制代码的长度

    字和字长的宽度可以一样,也可以不同
       如x86体系结构,字的宽度都是16位,而IA-32(Intel Architecture 32-bit)的字长为32位;AMD64架构的字长为64位;
       对于MIPS 32体系结构,字与字长都是32位;

    数据通路:指CPU内部数据流经的路径及路径上的部件,主要是CPU内部进行数据运算、存储和传输的部件,这些部件的宽度基本上要一致,才能相互匹配;


    数据量的度量单位

    经常使用的容量单位有B(Byte)、KB、MB、GB、TB,其间换算大小为1024
    通信中的带宽使用的单位有:
      千比特/秒 kb/s、兆比特/秒 Mb/s、千兆比特/秒 Gb/s、兆兆比特/秒 Tb/s,其间换算大小为1000
      同理,千字节/秒 KBps,兆字节/秒 MBps


    数据类型宽度

    在这里插入图片描述

    • 不同机器上同一数据类型的宽度可能不同
    • 为不同数据类型分配的字节数随ISA(指令体系结构)、机器字长和编译器的不同而不同

    数据的存储和排列顺序

    有 int a = 10,a 在计算机中的表示是 0x 00 00 00 0A,占四个字节
    假设 &a 得到结果0x00004725,
    这个地址是变量 a 所占空间的起始位置,及 a 存放在 0x00004725 ~ 0x00004728,
    那么从 0x00004725 ~ 0x00004728,数据存放的顺序是00 00 00 0A 还是 0A 00 00 00呢?
    这两种顺序就是以下两种存储方式

    数据 00 00 00 0A
    大端方式 4725 4726 4727 4728
    小端方式 4728 4727 4726 4725
    有效字节 MSB
    (最高有效字节)
    LSB
    (最低有效字节)

    小端:低位放在低字节 (x86架构)
    大端:低位放在高字节 (MIPS、IBM 360/370等)

    C语言 union 的存放顺序是所有成员从低地址开始,利用该特性来检测CPU的大/小端方式

    int main(){
    	union{
    		int a;
    		char b;
    	}num;
    	num.a = 0x12345678;
    	if(num.b==0x78){
    		printf("小端 num.b=0x%x",num.b);
    	}else{
    		printf("大端 num.b=0x%x",num.b);
    	}
    	return 0;
    }
    

    下表中地址 高 → 低

    变量a 12 34 56 78
    大端方式 变量b
    小端方式 变量b

    大/小端存储方式举例
    假设某机器中,某指令的地址为1000
    该指令的汇编形式为 mov AX,0x12345(BX) ,若操作码mov为40H,
    寄存器 AX 和 BX 的编号分别为0001B和0010B,立即数占32位
    (立即寻址方式指令中给出的数称为立即数)
    则按大/小端存储顺序,有下面两种情况
    在这里插入图片描述
    也就是说,只需要考虑指令中立即数的顺序
    并且可以看出,在内存中,一行指令的存储是由指令地址开始按字节向高地址存放的

    因此,在存放方式不同的机器间进行程序移植或者数据通信时,要注意顺序的转换
    比如音、视频和图像等文件格式或处理程序都涉及到字节顺序问题,其中常见的格式如下:
    小端存储:GIF,PC Paintbrush,Microsoft RTF,
    大端存储:Adobe Photoshop,JPEG,Mac Paint,


    2019/8/2


    2020/3/5 修正规格化数的定义

  • 相关阅读:
    Python遇上嵌入式:几款主流的Python开发板一览!
    shell入门(二):()、(())、[]、[[]]、{}
    Shell入门(一)
    Android Studio打开项目,停在gradle的解决方案
    安装vim中文帮助vimcdoc
    多选框(全选反选)-html
    select框右移-html
    记时器带暂停-html
    浮窗广告html
    js中的dom
  • 原文地址:https://www.cnblogs.com/kafm/p/12721801.html
Copyright © 2020-2023  润新知