计算机系统基础(一)笔记——Week2 数据的表示和存储
本文最后更新于:2024年5月25日 凌晨
Week2 数据的表示和存储
2.1 数制和编码
信息的二进制编码
机器级数据分两类:
- 数值数据:无符号整数、带符号整数、浮点数(实数)
- 非数值数据:逻辑数(包括位串)、西文字符、汉字
计算机内部均使用二进制编码
真值和机器数:
- 机器数:用0/1编码的计算机内部的0/1序列
- 真值:真正的值
如unsigned short x=127,机器数是0000 0000 0111 1111
数值数据的表示
确定数值数据首先要确定三个要素:
- 进位计数制
- 十/二/十六/八进制及其转换
- 定/浮点表示
- 定点整数、定点小数
- 浮点数
- 如何用二进制编码(解决正负号)
- 原码、补码、反码、移码
定点数和浮点数
Q:如何表示数值数据中的小数点?
通过约定小数点的位置来表示
- 小数点位置约定在固定位置的数称为定点数
- 小数点位置约定为可浮动的数称为浮点数
定点小数用来表示浮点数的尾数
定点整数用来表示整数,分为带符号/无符号整数
💡 任何实数:,其中,用来决定符号;M是一个二进制定点小数(尾数);E是一个二进制定点整数(阶);R是基数,为2/4/16等。计算机只用这三个数,就确定X,这称为浮点数
2.2 定点数的编码表示
原码表示
0→0000,-0→1000
1→0001,-1→1001
容易理解,但是:
- 0的表示不唯一
- 加减运算方式不统一
- 需额外对符号位处理,不利于硬件设计
- 当a<b时,实现a-b困难
50年代开始,整数部分用补码表示,但尾数用原码定点小数表示
移码表示
即将每一个数值加上一个偏置常数(Excess/bias)
通常,当编码位数为n时,bias取
比如:n=4,bias=8
-8→0000B,-7→0001B,7→1111B
💡 当bias=2^(n-1)时,移码和补码仅第一位不同
移码用来表示浮点数的阶
-
便于加减运算时的对阶操作(比大小)
补码:111(-1)< 011(3)
移码:011(3)<111(7)
补码表示(模运算)
举个例子:模12系统中,-4=8,-3=9,-5=7……
-
一个负数的补码等于模 减去 该负数的绝对值
-
对于模n,数a减去小于n的另一数字b,可以用a加上 -b的补码来代替
10-4=10+(12-4)=10+8=6(mod12)
-
8位二进制加法器模运算系统:
0111 1111-0100 0000=0111 1111+(2^8-0100 0000)
=0111 1111+1100 0000=1 0011 1111(mod2^8)=0011 1111
[x]补=2^n+x(mod 2^n)举个例子:[-1000]补=10000-1000=01000=1000
补码和真值的对应关系
-
特殊数的补码
💡 32位机器中,int、short、char型数据的机器数各占32、16、8位
-
变形补码
双符号位,用来存放可能溢出的中间结果
-
真值求补码
正数补码是其本身
负数补码:各位取反,末位加1(从右往左的遇到的第一个1前面都取反)
-
补码求真值
例子:1101 0110的真值:
简便求法:
符号为0,则为正数,数值部分相同
符号为1,则为负数,数值各位取反,末位加1(从右往左的遇到的第一个1前面都取反)
2.3 C语言中的整数
无符号整数
-
机器中的位排列有两种:高到低从左到右/从右到左
可以用LSB(Least Significant Bit)和MSB标识最低有效位和最高有效位,进行区分
一般高到低采用从左往右
一般全是正数运算采用无符号整数(编码中没有符号位)
带符号整数
用MSB表示数符
用补码表示带符号整数
C语言中无/带符号整数
(unsigned) int/short/long
常在数后面加上’U’/’u’表示无符号数
如果同时有unsigned和signed,C编译器全部转换为unsigned
例子:32位用补码表示的机器上执行以下表达式
32位说明最大整数为2^31-1=2147483648-1=2147483647
表达式 | 结果 | 说明 |
---|---|---|
0==0U | 1 | 00…0B=00…0B |
-1<0 | 1 | 11…11B(-1)<00…00B(0) |
-1<0U | 0 | 11…11B(2^32-1)>00…00B(0) |
2147483647>-2147483647-1 | 1 | 011…1B(2^31-1)>100…0B(-2^31) |
2147483647U>-2147483647-1 | 0 | 011…1B(2^31-1)>100…0B(2^31) |
2147483647>(int)2147483648U | 1 | 011…1B(2^31-1)>100…0B(-2^31) |
-1>-2 | 1 | 11…1B(-1)>11…10B(-2) |
(unsigned)-1>-2 | 1 | 11…1B(2^32-1)>11…10B(2^32-2) |
编译器处理常量默认的范围
C90:
0~2^31-1 | int |
---|---|
2^31~2^32-1 | unsigned int |
2^32~2^63-1 | long long |
2^63~2^64-1 | unsigned long long |
C99:
0~2^31-1 | int |
---|---|
2^31~2^63-1 | long long |
2^63~2^64-1 | unsigned long long |
一些例子:
-
某些32位系统上,-2147483648<2147483647==false
编译器先将-号和2147483648分开,先确定2147483648的类型,C90下解释为unsigned int类型,而右边解释为带符号数,故处理为无符号类型。由于10…0B大于01…1B,结果为false
-
int i=-2147483648,则i<2147483647==true
按int型整数比较,结果为true
-
-2147483647-1<2147483647==true
-号分开处理,而2147483647=2^31-1,处理为int类型
1 |
|
在ISO C90下,结果为
1 |
|
2.4浮点数的编码表示
科学计数法与浮点数
科学计数法表示:,二进制实数表示:
浮点数的表示范围
IEEE 754标准规格化数表示
规格化数:(小数点前总是1,故可隐含表示)
-
单精度
S Exponent Significand 1 bit 8 bits 23 bits -
Sign bit:1为负数,0为正数
-
Exponent:范围为移码0000 0001-1111 1110(-126到127),全0和全1表示特殊值
移码中的偏置常数:单精度为127,双精度为1023
-
Significand:规格化尾数最高位总是1,所以隐含表示,省1位
单精度:1+23bits 双精度:1+52bits
SP:
DP:
-
-
举个例子:float型变量x的机器数是BEE00000H,求x的值?
BEE00000H=1011 1110 1110 0000 0000 0000 0000 0000
=1—01111101—11000000000000000000000
S:1,负数
Exponent:移码125 原码-2
Significand:
SP:
-
举个例子:float型变量x=-12.75,求机器数?
S:1
Exponent:原码3 移码130=1000 0010
Significand:1001 1000 0000 0000 0000 000
PS:1—1000 0010—1001 1000 0000 0000 0000 000=1100 0001 0100 1100 0000 0000 0000 0 000=C14C0000H
IEEE 754标准特殊数表示
-
0的表示
+0:0 00000000 00000000000000000000000
-0: 1 00000000 00000000000000000000000
-
的表示
💡 浮点数除0的结果是,而不是溢出异常
:0 11111111 00000000000000000000000
:1 11111111 00000000000000000000000
-
“非数”的表示
即NAN(Not a number)
Exponent=255,Significand=nonzero
举个例子:0/0=NaN,sqrt(-4.0)=NaN
总结以上内容:
Exponent | Significand | 表示 |
---|---|---|
0 | 0 | 正负0 |
0 | nonzero | 非规格化数 |
1-254 | 任意小数点前隐含1 | 规格化数 |
255 | 0 | 正负无穷 |
255 | nonzero | NaN |
规格化数的范围:
非规格化数的范围:
💡 当输入一个不可表示数时,机器会将其转换为最近的可表示数
2.5 非数值数据的编码表示
逻辑数据的编码表示
逻辑值:关系表达式
表示:用一位表示逻辑值,N位串表示N个逻辑数据
运算:按位进行运算
识别:计算机靠指令识别逻辑数据
西文字符的编码表示
表示: 常用7位ASCII码表示
常见ASCII码:0~9 ⇒ 011 0000~011 1001
汉字及国际字符的编码表示
编码形式:
- 输入码(拼音、微软输入法等):对汉字用相应按键进行编码表示,用于输入
- 内码:用于在系统中进行存储、查找、传送等
- 字模点阵或轮廓描述:描述汉字轮廓,用于显示/打印
多媒体信息的表示
图形由构成图形的直线或曲线的坐标点及控制点来描述/数值数据
2.6 数据宽度和存储容量的信息
数据的基本宽度
bit(比特)→Byte(字节)→word(字)
- 现代计算机中,存储器按字节编址
💡 字字长,字长指CPU内部的数据流经部件 的宽度
小k通常表示1000,大K通常表示1024
2.7 数据存储时的字节排列
对于一个数据比如int型变量x=-10,x的存放地址为100,机器数是FFFFFFF6H,占4个单元
-
变量的地址是最小地址,即x存放在100#~103#
-
多个字节在存储单元中如何存放?
大端/小端方式
举个例子:int i=-65535,存放在100号单元(100~103),访问100号单元取出i时,要清楚其如何存放的。
FF | FF | 00 | 01 | |
---|---|---|---|---|
小端 | 103 | 102 | 101 | 100 |
MSB | LSB | |||
大端 | 100 | 101 | 102 | 103 |
-
大端:MSB所在的地址是数的地址
IBM 360/370,Motorola 68k,MIPS,Sparc,HP PA
-
小端:LSB所在的地址是数的地址
Intel 80*86,DEC VAX
检测系统的字节顺序
union的存放顺序是所有成员从低地址开始。
1 |
|
举个例子:
以下是由反汇编器生成的针对IA-32处理器的机器级代码表示文本
1 |
|
其中80483d2
是指令地址,89 85 a0 fe ff ff
是机器指令,mov %eax,0xfffffea0 (%ebp)
是汇编指令,0xfffffea0
是立即数
-
请问
0xfffffea0
的值和存放地址?IA-32是大端还是小端方式?存放地址为0x80483d4,值为=-101100000B=-352,小端方式
字节交换问题
大小端转换时涉及到字节顺序问题