定点机二进制数加减乘除法的C语言实现

main函数是空的,内容都被写进各个子函数里。在这里稍微说一下各个运算的原理:

加法:

写了三种加法,分别是严格格式(bin_plus_limit),右对齐(bin_plus_right),和左对齐(bin_plus_left)。只有严格格式有溢出检测。加法的原理都是最基础的进位。

减法:

即对减数B补码做加法。调用的是右对齐加法。
加减法不分原码或补码。

乘法(原码):
  1. 先初始化一个部分积S,长度为输入码长的2倍。
    部分积前半部分为0,后半部分为乘数B。

假设被乘数A=001011,被乘数B=000101
在这里插入图片描述

  1. 进入循环:
    观察S的最后一位
  • 如果是1,则先给S左对齐地加上A,再将S右移1位。
  • 如果是0,则单纯将S右移1位。

在这里插入图片描述

  1. 当部分积S中整个B都向右移干净时,循环过程结束。

在这里插入图片描述
最后应指出,符号位独立于数值计算。做一个异号得负同号得正的判断即可。

乘法(补码):

乘法的补码运算本质上和原码是一样的,但是在循环判别上稍稍复杂了一点。本算法即Booth算法。

  1. 对被乘数A和乘数B都要进行一些处理。
  • 如果A符号位只有1位,需要拓展为2位符号位
  • B末尾必须加一位0(必需)
  • 计算出-A的补码
  1. (与原码乘法相同)初始化一个前部分为0,后部分为B的部分积S

在这里插入图片描述

  1. 进入循环:
  • 如果S[bit-1]-S[bit-2]==-1
    (这里bit指的是S合并后的总位数,并不是给定数的位数)则先给S-A(加-A的补码),再将S向右位移1位。
  • 如果S[bit-1]-S[bit-2]==0,则只把S向右位移1位。
  • 如果S[bit-1]-S[bit-2]==1,则先给S+A,再把S向右位移1位。

在这里插入图片描述

  1. 循环到B还剩最后1位的时候,循环结束,最后再把S向右位移1位,得到最终结果

在这里插入图片描述

除法(整数/原码):

在这里插入图片描述
因为是整数定点机,所以除法结果不能出现小数。我们要限定,A>B才能A/B。
如上图所示,对于本来就位数相等的两个数,可以直接做除法。但是对于位数不等的两个数,必须先经历一个“左对齐做减法”的步骤,如下图
在这里插入图片描述
为了解决这个问题,我采用的办法是,对B进行填充,使之与A有效位相同,如下图
在这里插入图片描述
我们设这个扩充后的B为opB(option 操作)
此时做opA=A-opB,>0,如下图
opA就是操作过的A的意思,也就是这一步的余数。
在这里插入图片描述
之后我们让B向右位移1位,再做opA=opA-opB。明显这次<0
在这里插入图片描述
我们不对opA操作,继续把opB右移1位,如图
在这里插入图片描述
到此为止,opB==B,循环结束。即10111/100=101…11

总结刚刚的做法

  1. 给B进行处理(opB),删除左边多余的0(保留符号位的位置),右边填上0
  2. 进入循环:
  • 如果opA-opB<0,则对opA不操作,对opB右移1位。上商为0。
  • 如果opA-opB>0,则opA=opA-opB,对opB右移1为,上商为1。
  1. 在opB==B的时候,循环终止。得到答案

最后应指出,符号位独立于数值计算。做一个异号得负同号得正的判断即可。

在这里插入图片描述

除法(小数/原码):

小数的除法与整数的除法原理上是一样的,但是也有不同。
首先,因为是小数定点机,所以除法结果不能出现整数。我们要限定,A<B才能A/B。
因为小数从0.XXX开始,其左端是自然对齐的,不需要人工对齐。
但是小数有另外一个问题:至少需要一个双倍长度的寄存器才能存下余数,因为余数会比数值本身长。如下图

在这里插入图片描述
如果我们要完整保存余数,需要保存0.00000111。这里我们采用一种比较巧的办法:
把之前对opB右移改为对opA左移!!
这样我们只需要运算下面框选区域即可,但是这样不能得到一个正确的余数
在这里插入图片描述
如图,我们最终得到的余数是00111,是不正确的。
具体的操作办法我们总结如下

  1. 如果opA-opB<0,则仅对opA左移一位,上商0
  2. 如果opA-opB>0,则opA=opA-opB,再对opA左移一位,上商1
  3. 直到把B全部遍历一遍结束。

