计算机32位浮点数编码实验C描述
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
浮点数编码实验
1、提要
本篇讲解浮点数的编码,先介绍浮点数的编码规格,最后用C程序来实现将给定的整数编码转换成浮点数编码。
2、浮点数编码
在计算机中浮点数采用V = (-1)s×M×2E的形式来表示,在计算机中单精度浮点数是32位,双精度浮点数是64位,我们仅仅对单精度浮点数做说明。就单精度浮点数而言,计算机中保存了S,M和E 的编码,其中S表示符号位,0表示正数,1表示负数;M是学名叫尾数;E是阶码,它是指数加上一个偏置数,单精度浮点数的偏置数是127,之所以加上这个偏置数是为了便于浮点数的运算。
在单精度浮点数中,符号位占最高位1位,阶码占用紧接着的8位,尾数占用最后23位,如下图所示:
31 30 22 0 重点说一下尾数M,M隐含了小数点前面的1,举个例子,如果M是1010000000000011110000B,那么M的实际值是1#1010000000000011110000B,其中#表示小数点的位置;然后说说阶码E,假定解码E是10001001B,十进制值位137,E需要再减去偏置127,才能得到指数137-127=10,最后假定S是0,那么这个例子中所描述的浮点数表示的值是:1.1010000000000011110000B × 210也
就是:
11010000000.000011110000B。
3、将一个十进制数转成浮点数表示
举个例子,十进制数-12.75转换成浮点数表示,首先确定符号位是1,将12.75转成二进制表示1100.11B = 1.10011×23,可以确定尾数M是100 1100 0000 0000 0000 0000B,阶码E=3+127 = 130 = 1000 0010B,其浮点数表示为
1#1000 0010#100 1100 0000 0000 0000 0000B =C14C0000H。其中#分割S、E和M。
4、一些非规格浮点数的表示
上面部分说的是浮点数的规格表示,还有一些非规格表示。首先是0的表示,对于0来讲,符号位S是0是1都可以,阶码和尾数全部为0。
+∞和-∞的表示,对于+∞符号位是0表示正,阶码全为1,尾数全部为0,-∞和+∞只有符号不同,因此-∞符号位为1表示负,阶码和尾数与+∞相同全是0。
然后就是非数的表示,非数,就是不是数,符号位忽略,阶码全为1,尾数是非零的数。非数主要用来表示一些非法运算的结果,例如-∞++∞就等于非数。
最后,是阶码全部为0,但是尾数不为0的情况,此时尾数没有隐含的1,也就是原来规格化的数是1.M,现在是0.M,阶码E是-126,再按照浮点数的表示公式V = (-1)s×M×2E来计算浮点数的值。
5、进位
当将一个很大的整数转换成浮点数时,没有办法完全表示整数的有效位,就需要右移来舍掉后面的位数,浮点数的舍入默认采用向最接近的值舍入,此外还需要注意,要向偶数舍入,比如小数位是1/2,是进位还是舍弃,取决于前一位是偶数还是奇数,如果是偶数,就舍弃,是奇数就进位。仍然以一个例子来说明一个数K...XYYY,YYY是要舍掉的数,X是要接受进位的数,如果YYY正好是100B,也就是0.5,我们假定X也Y之间有个小数点,此外0.5是10进制值,是进位还是舍弃取决于X的值,如果X是1(二进制值),就进位,如果X 是0(二进制值)就舍掉,换句话说,当X是偶数时,就舍掉,X是奇数时就进位;如果YYY大于0.5(十进制值),也就是说YYY>100B,那么不管X是什么,都进位,如果YYY<0.5,也就是说YYY<100B,直接舍弃。
6、将一个整数编码转换成浮点数编码
将整数的编码用C语言转换成浮点数的编码,具体的解释会在代码中以注释形式出现。
unsigned float_i2f(int x)
{
unsigned s = 0;
unsigned r = 0;
unsigned e = 0, flag = 0, t;
int c = 0;
//0非规格化表示,直接返回0即可
if (x == 0)
return 0;
if (x < 0)
{
//转换成正整数
//并设置符号位
s = 0x80000000;
r = -x;
}
else r = x; //符号位为0
//确定尾数M,并记录左移的次数为计算阶码做准备while(!(r&0x80000000))
{
r = r<<1;
c = c+1;
}
//此处是进位处理此时r包含尾数的隐含位因此舍弃的正好
//是r的末尾8位,先得到末尾8位的值,如果大于0.5直接进//位,小于0.5直接舍弃,等于0.5时判断前面一位是0还是1,//来决定是否进位
t = r&0xFF;
if (t > 0x80)
flag = 1;
else if (t < 0x80)
flag = 0;
else if (t == 0x80)
if (r&0x100)
flag = 1;
else flag = 0;
//得到尾数,注意包含隐含位
r = r>>8;
//确定阶码为得到尾数将r左右成第31位为1,可以认为小数//点的位置在31位,输入的是整数,小数点在0的位置,而原来//小数点的位置就是31-c就是指数,
e = 31-c+127;
//进位
r = r+flag;
//考虑进位后是否会造成r最高位向左扩展
if(r&0x1000000)
{
r = r>>1;
e = e+1;
}