#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define Bias 15
#define Max pow(2, 16)
#define Min pow(2, -14)
//使用struct存放浮点格式数据(以半精度浮点数为例)
struct Float
{
int S;
int expo[5];
int mant[10];
};
//将输入的浮点数转化为浮点格式数据
void getFloat_num(float a, struct Float* pFl)
{
float b = a;
int expo = 0;
int i = 0;
if (a < 0)
{
pFl -> S = 1;
b = -b;
}
else
pFl -> S = 0;
while (b < 1)
{
b *= 2;
--expo;
}
while (b >= 2)
{
b /= 2;
++expo;
}
i = 5;
expo += Bias;
while (i > 0)
{
if (expo > 0) {
pFl -> expo[i - 1] = expo % 2;
expo /= 2;
} else {
pFl -> expo[i - 1] = 0;
}
--i;
}
i = 0;
--b;
while (i < 10)
{
b *= 2;
if (b >= 1)
{
--b;
pFl -> mant[i] = 1;
} else {
pFl -> mant[i] = 0;
}
++i;
}
}
//获取浮点格式数据的指数
int getFloat_exp(struct Float f)
{
int i = 0;
int ans = 0;
while (i < 5)
{
ans = ans * 2 + f.expo[i];
++i;
}
ans -= Bias;
return ans;
}
//获取浮点格式数据的小数
float getFloat_fraction(struct Float a)
{
int i = 0;
float ans = 1;
while (i < 10)
{
ans = ans * 2 + a.mant[i];
++i;
}
return ans;
}
//以浮点格式数据输出
void printFloat(struct Float f)
{
char fl[19];
int j = 0, i = 0;
fl[0] = f.S + '0';
fl[1] = '_';
j = 2;
while (j < 17)
{
fl[j] = f.expo[j - 2] + '0';
++j;
}
fl[7] = '_';
i = 8;
while (i < 18)
{
fl[i] = f.mant[i - 8] + '0';
++i;
}
fl[18] = '\0';
printf("%s\n", fl);
}
//浮点结构加法
void F_add(struct Float a, struct Float b)
{
struct Float answer;
float aFrac, bFrac;
int aExp, bExp;
int i = 0, j = 0;
float answer_fl;
aFrac = getFloat_fraction(a);
bFrac = getFloat_fraction(b);
aExp = getFloat_exp(a);
bExp = getFloat_exp(b);
answer_fl = pow(-1, a.S)*aFrac * pow(2, aExp - 10) + pow(-1, b.S)*bFrac * pow(2, bExp - 10);
if(fabs(answer_fl)>=Max | fabs(answer_fl)<Min)
{
printf("Error!\n");
}
else
{
getFloat_num(answer_fl, &answer);
printf("%f\n", answer_fl);
printFloat(answer);
}
}
//浮点结构减法
void F_sub(struct Float a, struct Float b)
{
b.S ^= 1;
F_add(a, b);
}
//浮点结构乘法
void F_mul(struct Float a, struct Float b)
{
struct Float answer;
float aFrac, bFrac;
int aExp, bExp, i;
float answer_fl;
aFrac = getFloat_fraction(a);
bFrac = getFloat_fraction(b);
aExp = getFloat_exp(a);
bExp = getFloat_exp(b);
i = 0;
while (i < abs(aExp - 10))
{
if (aExp > 10)
aFrac *= 2;
else aFrac /= 2;
++i;
}
i = 0;
while (i < abs(bExp - 10))
{
if (bExp > 23)
bFrac *= 2;
else bFrac /= 2;
++i;
}
answer_fl = pow(-1, a.S)*pow(-1, b.S)*aFrac * bFrac;
if(fabs(answer_fl)>=Max | fabs(answer_fl)<Min)
{
printf("Error!\n");
}
else
{
getFloat_num(answer_fl, &answer);
printf("%f\n", answer_fl);
printFloat(answer);
}
}
//浮点结构除法
void F_div(struct Float a, struct Float b)
{
struct Float answer;
float aFrac, bFrac;
int aExp, bExp, i;
float answer_fl;
aFrac = getFloat_fraction(a);
bFrac = getFloat_fraction(b);
aExp = getFloat_exp(a);
bExp = getFloat_exp(b);
answer_fl = pow(-1, a.S)*pow(-1, b.S) * (float)pow(2, aExp - bExp)*aFrac / bFrac;
if(fabs(answer_fl)>=Max | fabs(answer_fl)<Min)
{
printf("Error!\n");
}
else
{
getFloat_num(answer_fl, &answer);
printf("%f\n", answer_fl);
printFloat(answer);
}
}
//以半精度浮点数的运算为例
int main()
{
float a,b;
struct Float a_f;
struct Float b_f;
struct Float ans_f;
printf("请输入浮点数1:\n");
scanf("%f", &a);
while(1)
{
if(abs(a)>=Max | abs(a)<Min)
{
printf("Error!\n请重新输入:\n");
scanf("%f", &a);
if(abs(a) < Max & abs(a) >= Min)
break;
}
else
break;
}
printf("%f\n", a);
printf("请输入浮点数2:\n");
scanf("%f", &b);
while(1)
{
if(abs(b)>=Max | abs(b)<Min)
{
printf("Error!\n请重新输入:\n");
scanf("%f", &b);
if(abs(b) < Max & abs(a) >= Min)
break;
}
else
break;
}
printf("%f\n", b);
printf("\n浮点数1转化为浮点格式数据:\n");
getFloat_num(a, &a_f);
printFloat(a_f);
printf("浮点数2转化为浮点格式数据:\n");
getFloat_num(b, &b_f);
printFloat(b_f);
printf("\n两数以浮点格式相加结果:\n");
F_add(a_f, b_f);
printf("\n两数以浮点格式相减结果:\n");
F_sub(a_f, b_f);
printf("\n两数以浮点格式相乘结果:\n");
F_mul(a_f, b_f);
printf("\n两数以浮点格式相除结果:\n");
F_div(a_f, b_f);
system("pause");
return 0;
}