在这里插入图片描述

符号位独立于数值计算。做一个异号得负同号得正的判断即可。
最后要注意的是,刚刚的描述里有个细节:要判断opA-opB的大小,得计算一遍。这里又分了两个办法:

  1. 先opA=opA-opB,如果<0,再opA=opA+opB,这个就是恢复法

  2. 考虑到如果<0,opA=2*(opA+opB)-opB=2opA+opB,而如果>0,opA=2opA-opB,达成了对称性,所以可以减少恢复的次数,这个就是不恢复法。

最后代码如下:代码比较长,里面函数的含义都在注释里,主函数留给读者自行发挥

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 64
//名称说明:bin是指不区分补码或原码的二进制码
//补码称code 原码称truecode
//整数称int 小数称dec

char* bin_plus_right(char* A, char* B);
char* bin_plus_left(char* A,char* B);
void bin_move(char* A, int n, int type,int signal);

//对二进制字符串某位置反
void reverse_digit(char* code, int digit){
    if(code[digit]=='0'){
        code[digit]='1';
    }else if(code[digit]=='1'){
        code[digit]='0';
    }
}

//2的幂
int power_by_2(int subnum){
    int res=2;
    while((--subnum)>0){
        res=2*res;
    }
    return res;
}

//由补码 输出十进制整数
int code_to_int(char* code,int signal){
    //不能改变传来的code指针
    int bit=strlen(code);
    char* modecode=malloc((bit+1)*sizeof(char));
    strcpy(modecode,code);

    //生成补码的反码
    int weight=1;

    if(modecode[signal-1]=='1'){
        weight=-1;
        for(int i=signal;i<bit;i++){
            reverse_digit(modecode,i);
        }
    }
    //生成补码的补码(原码)
    char* one="1";
    if(modecode[signal-1]=='1'){
        modecode=bin_plus_right(modecode,one);
    }
    //由原码生成十进制数
    int flag=1;
    int res=0;
    int i=bit-1;
    while(i>signal-1){
        res+=(modecode[i--]-'0')*flag;
        flag*=2;
    }
    if((res==0)&&(weight==-1)){
        res=power_by_2(bit-signal);
    }
    res*=weight;
    free(modecode);
    return res;
}

//由原码 输出十进制整数
int truecode_to_int(char* code,int signal){
    int bit=strlen(code);
    int weight=1;
    if(code[0]=='1'){
        weight=-1;
    }
    int flag=1;
    int res=0;
    int i=bit-1;
    while(i>signal-1){
        res+=(code[i--]-'0')*flag;
        flag*=2;
    }
    res*=weight;
    return res;
}

//由原码 输出十进制小数
double truecode_to_dec(char* code,int signal){
    int bit=strlen(code);
    int weight=1;
    if(code[0]=='1'){
        weight=-1;
    }
    int i=1;
    double res=0;
    double flag=0.5;
    while(i<bit){
        res+=(code[i++]-'0')*flag;
        flag/=2;
    }
    res*=weight;
    return res;
}

//十进制 整数输出其补码
char* int_to_code(int num,int bit,int signal){//num 十进制整数 bit 总位数 signal 符号位(算在总位数内)(一般为1)
    char* modecode=(char*)malloc((bit+1)*sizeof(char));
    //符号位及最后一位处理
    if(num>=0){
        for(int i=0;i<=signal-1;i++){
            modecode[i]='0';
        }
    }else{
        for(int i=0;i<=signal-1;i++){
            modecode[i]='1';
        }
        num*=-1;
    }
    modecode[bit]='\0';

    //生成原码
    int i=bit-1;
    while(i>=signal){
        modecode[i--]=num%2+'0';
        num/=2;
    }
    if(num!=0){
        printf("<Error>:输入溢出,输入数±%d\n",power_by_2(bit-signal)-1);
    }

    //生成反码
    if(modecode[signal-1]=='1'){
        for(int i=signal;i<bit;i++){
            reverse_digit(modecode,i);
        }
    }

    //生成补码
    char* one="1";
    if(modecode[signal-1]=='1'){
        modecode=bin_plus_right(modecode,one);
    }

    return modecode;
}

