只是呼吸 发表于 2015-8-14 01:01:01

格式化函数:DIV_DigitFomart.c
函数功能:将传入的两个数格式化。其中格式化后的除数的最高位必须是9位十进制数。

#include "DIV.h"

void DIV_DigitFomart(const UINT32 * const dividend,int LEN_dividend,const UINT32 * const divisor,
                                       int LEN_divisor,int *Cdiv,int *divR)
{
        int i;
        UINT32 temp,t,result;
        UINT64 C;
   

        LEN_divisor--;
        LEN_dividend--;
        t=0;
        temp=divisor;
        result=1;

        do
        {
                temp<<=1;
                t++;
        }while(temp<BASE);////这个循环把除数首位移位。
    result<<=t;       ////求出要扩大的倍数。

        temp=0;
        for(i=0;i<LEN_divisor;i++)
        {
                C=UInt32x32To64(divisor, result)+temp;//// 除数扩大2^t倍。除数的最高位以外的各位保留8个十进制数。
                temp=(unsigned int)(C/BASE);
                divR=(int)(C%BASE);
        }
        divR=(int)(UInt32x32To64(divisor,result)+temp);///除数的最高位保留9个十进制数。

        temp=0;
        for(i=0;i<=LEN_dividend;i++)
        {
                C=UInt32x32To64(dividend,result)+temp;//// 被除数扩大2^t倍。被除数的各位数字保留8个十进制数。
                temp=(unsigned int)(C/BASE);
                Cdiv=(int)(C%BASE);
        }
        Cdiv=(int)temp;

        if(Cdiv>BASE)
        {
                Cdiv=Cdiv/BASE;
      Cdiv=Cdiv%BASE;
        }
}

补充内容 (2015-8-14 11:03):
应改为:格式化文件:DIV_DigitFomart.c

补充内容 (2015-8-15 14:11):
更正:程序第42行应改为:if(Cdiv>=BASE)

只是呼吸 发表于 2015-8-14 01:08:07

除法开始的函数:Big_Digit_DIV.c

#include "DIV.h"

void Big_Digit_DIV(UINT32 *qut, int *Work,int *Cdiv,int LENdividend, int *divR,int LENdivR)
{

//int    Cdiv[];      // 被除数dividend
//int    divR[];      // 除数    divisor
//int   qut[];      // 商      quotient   
    int    CTRL={0};   // 控制    control

    UINT64   C;
        int   temp;
    int f0,i,j,n;
   
    CTRL=0;                      //试商由1变为0时的判断依据。CTRL=1时表示试商由1变为0
//CTRL                           未定义
    CTRL=LENdivR;                //除数数组的最大下标
    CTRL=LENdividend;            //每次循环参与计算的被除数起始下标         
//CTRL                           未定义
//CTRL                           临时存贮试商的值            
    CTRL=LENdividend-LENdivR-1;//每次循环参与计算的被除数终点下标
       
       
        i=LENdividend-LENdivR-1;////除法总的循环次数的初始值(从LENdividend-LENdivR-1开始计数,直到0,最多循环LENdividend-LENdivR次)
        while(i>=0)//-----//除法开始
        {
                f0=CTRL;
                C=UInt32x32To64(Cdiv,BASE)+Cdiv;////-----C=Cdiv*10^8+Cdiv.
                temp=(int)(C/divR);// 求试商

      if((temp==0)||(CTRL==1))
      {
                        i--;//总循环次数减1
                        CTRL--; //被除数下标减1,被除数增加一项
                        if(CTRL<0)//满足条件时程序结束。
                        {
                                i=-1;    //强制程序退出。
                                continue;
                        }
                       
                        C=UInt32x32To64(C,BASE)+Cdiv;////--------C=Cdiv*10^16+Cdiv*10^8+Cdiv
                        temp=(int)(C/divR);//增加一项再求商。Cdiv就是增加的那一项。
                }
               
                CTRL=temp;
      quotient_MUL_divisor(Work,Cdiv,divR,CTRL);////乘法、加法和减法函数,将试商确定为真实商
      if(CTRL==1) continue;//试商由1变为0时,进行下一次循环。
      qut=(unsigned int)CTRL;//把确定了的商赋给qut[].

      j=CTRL;
      while((Cdiv==0)&&(j>=0))//计算余数从左端起非零第一项的位置下标
                j--;

                if(j<0)//计算出的j小于0,说明除法计算已完成。
                {
                        i=-1; //强制程序退出。
                        continue;
                }

                if(j<CTRL)//条件满足时,说明本次运算余数是零,
                {
                        i=j-LENdivR-1;//计算主循环下标。
                        CTRL=j;//返回被除数下标(上限,对应数组高位),用于下一次计算
                        CTRL=i;//返回被除数下标(下限,对应数组低位),用于下一次计算。
                }
               
                if(j>=CTRL)//说明本次运算有非零的余数。
                {
                        n=j-CTRL+1;//求余数剩下的位数
                        if(n<=LENdivR+1)////当n小于等于除数的长度时
                        {
                                temp=LENdivR+1-n+1;//求出要补充的新被除数个数。
                                CTRL=j;//返回被除数下标(上限,对应数组高位),用于下一次计算
                                CTRL=CTRL-temp;//返回被除数下标(下限,对应数组低位),用于下一次计算
                                i=CTRL;//计算主循环下标
                        }
                        else
                        {
                                CTRL=j;//返回被除数下标(上限,对应数组高位),用于下一次计算
                                CTRL=j-LENdivR-1; //返回被除数下标(下限,对应数组低位),用于下一次计算
                        }
                }
        }
}


