定点数的表示
重点,难点
无符号数:整个机器字长的全部二进制位均为数值位,没有符号位,相当于数的绝对值。
1001 1100B
寄存器的长度直接反映出了无符号数的表示范围。
表示范围:
8位二进制数:2的8次方种不同状态
0000 0000 ~ 1111 1111 = 1 0000 0000 - 1
0~255=2^8 - 1
有符号数:
+156D = 0 1001 1100B
-156D = 1 1001 1100B
真值 机器数
小数点怎么办?
没有专门硬件表示小数点。按约定来表示的
小数点:隐含存储(定点数:事先约定;浮点数:按规则浮动)
原码
有符号数:
- 原码表示法
- 补码表示法
- 反码表示法
- 移码表示法
原码:
符号+真值
如果是负数的话,前面多一个1,所以有2的n次方
2的n次方减去真值(因为是负值)部分。
实际上就是绝对值 + 1或者0
纯小数
原码的特点:简单、直观
补码
原码在加减的情况会出现问题
如何把减法统一成加法?
时钟,模12
补数:
一个负数加上“模”即得到该负数的补数
补码:
对于正数,补码与原码的表示相同
对于负数,原码符号位不变,数值部分按位取反,末位加1(取反加一)
小数还是纯小数
反码
对于正数,反码与原码的表示相同
对于负数,原码符号位不变,数值部分按位取反。
表示范围:原码一样
原补反相互转换
最高位为符号位,书写上用“,”(整数)或“.”(小数)将数值部分和符号位隔开。
对于正数,原码=补码=反码
对于负数,符号位为1,其数值部分
原码除符号位外每位取反末位加1->补码
原码除符号位外每位取反->反码
移码
用来干啥的?
补码是很难表示真值的大小的。
移码就是在真值X上加上一个常数(偏置值),通常这个常数去2的n次方。
只有整数才有移码
定点数的运算
- 移位运算
- 加减
- 溢出判断
- 乘除
- 强制类型转换
移位运算
左移:绝对值扩大
右移:绝对值缩小
和加减法结合实现了乘除法
算术移位:机器码采用有符号数
符号位不参与移位
正数:原码、补码、反码都一样->左移右移都补0
负数:反码1,原码0,补码左移0右移1
原码算术移位:左移丢1,运算出错;右移丢1,影响精度。
逻辑移位
机器数采用无符号数:逻辑移位
逻辑左移时,高位移丢,低位添0
逻辑右移时,低位移丢,高位添0
循环移位(了解即可)
最高位添到最低位。
加减运算
补码:两个有符号数可以直接相加,不需要分类讨论
加减法的基本思路:
- 转化为x+y的形式
- 计算两个补码的相加
做题。
符号扩展
-B的补码:连通符号位一起取反
-c的补码:连同符号位一起取反。
溢出判断
如何判断溢出?
一:
两个整数相加,符号位变成1
两个负数相加,符号位变成0
逻辑表达式
与:如ABC,表示A与B与C,仅当A、B、C均为1时,ABC为1,A、B、C中有一个或多个为0,则ABC为0
或:如A+B+C,表示A或B或C,仅当A、B、C均为0时,A+B+C为0,ABC中有一个或多个是1,则A+B+C为1
非:如Abar,表示A非,取反。
二:
采用一位符号位。根据数据位进位情况判断溢出
三:
采用双符号位
正数符号为00,负数符号为11
乘法运算(了解过程)
直接做题。
原码一位乘法
计算机用两个寄存器(累加器(保存机器字长),乘商寄存器(保存乘数的绝对值))
初始累加器里的值000000.
乘商寄存器最右边那个数字是1,则竖式+x
如果是0,就+00000,竖式不变
做一次操作写进累加器里,然后竖式里、ACC、MQ右移一位。
一直从MQ里移出来的值变成乘数后,结束。
ACC和MQ里全部就是结果
补码一位乘法
Booth算法。原理不需要掌握。
第一步,先求出补码。用两位符号位
乘法运算回顾:
除法运算(了解过程)
符号位和数值位分开处理
笔算:
原码恢复余数法
符号位数值位分开处理
首先把绝对值写出来,在写出y绝对值补码,y的绝对值相反数的补码
加上y的y的绝对值相反数的补码,判断是不是大于y的
不是商0,是商1,左移
原码不恢复余数法
若余数为负数,
需要加回。
补码加减交替法
先求出补码和负数的补码(原码是要求绝对值的补码)
被除数和除数同号,则被除数减去除数;异号则被除数加上除数。
余数和除数同号,商1,余数左移一位减去除数;
余数和除数异号,商0,余数左移一位加上除数。
重复n次。
末尾恒置1
除法运算总结回顾
用十进制算不香嘛?
强制类型转换
无符号数与有符号数:不改变数据内容,改变解释方式
short x = -4321; //short占用2个字节
unsigned short y = (unsigned short)x;
x: 1110 1111 0001 1111
y:1110 11110001 1111——真值:61215
长整数变短整数:高位截断,保留地位。
int a = 165537,b=-34991; //int占用4个字节
short c = (short)a, d = (short)b;
a:0x000286a1
c:0x86a1——真值-31071
b:0xffff7751
d:0x7751——真值30545
短整数变长整数:符号拓展
short x = -4321;
int m = x;
unsigned short n = (unsigned short)x;
unsigned int p = n;
x:1110 1111 0001 1111
m:1111 1111 1111 1111 1110 1111 0001 1111——真值-4321
n:1110 1111 0001 1111——真值61215
p:0000 0000 0000 0000 1110 1111 0001 1111——真值61215