//给一个补码求其负数的补码
char* code_to_negative(char* code){
    //不能改变传来的code指针
    int bit=strlen(code);
    char* modecode=malloc((bit+1)*sizeof(char));
    strcpy(modecode,code);

    int i=bit-1;
    while(modecode[i--]!='1'){
        ;
    }
    while(i>=0){
        reverse_digit(modecode,i--);
    }
    return modecode;
}

//原码乘法
char* truecode_multi(char* A,char* B,int bit,int signal){
    //A*B A:被乘数 B:乘数
    char* res=malloc((2*bit+1)*sizeof(char));
    char* tem=malloc((2*bit+1)*sizeof(char));
    //初始化部分积(前部分=0,后部分=B)
    int i=0;
    for(;i<bit;i++){
        res[i]='0';
        tem[i]='*';
    }
    for(;i<2*bit;i++){
        res[i]='0';
        tem[i]='^';
    }
    res[2*bit]='\0';
    tem[2*bit]='\0';
    res=bin_plus_right(res,B);
    printf(">>被乘数A=\n       %s\n",A);
    printf(">>部分积S 乘数B=\n       %s\n       %s \n",res,tem);
    printf("-----------\n");
    //处理符号位
    if(A[signal-1]!=B[signal-1]){
        for(int i=0;i<=signal-1;i++){
            res[i]='1';
        }
    }

    //乘法
    int Bi=0;//乘数B的指针
    while(Bi<bit){
        if(res[bit*2-1]=='1'){//以B的每一位"1"
            res=bin_plus_left(res,A);//累加A与部分积的和(左对齐)
            printf(">先加A %s\n",res);
            bin_move(res,1,1,signal);//给部分积向右移位1位
            printf(">再位移%s\n",res);
        }else{
            bin_move(res,1,1,signal);
            printf(">只位移%s\n",res);
        }
        Bi++;
        tem[bit+Bi-1]='*';
        printf("       %s\n\n",tem);
    }
    printf("-----------\n");
    printf(">>  %d*%d=%d\n",code_to_int(A,signal),code_to_int(B,signal),code_to_int(res,signal));
    return res;
}

//补码乘法(Booth算法)
char* code_multi(char* A,char*B,int bit,int signal){
    //处理被乘数A的符号位为2位
    char* dA=malloc((bit+2)*sizeof(char));
    if(signal==1){//如果被乘数A是单符号位,要先处理成双符号位
        dA[0]=A[0];
        for(int i=0;i<=bit;i++){
            dA[i+1]=A[i];
        }
    }else{//这里默认只有2符号位。2以上符号位的情况未考虑
        strcpy(dA,A);
    }

    //处理乘数B增加一位0
    char* dB=malloc((bit+2)*sizeof(char));
    for(int i=0;i<bit;i++){
        dB[i]=B[i];
    }
    dB[bit]='0';
    dB[bit+1]='\0';

    //准备(-A)补
    char* dAmod=code_to_negative(dA);
    printf(">>被乘数A=%s,-A=%s\n",dA,dAmod);

    //初始化 部分积(前部分=0,后部分=B)
    char* res=malloc((bit*2+4-signal)*sizeof(char));
    char* tem=malloc((bit*2+4-signal)*sizeof(char));
    int i=0;
    for(;i<bit+2-signal;i++){
        res[i]='0';
        tem[i]='*';
    }
    for(;i<bit*2+3-signal;i++){
        res[i]='0';
        tem[i]='^';
    }
    res[2*bit+3-signal]='\0';
    tem[2*bit+3-signal]='\0';
    res=bin_plus_right(res,dB);
    printf(">>部分积S 乘数B=\n       %s\n       %s\n",res,tem);
    printf("-----------\n");

    int Bi=0;
    while(Bi<bit-1){
        if(res[2*bit+2-signal]-res[2*bit+1-signal]==-1){
            printf(">低位-高位=-1,累加(-A)\n");
            res=bin_plus_left(res,dAmod);//累加(-A)补
            printf(">先加-A%s\n",res);
            bin_move(res,1,0,signal);//给部分积向右移位1位
            printf(">再位移%s\n",res);
        }else if(res[2*bit+2-signal]-res[2*bit+1-signal]==0){
            printf(">低位-高位=0\n");
            bin_move(res,1,0,signal);//给部分积向右移位1位
            printf(">只位移%s\n",res);
        }else if(res[2*bit+2-signal]-res[2*bit+1-signal]==1){
            printf(">低位-高位=-1,累加A\n");
            res=bin_plus_left(res,dA);//累加A补
            printf(">先加A %s\n",res);
            bin_move(res,1,0,signal);//给部分积向右移位1位
            printf(">再位移%s\n",res);
        }
        Bi++;
        tem[bit+2-signal+Bi-1]='*';
        printf("       %s\n\n",tem);
    }
    if(res[2*bit+2-signal]-res[2*bit+1-signal]==-1){
        printf(">低位-高位=-1,累加(-A)\n");
        res=bin_plus_left(res,dAmod);//累加(-A)补
        printf(">终加-A%s\n",res);
    }else if(res[2*bit+2-signal]-res[2*bit+1-signal]==1){
        printf(">低位-高位=-1,累加(-A)\n");
        res=bin_plus_left(res,dA);//累加A补
        printf(">终加A %s\n",res);
    }
    bin_move(res,2,0,signal);
    printf(">终位移%s\n\n",res);
    printf("-----------\n");
    printf(">>  %d*%d=%d\n",code_to_int(A,signal),code_to_int(B,signal),code_to_int(res,2));

}

