实验3 同符号浮点数加法运算/无符号定点数乘法运算的机器级表示
实验序号:3 实验名称:同符号浮点数加法运算/无符号定点数乘法运算的机器级表示
适用专业:软件工程 学 时 数:2学时
一、实验目的
1.掌握定点数乘法溢出的判定方法。
2.掌握浮点数加法的基本运算法则。
3.掌握浮点数规格化方法。
二、实验要求
按照实验题目的要求,编写程序并上机调试
三、实验设备、环境
计算机、Windows 7 、Visual C++ 6.0
四、实验步骤及内容
1.编写浮点数加法器:
设在main中有如下数组:
char float1[33];
char float2[33];
编写函数
float addfloat(char float1[],char float2[],int m,int n);
输出浮点数加法结果,在函数内部要求有保护位和舍入位并通过这两位判定是否舍入。
2.编写无符号整数乘法运算器:
char int1[5];
char int2[5];
编写函数
unsigned mul(char int1[],char int2[],int m,int n);
在运算结束后,将高4位保存在int1中,低4位保存在int2中,返回是否溢出。
提示:
1.乘法运算要求必须编写乘法器,不可以将二进制串先转换为十进制,做乘法运算后再转换为二进制。
2.浮点数加法器应当分为几个函数来写:计算阶码exponent,尾数右移shift,无符号整数加法器add。
3.浮点数加法器的总过程是对阶、尾数相加、右规、舍入
4.注意到尾数共有23位,舍入需要加2位,隐藏的1需要加1位,加法运算有可能进1再加1位,因此尾数用一个27位的数组来表示会大大简化计算难度。
五、讨论、思考题
1、为什么要用浮点数加法运算最多只会右规一次?
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
void removeBlank(char *str) {
char *tmp = str;
int i, j = 0;
for (i = 0; str[i] != '\0'; i++) {
if (str[i] != ' ')
tmp[j++] = str[i];
}
tmp[j] = '\0';
str = tmp;
}
int exponent(int *exponent_ptr) {
int i = 0;
int res = 0;
for (i = 0;i < 8;i ++ )
res += pow(2, i) * exponent_ptr[i];
res -= 127;
return res;
}
int* add(int *arr_1, int *arr_2, int *flag)
{
int i = 0;
int *res = (int *)malloc(100),*result = (int *)malloc(100),*handle_arr_1 = (int *)malloc(100),*handle_arr_2 = (int *)malloc(100);
memset(handle_arr_2, 0, 100);
memset(res, 0, 100); memset(handle_arr_1, 0, 100);
for (i = 0;i < 23;i ++ ) {
handle_arr_1[22 - i] = arr_1[i];
handle_arr_2[22 - i] = arr_2[i];
}
for (i = 0;i < 23;i ++ ) {
res[i + 1] = (res[i] + handle_arr_1[i] + handle_arr_2[i]) / 2;
res[i] = (res[i] + handle_arr_1[i] + handle_arr_2[i]) % 2;
}
if (res[23] == 1)
*flag = 1;
for (i = 0;i < 23;i ++ )
result[22 - i] = res[i];
return result;
}
char* shift(int *shift_ptr, int bytes)
{
int i = 0;
bytes = bytes - 1;
int array[27];
char *res_array = (char *)malloc(100);
memset(res_array, 0, 100);
for (i = 0;i < bytes; i++ )
res_array[i] = '0';
res_array[bytes] = '1';
for (i = bytes + 1;i < bytes + 24;i ++ )
res_array[i] = shift_ptr[i - 1 - bytes] + '0';
return res_array;
}
float addfloat(char float1[], char float2[], int m, int n)
{
int i = 0;
int flag_1 = float1[0] - '0';
int flag_2 = float2[0] - '0';
int exponent_1[8], exponent_2[8];
int final_1[27], final_2[27];
int inf_flag_1 = 0, inf_flag_2 = 0;
for (i = 1;i <= 8;i ++ ) {
exponent_1[8 - i] = float1[i] - '0';
exponent_2[8 - i] = float2[i] - '0';
if (exponent_1[8 - i] == 0) inf_flag_1 = 1;
if (exponent_2[8 - i] == 0) inf_flag_2 = 1;
}
if (inf_flag_1 == 0 || inf_flag_2 == 0 && (float1[0] == '0' && float2[0] == '0')) {
printf("正上溢\n");
return 0;
} else if (inf_flag_1 == 0 || inf_flag_2 == 0 && (float1[0] == '0' && float2[0] == '0')) {
printf("负上溢\n");
return 0;
} else if (inf_flag_1 == 0 || inf_flag_2 == 0 && (float1[0] != float2[0])) {
printf("0\n");
return 0;
}
for (i = 9;i < 32;i ++ ) {
final_1[i - 9] = float1[i] - '0';
final_2[i - 9] = float2[i] - '0';
}
int exponent_res_1 = exponent(exponent_1),exponent_res_2 = exponent(exponent_2);
int flag = 0, sum_integer = 0, exponent = 0;
if (exponent_res_1 > exponent_res_2) {
sum_integer = 1; exponent = exponent_res_1;
char* final_array = shift(final_2, exponent_res_1 - exponent_res_2);
for (i = 0;i < 23;i ++ )
final_2[i] = final_array[i] - '0';
} else if (exponent_res_1 < exponent_res_2) {
sum_integer = 1; exponent = exponent_res_1;
char* final_array = shift(final_1, exponent_res_2 - exponent_res_1);
for (i = 0;i < 23;i ++ )
final_1[i] = final_array[i] - '0';
} else {
sum_integer = 2;
exponent = exponent_res_1;
}
int* array = add(final_1, final_2, &flag);
sum_integer += flag;
float result = 0;
for (i = 0;i < 23;i ++ )
result += pow(2, -i-1) * array[i];
result = (result + sum_integer) * pow(2, exponent);
if (flag_1)
result = -result;
return result;
}
int err_code = -1;
unsigned mul(char int1[], char int2[], int m, int n)
{
int i = 0, j = 0;
int arr_mul_sum[10];
int array_result[10];
int arr_1[5], arr_2[5];
for (i = 0;i < 10;i ++ )
arr_mul_sum[i] = 0, array_result[i] = 0;
for (i = 0;i < 5;i ++ )
arr_1[i] = 0, arr_2[i] = 0;
for (i = 0;i < m;i ++ )
arr_1[m - 1 - i] = int1[i] - '0';
for (i = 0;i < n;i ++ )
arr_2[n - 1 - i] = int2[i] - '0';
for (i = 0;i < 4;i ++ ) {
for (j = 0;j < 4;j ++ )
arr_mul_sum[j + i] += arr_1[i] & arr_2[j];
}
for (i = 0;i < 10;i ++ ) {
arr_mul_sum[i + 1] = arr_mul_sum[i] / 2 + arr_mul_sum[i+1];
arr_mul_sum[i] = arr_mul_sum[i] % 2;}
printf("结果: ");
for (i = 7;i >= 0;i -- ) {
printf("%d", arr_mul_sum[i]);
if(i == 4)
printf(" ");
}
printf("\n");
return 1;
}
int main()
{
char int1[5], int2[5];
char float1[33], float2[33];
//gets(int1);
//gets(int2);
gets(float1);
gets(float2);
removeBlank(float1);
removeBlank(float2);
float res_float = addfloat(float1, float2, strlen(float1), strlen(float2));
printf("%f\n", res_float);
//unsigned int a = mul(int1, int2, strlen(int1), strlen(int2));
return 0;
}
浮点数加法:
无符号数乘法: