计算机系统基础:实验3

计算机系统基础:实验3 同符号浮点数加法运算/无符号定点数乘法运算的机器级表示

提示:根据《计算机系统基础》 中给出的解释来解决更容易,看一下p73页能更简单理解

题目要求:

  1. 能够用C语言仿真浮点数加法器的运算过程
  2. 能够用C语言仿真无符号数乘法器的运算过程

 #include <stdio.h>
#include <stdlib.h>
float addfloat(char float1[], char float2[], int m, int n);
unsigned mul(char int1[], char int2[], int m, int n);
float floatToValue(char binary[],int count);//浮点数的10进制转换
int calExponent(char float1[], char float2[]);//对阶
int shiftRight(char wei1_re[]);// 计算右规
void unsignedAdd(char wei1[],char wei2[],char wei_re[]);//计算无符号数相加

int main(){
     // 浮点数加法器
//    char float1[33];
//    char float2[33];
//    printf("浮点数:\n");
//    fgets(float1,33,stdin);
//    scanf("\n");
//    fgets(float2,33,stdin);
//    int m = 0,n = 0;
//    float result = addfloat(float1,float2,m,n);
//    printf("结果为:%f \n",result);
    //无符号整数乘法
    char int1[5];
    char int2[5];
    printf("乘法:\n");
    fgets(int1,5,stdin);
    scanf("\n");
    fgets(int2,5,stdin);
    int m = 0,n = 0;
    
    mul(int1, int2,m,n);

    return 0;
}