//二进制码加法(固定位,有溢出判断)
char* bin_plus_limit(char* A,char* B,int bit,int signal){
    char* res=malloc((bit+1)*sizeof(char));
    res[bit]='\0';
    int flag=0;//统一进位符
    int flag_last=0;//最高位进位符

    int i=bit-1;
    for(;i>=0;i--){
        if(A[i]!=B[i]){
            if(flag==0){
                res[i]='1';
            }else{
                res[i]='0';
            }
        }else if(A[i]=='0'){
            if(flag==0){
                res[i]='0';
            }else{
                res[i]='1';
                flag=0;
            }
        }else if(A[i]=='1'){
            if(flag==0){
                res[i]='0';
                flag=1;
            }else{
                res[i]='1';
            }
        }
        if(i==signal){
            flag_last=flag;
        }
    }

    if(signal==1){
        if(flag!=flag_last){
            printf("<Error>:计算溢出,计算数±%d\n",power_by_2(bit-signal)-1);
        }
    }else{
        if(res[signal-1]!=res[signal-2]){
            printf("<Error>:计算溢出,计算数±%d\n",power_by_2(bit-signal)-1);
        }
    }
    return res;
}

//二进制码加法(右对齐,自由位数,无溢出判断)
char* bin_plus_right(char* A, char* B){
    int len=strlen(A);
    if(len<strlen(B)){
        len=strlen(B);
    }
    char* res=malloc((len+1)*sizeof(char));
    res[len]='\0';
    int flag=0;
    int ri=len-1;
    int ai=strlen(A)-1;
    int bi=strlen(B)-1;
    do{
        if(A[ai]=='.'){
            res[ri--]='.';
            ai--;
            continue;
        }
        if(B[bi]=='.'){
            res[ri--]='.';
            bi--;
            continue;
        }
        if(ai==-1){
            if(flag==1){
                if(B[bi]=='1'){
                    res[ri--]='0';
                    bi--;
                }else{
                    res[ri--]='1';
                    bi--;
                    flag=0;
                }
            }else{
                res[ri--]=B[bi--];
            }
            continue;
        }
        if(bi==-1){
            if(flag==1){
                if(A[ai]=='1'){
                    res[ri--]='0';
                    ai--;
                }else{
                    res[ri--]='1';
                    ai--;
                    flag=0;
                }
            }else{
                res[ri--]=A[ai--];
            }
            continue;
        }
        if(A[ai]!=B[bi]){//一个是1一个是0
            if(flag==0){
                res[ri--]='1';
                ai--;
                bi--;
                continue;
            }else{
                res[ri--]='0';
                ai--;
                bi--;
                continue;
            }
        }
        if(A[ai]==B[bi]){
            if(A[ai]=='0'){
                if(flag==0){
                    res[ri--]='0';
                    ai--;
                    bi--;
                    continue;
                }else{
                    res[ri--]='1';
                    flag=0;
                    ai--;
                    bi--;
                    continue;
                }
            }else if(A[ai]=='1'){
                if(flag==0){
                    res[ri--]='0';
                    flag=1;
                    ai--;
                    bi--;
                    continue;
                }else{
                    res[ri--]='1';
                    ai--;
                    bi--;
                    continue;
                }
            }
        }
    }while(ri>-1);
    return res;
}