补充内容 (2015-8-14 11:00):
应改为:除法开始的文件:Big_Digit_DIV.c

只是呼吸 发表于 2015-8-14 01:11:04

本帖最后由 只是呼吸 于 2015-8-14 09:08 编辑

除法运算过程中要调用的大整数加、减、乘函数:quotient_MUL_divisor.c

#include "DIV.h"

void quotient_MUL_divisor(int *result,int *Cdiv,int *divR,int *CTRL)
{
        int i,n,s,temp;
        UINT64 C;
        //int temp;//result={0},temp;
       
        n=CTRL-CTRL-CTRL;//对位计算。
        s=CTRL+CTRL+1;      //对位计算。
       
        temp=0;
        for(i=0;i<=CTRL;i++)//CTRL是除数数组的最大下标。
        {
                C=UInt32x32To64(divR,CTRL)+temp;/// CTRL是函数传入的试商,做乘法。赋给result[];
                temp=(int)(C/BASE);          ///取出向前的进位值。
                result]=(int)(C%BASE);////保留本位的8位数字。
        }
        if(n==2)
        {
                result=temp%BASE;//// 当n==2时继续进位。
                result=temp/BASE;
        }
        else
        {
                result=temp; ////n==1时的进位。
        }
       

        temp=0;
        for(i=CTRL;i<=CTRL;i++)
        {
                Cdiv-=(result+temp);//---------------------减法。减剩的就是余数,直接赋给Cdiv[]
               
                temp=0;
                if(Cdiv<0)//把余数数组内的负数变为正的。
                {
                        Cdiv+=BASE;///加上100000000;
                        temp=1;///向前一位借1。
                }
        }///)(*///
       
       
       
        CTRL=0;
        if(temp==1) /// temp==1表示余数是负的。
        {
                for(i=0;i<=CTRL;i++)
                        Cdiv]+=divR;//-------加法,余数为负数时做一次加法,将负的余数变为正的。
               
                for(i=CTRL;i<=CTRL;i++)//对相加的结果作进位处理
                {
                        temp=Cdiv/BASE;
                        Cdiv+=temp;
                        Cdiv-=temp*BASE;
                }
               
                if(CTRL==1)///当temp==1和CTRL==1同时成立时。说明真实的商应该是0。
                {
                        CTRL=1; //强制让被除数增加一项。
                }
                else
                {
                        CTRL=0;
                }
                CTRL=CTRL-1;//余数为负时,试商减去1
        }
        return ; ////(*///      
}


补充内容 (2015-8-14 11:02):
应改为:除法运算过程中要调用的大整数加、减、乘文件:quotient_MUL_divisor.c

只是呼吸 发表于 2015-8-14 09:37:12

本帖最后由 只是呼吸 于 2015-8-14 10:55 编辑

这里给出简单的调用示例。

将上面9#到13#的程序做在一个工程中,在工程中添加文件:mymain.c

#include <stdio.h>
#include "DIV.h"

int main()
{
        UINT32 t1,t2;//------------时间变量。
        UINT32 c={0},e={0},result={0};

        int s,j;

        t1=GetTickCount();//时间计时开始;
      c=1023;
      c=2305;
      c=30000214;
      c=92364017;
      c=0;
      c=99999999;
      c=90031470;
      c=30247952;
   
      e=6;
      e=21455;
      e=99962301;
      e=96325793;//////以上数组每一个单元以10^8为进位的基数。较大的下标对应高位数字,较小的下标对应低位数字。

        printf("被除数    ");
      printf("%u",c);
        for(s=6;s>=0;s--)
                printf("%08u",c);//输出语句。
        printf("\n");

        printf("除数    ");
      printf("%u",e);
        for(s=2;s>=0;s--)
                printf("%08u",e);
        printf("\n");
        printf("\n");

   j=Big_NumDiv_q(result,c,e,7+1,3+1);// j是函数返回的商的最大下标。


        t2=GetTickCount();//时间计时结束;

        printf("商    ");
        printf("%u",result);//输出语句。输出商。       
        for(s=j-1;s>=0;s--)
                printf("%08u",result);
        printf("\n");

    printf("时间%d\n",t2-t1);
   
system( "pause" );
       
        return 0;
}

      


补充内容 (2015-8-16 14:08):
更正:#11楼中的程序第42行应改为:if(Cdiv>=BASE)

只是呼吸 发表于 2015-8-16 14:08:52

更正:#11楼中的程序第42行应改为:if(Cdiv>=BASE)
页: 1 [2]
查看完整版本: 笔算除法的代码