函数功能:将传入的两个数格式化。其中格式化后的除数的最高位必须是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) 除法开始的函数: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 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 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) 更正:#11楼中的程序第42行应改为:if(Cdiv>=BASE)
页:
1
[2]