//二进制码加法(左对齐,自由位数,无溢出判断)
char* bin_plus_left(char* A,char* B){
    int lenmax=strlen(A);
    int lenmin=strlen(B);
    int temp=0;//代表A更长
    if(lenmax<lenmin){
        temp=lenmin;
        lenmin=lenmax;
        lenmax=temp;//代表B更长
    }

    char* res=malloc((lenmax+1)*sizeof(char));
    res[lenmax]='\0';
    int flag=0;
    int i=lenmax;//A和res的
    while(i>=lenmin){
        if(temp==0){//A更长
            res[i]=A[i];
        }else{//B更长
            res[i]=B[i];
        }
        i--;
    }
    while(i>=0){
        if(A[i]!=B[i]){
            if(flag==0){
                res[i]='1';
            }else{
                res[i]='0';
            }
        }else if(A[i]=='0'){
            if(flag==0){
                res[i]='0';
            }else{
                res[i]='1';
                flag=0;
            }
        }else if(A[i]=='1'){
            if(flag==0){
                res[i]='0';
                flag=1;
            }else{
                res[i]='1';
            }
        }
        i--;
    }
    return res;
}

//二进制码位移(n>0右移,n<0左移)
//signal变量只在type=1(原码)时起作用,其余状况可以随便填
//type=0:补码 type=1:原码 type=10:逻辑位移
void bin_move(char* A, int n, int type,int signal){
    int i;
    int bit=strlen(A);
    int negtive=1;//负数标记
    if(A[0]=='1'){//负数
        negtive=-1;
        if(type==1){//原码需要暂时接管符号位
            for(int i=0;i<=signal-1;i++){
                A[i]='0';
            }
        }
    }

    if(n>=0){//右移
        while(bit-1>=0){
            A[bit-1]=A[bit-1-n];
            bit--;
        }
        i=0;
        while(i<n){
            if(negtive==-1&&type==0){
                A[i]='1';//补码负数右移填1
            }else{
                A[i]='0';
            }
            i++;
        }
    }else{//左移
        n*=-1;
        i=n;
        while(i<bit){
            A[i-n]=A[i];
            i++;
        }
        i=i-n;
        while(i<bit){
            A[i++]='0';
        }
    }
    if(type==1&&negtive==-1){//负数原码需要归还符号位
        for(int i=0;i<=signal-1;i++){
            A[i]='1';
        }
    }
}

//二进制码减法(用补码实现)
char* bin_substruct_right(char*A, char*B){
    //A-B,即A+(-B)
    char* Bmod=code_to_negative(B);
    char* res=bin_plus_right(A,Bmod);
    return res;
}

