计算机组成原理作业第二题
题目如下
编写C语言函数,利用位运算,实现如下类型转的功能:
//1、short到int类型转换。
//2、int到short类型转换。返回的信息由两部分组成:转换后的值、是否正确转换。
//提示:参数为const int和short *,返回值为int,如能正确转换返回0,否则返回-1。或参数只有一个int类型,返回一个自定义的结构体类型。
//3、将int型参数x、y看做32位移码,试比较它们的大小,若x>y,返回1;x=y,返回0;x<y,返回-1。
//提示:由于移码的单调递增性,移码x、y比较大小时,可以从最高位开始逐位进行比较,在第一个不同位上,哪个变量该位为1,则该变量对应真值较大。例如:
//[x]移=00100000
//[y]移=00110000
//从第7位开始,第7、6、5位均相同,第4位不同,y的第4位为1,则[y]真值较大。/
//4、参数为float类型,返回其二进制存储格式。
//5、输入为任意32位二进制,将其看做float类型的存储格式,输出其对应的值。需要处理非数。
//6、float类型转换为int类型,舍弃小数部分,需要处理超出int表示范围的情形。
//7、int类型转为为float类型。
//8、float类型转换为double类型。
主要思路:利用float,int,double等数据在计算机内保存的格式,
合理使用指针进行互相转换。
以第一题short到int类型转换的代码为例
short n,*p;
int *pi,m,f;//f指符号位
printf("请输入一个short数\n");
scanf("%d",&n);
p=&n;
pi=p;
m=*pi;//
此处不能直接转换,使用指针作中介,把short的数据复制到int型的数据里面
此处要注意数据是负数的时候 在计算机内存储的格式是反码
f=(m>>15)&1;
if(f)//如果符号位是1 负数 储存反码 高位全为1
m|=0xffff0000;
else
m&=0x0000ffff;
printf("转换结果=%0#10x\n",m);
附:浮点数IEEE754标准储存格式
了解浮点数的储存格式对完成后面的题目十分重要
一个32位浮点数,以(-1)s X(1.m)X2E-127的形式表示
S是符号位 0正数 1负数
M代表尾数
e代表次数
E=e+127
(课本22页有详细解释)
存储的格式如下图
31 | 30–23 | 22-0 |
---|---|---|
S | E | M |
进行格式转换时,要依据储存的格式处理数据,合理利用位运算和指针。
下面展示 代码
。
#include <stdio.h>
#include <stdlib.h>
void fun1()
{
short n,*p;
int *pi,m,f;//f指符号位
printf("请输入一个short数\n");
scanf("%d",&n);
p=&n;
pi=p;
m=*pi;//不能直接转换,使用指针作中介复制到int型里面
f=(m>>15)&1;
if(f)//如果符号位是1 负数 储存反码 高位全为1
m|=0xffff0000;
else
m&=0x0000ffff;
printf("转换结果=%0#10x\n",m);
return 0;
}
int fun2(int x)
{
short n,*p;
int *pi,s;
if(x>32767||x<=-32768)
printf("error\n");
else
{
pi=&x;
p=pi;
n=*p;
return n;
} if(x==0)
printf("x=y\n");
return 0;
}
int fun3(int x,int y)
{
int m,n,i;
for(i=31;i>=0;i--)
{
if((x>>i&1)==(y>>i&1)) //循环比较x,y的最高位,当相同时不做任何事
;
else if((x>>i&1)>(y>>i&1))//如果x最高位为1y为0,x>y
return 1;
else if((x>>i)<(y>>i) ) //如果x先出现0,y出现1,x<y
return -1;
}
return 0;//循环32次 xy都相同,则x==y
}
int fun4(float b)
{
int x,*px;
float y,*py;
py=&b;
px=py;
x=*px;
printf("the result=%0#10x\n",x);
return 0;
}
void fun5()
{
int x,m,e,*ip;
float *p,n;
printf("请输入八位十六进制数");
scanf("%x",&x);
e=(x>>23)&0x000000ff; //阶码保存位 23-30
m=x&0x007fffff; //尾数0-22
if(e==255&&m!=0)
printf("error\n");//是无穷或者0
else
{
ip=&x;p=ip;n=*p;
printf("阶码=:%x\t数=:%x\n",e,m);
printf("真值=:%f\n",n);
}
return 0;
}
void fun6()
{
float x,*pi;
int e,m,s,y,*p;
printf("请输入float x=\n");
scanf("%f",&x);
if(x>2147483648||x<=-2147483649)
printf("error\n");//溢出
else
{
pi=&x;
p=pi;
*p=y;
// 经典换到y里面
m=y&0x007fffff ; //0000 0000 0111 1111 1111 1111 1111 1111取低23位尾数
m&=0x00800000 ; //m左侧隐藏的1补上
e=(y>>23)&0x000000ff-127; //E=e+127
if((y>>31)==1)// 符号位为1,负数
{
y=((m<<23)>>e);
y=-y;
}
else
y=((m<<23)>>e);
printf("y=%d\n",y);
}
}
void fun7()
{
int x,*px,e=0,m,f,h=0,hl,dl,k,z,i;//e次数 m'尾数 f符号位,E=e+127,h存放合成后的数
float y,*py;
printf("请输入int x=\n");
scanf("%d",&x);
f=((x>>31)&0x00000001);//取符号位
if(f==1)
x=(x^0x7fffffff)+1; //如果符号位1,取补码
m=x;
k=x<<1;
//尾数m
for(i=0;i<32;i++)
{
if((k&0x00000001)==0)//当最低位是0,dl++
{
k=k>>1;
dl++;
}
else
i=32;//跳出循环
}
k=x;
for(i=0;i<32;i++)
{
if((x&0x80000000)==0)//当最高位是0,hl+
{
k=k<<1;
hl++;
}
else
i=32;
}
e=31-dl-hl-1+127; //尾数的有效位
printf("阶码=%d\n",e);
e=e<<23;
while(!(m&0x80000000))
m=m<<1;
m=m<<1;
m=m>>9;
m=m&0x007fffff;
x=m|e;
px=&x;
py=px;
y=*py;
printf("float=:%f\n",y);
}
void fun8()
{
float x,*ip;
double *dp,z;
long long *p,y,e,m;
printf("请输入一个float x:");
scanf("%f",&x);
ip=&x;p=ip;y=*p;
y=y&0x00000000ffffffff;
e=(y>>23)&0x0000000ff;
e=(e-127+1023)<<52;
m=(y&0x7fffff)<<29;
y=e|m;
if(x<0)y=y|0x8000000000000000;
p=&y;dp=p;z=*dp;
printf("double=%lf\n",z);
}
int main()
{
int m,n;//x:输入的x值,m用于输出赋值,n用于选择题号
printf("请输入题号1-7\n");
scanf("%d",&n);
switch(n)
{
case 1:
fun1();
break;
case(2):
{
int x;
printf("请输入int型x\n");
scanf("%d",&x);
m= fun2(x);
if(m=0)
printf("error\n");
else
printf("%0#10x",m);
}
break;
case(3):
{
int x,y;
printf(":请输入x");
scanf("%d",x);
m=fun3(x,y);
if(m==1)
printf("x>y\n");
if(m==0)
printf("x=y\n");
if(m==-1)
printf("x<y\n");
}
break;
case(4):
{
float b;
printf("请输入float型b");
scanf("%f",b);
fun4(b);
}
break;
case(5):
{
fun5();
}
break;
case(6):
{
fun6();
}
break;
case(7):
{
fun7();
}
break;
case(8):
{
fun8();
}
break;
}
return 0;
}