float addfloat(char float1[], char float2[], int m, int n){
    char wei1[27],wei2[27],wei_re[27],result[32];;
    int i;
    for(i=0;i<27;i++){
        wei1[i] = '0';
        wei2[i] = '0';
        wei_re[i] = '0';
    }
    
    int move = calExponent(float1, float2);
        //尾数加减
        if(move<0){
            //move = -move;
            int t;
            //27位中第零位不取数字,用作进位
            //第二位为隐藏位,必为‘1’
            wei1[-move+1] = '1';
            wei2[1] = '1';
            //之后的的23位为尾数的小数值
            for(t=9;t<32;t++){
                wei1[t-7-move] = float1[t];
                wei2[t-7] = float2[t];
            }
            unsignedAdd(wei1, wei2, wei_re);
            //右规
            int count = shiftRight(wei_re);
            //计算最终值
            for (i = 0; i<32; i++) {
                if(i<9){
                    result[i] = float2[i];
                }
                else{
                    result[i] = wei_re[i-7];//结果尾数的从第2位开始 第0位是右规 第1位是隐藏位
                }
            }
           
            return floatToValue(result,count);
        }
        else{
            int t;
            //27位中第零位不取数字,用作进位
            //第二位为隐藏位,必为‘1’
            wei2[move+1] = '1';
            wei1[1] = '1';
            //之后的的23位为尾数的小数值
            for(t=9;t<32;t++){
                wei2[t-7+move] = float2[t];
                wei1[t-7] = float1[t];
            }
            unsignedAdd(wei2, wei1, wei_re);
            //右规
            int count = shiftRight(wei_re);
            //计算最终值
            for (i = 0; i<32; i++) {
                if(i<9){
                    result[i] = float1[i];
                }
                else{
                    result[i] = wei_re[i-7];//结果尾数的从第2位开始 第0位是右规 第1位是隐藏位
                }
            }
           
            return floatToValue(result,count);
        }
}
//计算阶码
int calExponent(char float1[], char float2[]){
    int count=0,i,j,e1=0,e2=0;
    char temp[9];
    temp[0] = '0';
    //对阶 float1的阶码-float2的阶码
    for(i = 8; i >= 1; i--) {
        if(count){
            temp[i] = float2[i]=='1' ? '0':'1';
        }
        if(float2[i]!='0'&& count == 0){
            temp[i] = float2[i];
            count++;
        }
        
    }
        for(j=1;j<9;j++){
            if(float1[j]=='1') {
                e1 = e1 + (1<<(8-j));
            }
            if(temp[j]=='1') {
                e2 = e2 + (1<<(8-j));
            }
        }
        
        return e1+e2-256;
}
//尾数右移
int shiftRight(char wei_re[]){
    //右规
    int count = 0;
    if (wei_re[0] == '1') {
        int i;
        count++;
        char temp[27];
        for (i=0; i<27; i++) {
            temp[i] = wei_re[i];
        }
        wei_re[0] = '0';
        for (i = 1; i<27; i++) {
            wei_re[i] = i==0 ? 0:temp[i-1];
        }
    }
    if(wei_re[26]=='1'){
        if(wei_re[25]=='1'){
            int t;
            for (t = 24; t>=0; t++) {
                if(wei_re[t]!='1'){
                    wei_re[t] = '1';
                    break;
                }
                wei_re[t] = '0';
            }
        }
        else {
            if(wei_re[24]=='1'){
                int v;
                for (v = 23; v>=0; v++) {
                    if(wei_re[v]!='1'){
                        wei_re[v] = '1';
                        break;
                    }
                    wei_re[v] = '0';
                }
            }
        }
    }
    return count;
    
}
//无符号数增加
void unsignedAdd(char wei1[],char wei2[],char wei_re[]){
    char carr='0';
    int j;
    for(j=26;j>=1;j--){
        if(wei1[j] == '1'&&wei2[j] == '1'){
            if(carr=='1'){
                wei_re[j]='1';
            }else{
                wei_re[j]='0';
            }
            carr='1';
        }else if (wei1[j] == '0'&&wei2[j] == '0'){
            if(carr=='1'){
                wei_re[j]='1';
            }else{
                wei_re[j]='0';
            }
            carr='0';
        }else {
            if(carr=='1'){
                wei_re[j]='0';
            }else{
                wei_re[j]='1';
            }
        }
    }
    //此处判断结果尾数是否需要进位
    if(carr=='1'){
        wei_re[0] = '1';
    }
}
//浮点数转10进制
float floatToValue(char binary[],int count){
        float sum = 0;
        int exponent = 0;
        int symbol = 1;
        float significand = 0;
        if(binary[0]=='1') {
            symbol = -1;//符号位
        }
        for(int i = 1; i < 9; i++) {
            if(binary[i]=='1') {
                exponent = exponent + (1<<(8-i));
            }
        }
    //此处判断是否存在右规行为 有的话阶码加一 没有的话照旧
    exponent = count<=0 ? exponent - 127:exponent - 126 ;//所得阶码减去偏移量
        if(exponent>=0) {
            significand = 1<<exponent;
            for(int i = 9; i < 32; i++) {
                if(binary[i]=='1') {
                    //此处计算小数点前的位数
                    if(exponent > i-9){
                        significand = significand + (1<<(exponent-(i-8)));
                    }else{
                    //此处计算小数点后的位数
                        significand = significand + (1.0/(1<<(i-exponent-8)));
                    }
                }
            }
            sum = significand * symbol;
        } else {
            for(int i = 9; i < 32; i++) {
                if(binary[i]=='1') {
                    significand = significand + (1.0/(1<<(exponent+i-8)));
                }
                sum = significand * symbol;
            }
        }
        if((exponent==128)&&(significand==0)) {
            printf("无穷大\n");
            return (1.0/0.0);//表示无穷
        }
        if((exponent==128)&&(significand!=0)) {
            printf("非规格化数正上溢\n");
            return (0.0/0.0);//不是一个数字
        }
        if((exponent==-127)&&(significand!=0)) {
            printf("非规格化数正下溢\n");
            return 0;
        }
        return sum;
}
//无符号整数乘法
unsigned mul(char int1[], char int2[], int m, int n){
    char result[9];
    for (m = 0; m<9; m++) {
        result[m] = '0';
    }
    int count = 8;
    char cin = '0';
    for (n = 3; n>0; n--) {
        if(int2[n]!='0'){
            int i,j = count;
            for(i = 3 ;i>=0;i--){
                if(int1[i] == result[j]){
                    char temp = result[j];
                    result[j] = cin!='0' ? '1':'0';
                    cin = temp!='0' ? '1':'0';
                }else{
                    result[j] = cin!='0' ? '0':'1';
                    cin = result[j] !='0' ? '0':'1';
                }
                j--;
            }
        }
        count--;
    }
    printf("结果为:");
    for (n = 1; n<9; n++) {
        printf("%c",result[n]);
        if (n==4) {
            printf(" ");
        }
    }
    return 0;
}



   

测试举例:

测试用例1
测试用例2
测试用例3测试用例4

总结:

秘诀:一定要看书,一定要看书!!
那什么我C语言基础比较差,所以这个整了一周才完成,但是还是很有成就感的,哈哈哈哈哈哈,加油各位!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值