//原码除法-整数
char* truecode_int_divide(char* A,char* B,int bit, int signal){
    //处理商R
    char* R=malloc((bit+1)*sizeof(char));
    for(int i=0;i<bit;i++){
        R[i]='0';
    }
    R[bit]='\0';

    //处理被除数A和除数B的符号
    char* opA=malloc((bit+1)*sizeof(char));
    char* opB=malloc((bit+1)*sizeof(char));
    strcpy(opA,A);
    strcpy(opB,B);
    int sign=1;
    if(opA[0]=='1'){
        sign=-1;
        for(int i=0;i<=signal-1;i++){
            opA[i]='0';
        }
    }
    if(opB[0]=='1'){
        sign*=-1;
        for(int i=0;i<=signal-1;i++){
            opB[i]='0';
        }
    }

    //处理整数除数B的位数,对齐左边
    int i=0;
    while(opB[i+signal]=='0'){
        i++;
    }
    bin_move(opB,-i,10,0);

    printf("opA=%s(%d),opB=%s(%d)\n",opA,code_to_int(opA,signal),opB,code_to_int(opB,signal));

    //除法:直到opB=B
    while(code_to_int(opB,signal)>=code_to_int(B,signal)){
        if(code_to_int(bin_substruct_right(opA,opB),signal)<0){//opA-opB<0(而且还没减,只是判断了一下)
            printf("A %s-B %s=A %s %d<0\n",opA,opB,bin_substruct_right(opA,opB),code_to_int(bin_substruct_right(opA,opB),signal));
            //opA-opB并没有发生,相当于恢复了
            bin_move(opB,1,10,0);//对opB右移1位

            bin_move(R,-1,10,0);
            R[bit-1]='0';//上商0
            printf("商上0 %s(%d)\n",R,code_to_int(R,signal));

        }else if(code_to_int(bin_substruct_right(opA,opB),signal)>=0){
            printf("A %s-B %s=A %s %d>0\n",opA,opB,bin_substruct_right(opA,opB),code_to_int(bin_substruct_right(opA,opB),signal));
            opA=bin_substruct_right(opA,opB);//这下opA-opB真的减了
            bin_move(opB,1,10,0);//对opB右移1位
            printf("B %s\n",opB);

            bin_move(R,-1,10,0);
            R[bit-1]='1';//上商1
            printf("商上1 %s(%d)\n",R,code_to_int(R,signal));

        }
        printf("\n");
    }

    printf(">>%d/%d=%d.....%d",code_to_int(A,signal),code_to_int(B,signal),code_to_int(R,signal),code_to_int(opA,signal));
    //还原符号位
    if(sign==-1){
        for(int i=0;i<=signal-1;i++){
            R[i]='1';
        }
    }
    return R;
}

//原码除法-小数-恢复余数法
char* truecode_dec_divide_resume(char* A,char* B,int bit, int signal){
    //处理商R
    char* R=malloc((bit+1)*sizeof(char));
    for(int i=0;i<bit;i++){
        R[i]='0';
    }
    R[bit]='\0';

    //处理被除数A和除数B的符号
    char* opA=malloc((bit+1)*sizeof(char));
    char* opB=malloc((bit+1)*sizeof(char));
    strcpy(opA,A);
    strcpy(opB,B);
    int sign=1;
    if(opA[0]=='1'){
        sign=-1;
        for(int i=0;i<=signal-1;i++){
            opA[i]='0';
        }
    }
    if(opB[0]=='1'){
        sign*=-1;
        for(int i=0;i<=signal-1;i++){
            opB[i]='0';
        }
    }

    printf("opA=%s(%lf),opB=%s(%lf)\n",opA,truecode_to_dec(A,signal),opB,truecode_to_dec(B,signal));

    //除法:首次判断
    if(truecode_to_dec(bin_substruct_right(opA,opB),signal)<0){//opA-opB<0(而且还没减,只是判断了一下)
        printf("结果<1,继续运算\n\n");
    }else{//opA-opB>0(而且还没减,只是判断了一下)
        printf("结果>1,不能运算\n\n");
        return R;
    }

    //除法:bit-1次
    int j=bit+1;
    while(--j){
        printf("j=%d\n",j);
        if(truecode_to_dec(bin_substruct_right(opA,opB),signal)<0){//opA-opB<0(而且还没减,只是判断了一下)
            printf("A %s-B %s=A %s %lf<0\n",opA,opB,bin_substruct_right(opA,opB),truecode_to_dec(bin_substruct_right(opA,opB),signal));
            //opA-opB并没有发生,相当于恢复了
            bin_move(opA,-1,10,0);//对optA左移一位
            printf("A %s\n",opA);

            bin_move(R,-1,10,0);
            R[bit-1]='0';//上商0
            printf("商上0 %s(%lf)\n",R,truecode_to_dec(R,signal));


        }else{//opA-opB>0(而且还没减,只是判断了一下)
            printf("A %s-B %s=A %s %lf>0\n",opA,opB,bin_substruct_right(opA,opB),truecode_to_dec(bin_substruct_right(opA,opB),signal));
            opA=bin_substruct_right(opA,opB);//这下opA-opB真的减了
            bin_move(opA,-1,10,0);//对optA左移一位
            printf("A %s\n",opA);

            bin_move(R,-1,10,0);
            R[bit-1]='1';//上商1
            printf("商上1 %s(%lf)\n",R,truecode_to_dec(R,signal));
        }
        printf("\n");
    }
    bin_move(opA,-bit+1,10,0);//因为算下来的余数不是真正的余数,而是部分余数。具体见图。所以,真正的余数需要继续左移。但是一定会溢出,因为位数不够

    printf(">>%lf/%lf=%lf...%lf\n",truecode_to_dec(A,signal),truecode_to_dec(B,signal),truecode_to_dec(R,signal),truecode_to_dec(opA,signal));
    //还原符号位
    if(sign==-1){
        for(int i=0;i<=signal-1;i++){
            R[i]='1';
        }
    }
    return R;

}

