深入理解计算机系统homework2 2.85 2.93 2.95
2013-09-20 12:49
148 查看
2.85 最小的正非规格化数 值:2^(-63) * (2^(2-2^15)) = 2^(-16445) 十进制值: 最小的正规格化数 值:1*2^(2-2^15) = 2^(-16382) 十进制值: 最大的规格化数: 值:(2-2^(-63))* 2^(2^14) = (2-2^(-63))*2^16384 2.93 【分析】 如果exp上全是1则该数是无穷大或者NaN,只需要异或一下判断全1即可。 否则如果exp大于0,那么我们在exp上减去一即可,但是如果exp被减成0了,因为exp不等于0,默认小数点前是1,那么我们就要把小数点前的1给补回去,然后做整体右移一位。如果exp原来是0,整体右移一位即可。 最后考虑向偶数进位,如果原数f末尾两位是11,则需要最后结果在尾数上加一。float_bits float_half(float_bits f) { unsigned exp = f & 0x7F800000;//取出阶码 unsigned sign = f & 0x80000000;//取出符号位 unsigned frac = f & 0x7fffff;// 取出尾数 // 判断f的最后是否是3考虑向偶数进位 unsigned round = ( ( f >> 1 ) & f) & 1; if (exp ^ 0x7F800000) // f不死NAN 或者 无穷大 { if (exp) { exp = ( (exp >> 0x17) + ~0 ) << 0x17;//阶码减一 if ( ! exp ) frac = frac + (1 << 0x17 ); // 向后退1,正数前面默认为1. } if (!exp) frac = ( frac >> 1 )+ round; } return sign | exp | frac; }
2.95为了放在word中,缩进了一些代码【分析】将int转化成float,首先考虑符号位,然后讲i取绝对值,当成一个正数转化即可。然后判断i是2的几次幂,可以通过类似于二分法的方式判断。即右移16位判断是否不为0,如果不为0则exp+16,然后判断右移16位后剩余的位数有几位,否则右移8位判断依次类推。然后因为是正数,小数点左边存在一个隐式的1,所以num=( ~ (1<< exp ) ) & num ;把最高的1去掉,然后把剩余的数放进frac中,同时要考虑向偶数取整的问题。如果num不足23位,直接移动相应位数,放入frac中,否则截掉多余的位数,如果最后一位并且舍去一段中的最高也为1或者舍去的东西超过0.5那么就给frac+1,判断一下frac时候有溢出,溢出的话给exp+1,然后取剩余的23位的值即可。最后就是给exp加上bias偏置值,前提是如果num不为0。[code]float_bits float_i2f(int i)
{
unsigned sign = i >>0x1F;
unsigned num = i;
if (sign & 0x1)
num = ~num + 1; // 求绝对值
//printf("%x\n",num);
unsigned temp = num;
unsigned exp = 0;
unsigned frac = 0;
if(num >> 16) {
exp= exp + 0x10; num = num >> 0x10;//printf("%x%x\n",exp,num);
}
if(num>>8) {
exp= exp + 0x8; num = num >> 0x8;//printf("%x %x\n",exp,num);
}
if(num>>4) {
exp= exp + 0x4; num = num >> 0x4;//printf("%x %x\n",exp,num);
}
if(num>>2) {
exp= exp + 0x2; num = num >> 0x2;//printf("%x %x\n",exp,num);
}
if(num>>1) {
exp= exp + 0x1; num = num >> 0x1;//printf("%x %x\n",exp,num);
}
//正数小数点前的1需要去掉(即最高位的1去掉)
num = temp;
num=( ~ (1<< exp ) ) & num ;
//printf("num=%x\n",num);
if (temp >> 23) // 如果num超过了23位
{
unsigned delta = exp - 0x17;
frac = num >> delta;
//printf("%x %x\n",delta,frac);
unsigned round = 0;
int Cond1 = ( ( num & ((1 << delta) -1 ) ) > (1 << (delta-1)) );
int Cond2 = (frac & 0x1) && ( num >> (delta -1) & 0x1);
//printf("cond%d %d\n",Cond1,Cond2);
if( (exp != 0x17) & ( Cond1 | Cond2) )
// exp 不等于23 判断舍去后是否需要向偶数进位
{
round = 1;
frac = frac + round;
//printf("round-frac%x\n",frac);
if (frac >> 0x17)
{
exp +=1;
frac = frac & 0x7fffff;
}
}
//printf("frac=%x\n",frac);
} else
frac = num << (0x17 - exp ) ;
//printf("exp=%x\n",exp);
if (temp)
exp = exp + 127; // 加上bias偏置值
//printf("%x %x %x %x\n", num , sign,exp,frac);
return ( sign << 0x1F ) | ( exp << 0x17 ) | frac;
}
[/code]
相关文章推荐
- 深入理解计算机系统homework3 3.55 3.56 3.58 3.59 3.60
- 深入理解计算机系统 家庭作业 2.93
- 深入理解计算机系统_3e 第五章家庭作业 CS:APP3e chapter 5 homework
- 【深入理解计算机系统-第二版】第二章部分家庭作业(Homework)参考答案
- 深入理解计算机系统_3e 第十章家庭作业 CS:APP3e chapter 10 homework
- 深入理解计算机系统_3e 第二章家庭作业 CS:APP3e chapter 2 homework
- 深入理解计算机系统_3e 第八章家庭作业 CS:APP3e chapter 8 homework
- 深入理解计算机系统_3e 第三章家庭作业 CS:APP3e chapter 3 homework
- 深入理解计算机系统_3e 第四章家庭作业(部分) CS:APP3e chapter 4 homework
- 深入理解计算机系统_3e 第十一章家庭作业 CS:APP3e chapter 11 homework
- 深入理解计算机系统_3e 第六章家庭作业 CS:APP3e chapter 6 homework
- 深入理解计算机系统_3e 第七章家庭作业 CS:APP3e chapter 7 homework
- 深入理解计算机系统--虚拟存储器
- 深入理解计算机系统(1.2)---hello world的程序是如何运行的
- CS:APP3e 深入理解计算机系统_3e ShellLab(tsh)实验
- 深入理解计算机系统 1.6 存储设备形成层次结构
- 深入理解计算机系统 笔记1 计算机系统漫游
- 读完了csapp(中文名:深入理解计算机系统)
- 深入理解计算机系统2_信息存储(读书笔记)