//原码除法-小数-不恢复余数法
char* truecode_dec_divide_nonresume(char* A,char* B,int bit, int signal){
    //处理商R
    char* R=malloc((bit+1)*sizeof(char));
    for(int i=0;i<bit;i++){
        R[i]='0';
    }
    R[bit]='\0';

    //处理被除数A和除数B的符号
    char* opA=malloc((bit+1)*sizeof(char));
    char* opB=malloc((bit+1)*sizeof(char));
    strcpy(opA,A);
    strcpy(opB,B);
    int sign=1;
    if(opA[0]=='1'){
        sign=-1;
        for(int i=0;i<=signal-1;i++){
            opA[i]='0';
        }
    }
    if(opB[0]=='1'){
        sign*=-1;
        for(int i=0;i<=signal-1;i++){
            opB[i]='0';
        }
    }

    printf("opA=%s(%lf),opB=%s(%lf)\n",opA,truecode_to_dec(A,signal),opB,truecode_to_dec(B,signal));

    //除法:首次判断
    printf("(首次)A %s-B %s=",opA,opB);
    opA=bin_substruct_right(opA,opB);//opA=opA-opB
    printf("A %s %lf",opA,truecode_to_dec(opA,signal));

    //除法:bit-1次
    int j=bit;
    while(--j){
        if(opA[0]=='1'){//opA-opB<0(已经实打实减了)
            printf("<0\n\n");

            bin_move(R,-1,10,0);
            R[bit-1]='0';//上商0
            printf("商上0 %s(%lf)\n",R,truecode_to_dec(R,signal));

            printf("A %s*2+B %s=",opA,opB);
            bin_move(opA,-1,10,0);//对opA左移一位
            opA=bin_plus_left(opA,B);//opA=opA+opB
            printf("A %s %lf",opA,truecode_to_dec(opA,signal));
        }else{//opA-opB>(已经实打实减了)
            printf(">0\n\n");

            bin_move(R,-1,10,0);
            R[bit-1]='1';//上商1
            printf("商上1 %s(%lf)\n",R,truecode_to_dec(R,signal));

            printf("A %s*2-B %s=",opA,opB);
            bin_move(opA,-1,10,0);//对optA左移一位
            opA=bin_substruct_right(opA,opB);//opA=opA-opB
            printf("A %s %lf",opA,truecode_to_dec(opA,signal));
        }
    }

    //终次:上商但是不处理余数
    if(opA[0]=='1'){//余数<0,
        printf("<0\n\n");

        bin_move(R,-1,10,0);
        R[bit-1]='0';//上商0
        printf("商上0 %s(%lf)\n",R,truecode_to_dec(R,signal));
    }else{//余数>0,上商1
        printf(">0\n\n");

        bin_move(R,-1,10,0);
        R[bit-1]='1';
        printf("(终次)商上1 %s(%lf)\n",R,truecode_to_dec(R,signal));
    }

    bin_move(opA,-bit+1,10,0);//因为算下来的余数不是真正的余数,而是部分余数。具体见图。所以,真正的余数需要继续左移。但是一定会溢出,因为位数不够

    printf(">>%lf/%lf=%lf...%lf\n",truecode_to_dec(A,signal),truecode_to_dec(B,signal),truecode_to_dec(R,signal),truecode_to_dec(opA,signal));
    //还原符号位
    if(sign==-1){
        for(int i=0;i<=signal-1;i++){
            R[i]='1';
        }
    }
    return R;

}

int main()
{
    printf("helloworld");
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值