c语言高精度乘法函数 c++高精度乘法

高精度 阶乘和 C语言

哥给你一个好的,用数组模拟乘法

成都创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:网站设计制作、网站建设、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的山南网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

俺原创的,呵呵~~~

#include stdio.h

void main()

{

int a[1000]={1},b[4]={0};

int k,i,j;

scanf("%d",k);

void multi(int a[],int b[]); // 用于计算乘法的函数,计算a*b 并把结果放在a当中

void seperate(int n, int b[]); //分离一个数的没一位,并放在b中!

for (i=1;i=k;i++)

{

seperate(i,b);

multi(a,b);

}

for (j=999;a[j]==0;j--);

//反序输出

for (i=j;i=0;i--) //

printf("%d",a[i]); //

} //主函数结束,下面是函数部分

void seperate(int n,int b[]) //注意最后一位是放在b[0]中的!

{

int i;

for (i=0;n0;i++)

{

b[i]=n%10;

n/=10;

}

}

void multi(int a[],int b[]) //核心程序,非常难调啊!!!!!

{

int tp[1000]={0};

int i,j,t,p,m,n;

for (m=3;b[m]==0;m--);

for (n=999;a[n]==0;n--);

for (j=0;j=m;j++)

{

t=0;

for ( i=0;in+2;i++)

{

p=b[j]*a[i]+t+tp[i+j];

tp[i+j]=p%10;

t=p/10;

}

}

for (j=999;tp[j]==0;j--);

for (i=0;i=j;i++)

a[i]=tp[i];

}

求一段高精度乘法函数(C++)

设计高精度乘法计算函数

[返回]

计算机世界2001年第12期

设计高精度乘法计算函数

重庆建设中学 杨宏伟

我们知道计算机的计算精度不是无限大的,甚至是十分有限的。CPU的字长和操作系统的处理能力直接制约着运算精度和运算能力。随着计算机应用的深入,人们对计算能力的需求,尤其是精度的需求,越来越高。虽然目前32位CPU及操作系统提供的计算精度,较之从前已有很大的提高,而且精度更高的64位CPU及操作系统正在普及,但是,对许多计算机应用课题来说,能不能具有不直接依赖硬件条件的高精度、高性能计算能力仍是至关重要的。为此,设计高精度计算的软件包,用软件方法实现高精度计算,是一件有实用价值的工作。例如,目前在电子商务应用中,密码的校验及计算就是对高精度计算的典型需求。

分析问题

由于C语言具有执行效率高、支持动态存储分配等特点,我们选用C语言编写了一套工具函数,供高精度计算使用。乘法运算在计算机运算中是一种基本运算,它的计算过程对整个计算效率有举足轻重的影响。仔细研究乘法运算对高精度计算十分必要。

为了实现高精度计算,首先要建立高精度的数据表示方法。我们采用将整数和小数分开,组成两个队列的方法存储数据。这种方法不仅节约存储空间,而且有利于确保整数运算的精度。

描述运算对象的数据结构如下:

struct VARARRAY {

char cDigit; //保存数据位

//指向下一个数据位

struct VARARRAY * spNext;

};

 

struct SUPERNUMBER

{

//指向最低位整数

struct VARARRAY * spIntPart;

 

//指向最低位小数

struct VARARRAY * spDecPart;

 

//指向最高位整数

struct VARARRAY * spIntLast;

 

//指向最高位小数

struct VARARRAY * spDecLast;

 

int iNumberInt; //整数位数

int iNumberDec; //小数位数

char cSign;

}; //符号位

在用SUPERNUMBER结构描述运算对象的基础上,我们定义了一套函数,全面实现SUPERNUMBER型数据的输入、输出、赋值、比较、加、减、乘、除、整除等运算功能。本文重点介绍无精度损失的乘法计算方法及主要函数的设计。

乘法算法

为了不损失计算精度,我们将乘法转换为加法实现,基本算法如下:

1.将数符较多的数据表示为X,作为加数,数符较少的数据表示为Y,控制加法次数;

2.如果Y含有小数部分,将Y转变为纯整数YDEC,并记录小数点的右移位数I;

3.初始化返回值T为0,取得Y的位数WIDTH,设计数器COUNT为0;

4.取Y右侧第COUNT+1位,以此数为次数加X,再左移COUNT位,加到T中;

5.把COUNT加1;

6.若COUNT等于WIDTH,转下一步,否则转第4步;

7.将T中的小数点左移I位;

8.返回T,得到乘法结果。

本算法的特点是加法次数少,若Y的宽度为W,最多进行9×W次加法及W次移位即可。

乘法函数

乘法函数通过把两个SUPERNUMBER型的数据相加实现运算目的,其结果通过指针返回。

struct SUPERNUMBER * su_mu(

struct SUPERNUMBER * spSourceOne,

struct SUPERNUMBER * spSourceTwo)

{

struct SUPERNUMBER * spNew;

struct SUPERNUMBER * spYDec;

struct SUPERNUMBER * spX,* spY,* spC,* spT;

struct VARARRAY * spTem;

int iYDec,iWidth,iDigit,iC1,iC2;

spNew=su_as(“0”);

if (spSourceOne-iNumberInt+spSourceOne-iNumberDec=spSourceTwo-iNumberInt+

spSourceTwo-iNumberDec){

spX=su_co(spSourceOne);

spY=su_co(spSourceTwo);

}

else{

spY=su_co(spSourceOne);

spX=su_co(spSourceTwo);

}

iYDec=spY-iNumberDec;

spYDec=su_mo(spY,iYDec);

iWidth=spYDec-iNumberInt;

spTem=spYDec-spIntPart;

for(iC1=0;iC1iWidth;iC1++)

{

iDigit=(int)(spTem-cDigit-‘0’);

spTem=spTem-spNext;

spC=su_as(“0”);

for(iC2=0;iC2iDigit;iC2++)

{

spT=su_ad(spC,spX);

su_fr(spC);

spC=su_co(spT);

su_fr(spT);

 

}

spT=su_mo(spC,iC1);

su_fr(spC);

spC=su_ad(spNew,spT);

su_fr(spNew);su_fr(spT);

spNew=su_co(spC);

su_fr(spC);

}

spT=su_mo(spNew,-iYDec);

su_fr(spNew);

spNew=su_co(spT);

su_fr(spT);

su_fr(spYDec);

su_fr(spX);

su_fr(spY);

return spNew;

}

在此函数中,我们使用了在高精度计算软件包中定义的其他函数(本文省略其实现代码),主要有:

1.将字符串转化为SUPERNUMBER类型:

struct SUPERNUMBER * su_as(char*zpSource);

2.将一个SUPERNUMBER复制到另一个SUPERNUMBER中:

struct SUPERNUMBER * su_co(struct SUPERNUMBER * spSource);

3.两个SUPERNUMBER的“等于”关系运算,若相等,返回1:

int su_ee(struct SUPERNUMBER * spSource, struct SUPERNUMBER * spDesti);

4.两个SUPERNUMBER数的加法运算:

struct SUPERNUMBER * su_ad(struct

SUPERNUMBER * spSource,struct SUPERNUMBER * spDestination);

5.SUPERNUMBER与用整数表示的数据的加法运算:

struct SUPERNUMBER * su_si(

struct

SUPERNUMBER * spSource, int iDesti);

6.移动小数点:

struct SUPERNUMBER * su_mo(struct

SUPERNUMBER * spSource, int iNum);

7.释放SUPERNUMBER数据的存储空间:

void su_fr(struct SUPERNUMBER * spSource);

应用实例

当我们计算16的阶乘时,常规的方法难于直接得到正确的结果,即使定义长整型(long int)数据,在计算出11的阶乘39916800之后,也开始出现数据错误。但是利用本文介绍的方法,可精确地计算出从1到16的阶乘值。代码如下:

FILE * fp;

struct SUPERNUMBER * spX;

struct SUPERNUMBER * spY;

struct SUPERNUMBER * spZ;

struct SUPERNUMBER * spSum;

fp=fopen(“abcd.txt”,“a+”);

if (fp==NULL) MessageBox(hWndMain,“file error”,“”,MB_OK);

//初始化变量

spX=su_as(“0”);

spY=su_as(“30”);

spSum=su_as(“1”);

//计算从1到16的阶乘值

lp: spZ=su_si(spX,1);

su_fr(spX);

spX=su_co(spZ);

su_fr(spZ); spZ=su_mu(spSum,spX);

su_fr(spSum);

spSum=su_co(spZ);

su_fr(spZ);

su_os(spSum);

su_of(spX,fp);

su_of(spSum,fp);

if (!su_ee(spY,spX)) goto lp;

 

fclose(fp);

运算结果为:

1 ! 1 2! 2

3 ! 6 4! 24

13 ! 6227020800 14! 87178291200

15 ! 1307674368000 16! 20922789888000

C语言:求n阶乘(高精度) 已经用高精度乘法,如何组合程序,完成功能呢 ???

你的程序有些问题 我改了一下 你看看

#includestdio.h#includestring.h

//将数转为数组

int f(int n,int a[]){

int i=0;

while(n!=0){

a[i++]=n%10;

n=n/10;

}

return i;

}

//求数组长度

int qiu(int a[]){

int i;

for(i=2003;i=0;i--) {

if(a[i]!=0) {

return i+1;

break;

}

}

return 0;

}

//将数组a 赋值到数组b 并清零数组a

void fuzhi(int a[],int b[]){

int a1,b1,i;

a1=qiu(a);

b1=qiu(b);

for(i=0;ib1;i++){

b[i]=0;

}

for(i=0;ia1;i++){

b[i]=a[i];

}

for(i=0;ia1;i++){

a[i]=0;

}

}

//求n的阶乘

int fun(int n){

int i=0,k;

int a[2004]={0},b[2004]={0} ,c[2004]={0};

if(n==0||n==1){

printf("n=%d的阶乘为:1\n",n);

}

else

{

f(1,a);

f(2,b);

fac(a,b,c);

for(i=3;i=n;i++){

fuzhi(c,a);

f(i,b);

fac(a,b,c);

}

k=qiu(c);

printf("计算结果:\n");

for(i=k-1;i=0;i--) {

printf("%d",c[i]);

}

printf("\n");

}

return 0;

}

//本函数是求两个数之积的高精度乘法,并输出两个数之积为数组c

int fac(int a[],int b[],int c[])

{

int i,j,m=0,n=0,k=0;

m=qiu(a);

n=qiu(b);

for(j=0;jn;j++){

for(i=0;im;i++) {

c[i+j]=c[i+j]+a[i]*b[j];

while(c[i+j]=10)

{

c[i+j]=c[i+j]-10;

c[i+j+1]=c[i+j+1]+1;

}

}

}

return 0;

}

void main(){

int n;

printf("请输入N的值:\n");

scanf("%d",n);

fun(n);

return 0;

}

可以运行 结果也没有问题 如果有不懂的 可以加我QQ 354156421

求助 c语言实现高精度乘法

Hpre.h 文件

//HighPrecision

// 1234567890 高位存在数组最末

#include iostream

#include string.h

#include vector

using namespace std;

const int maxlen=300;

class HP{

public:

HP()

HP(int inte,int len);

~HP() ;//

HP(int inte);

HP(const char*str);

int HP_DectoB(int sum,int b,int *S);

friend ostream operator (ostream cout,const HP x)

{

if(x.sign_bit) cout"-";

for(int i=x.len;i0;i--)

{

coutx.num.at(i);

if((i-1)%3==0 i!=1) cout",";

}

return cout;

}

HP operator=(int inte);

HP operator=(const char* str);

HP operator*(const HP b);

HP operator+(const HP b);

HP operator-(const HP b);

HP operator/(const HP b);

HP operator%(const HP b);

HP operator++();

HP operator++(int);//后置自增运算符

HP operator--();

HP operator--(int);

int Compare(const HP b);

HP GCD(const HP b);

private:

int len;

vectorint num;

bool sign_bit;//符号位 1 - 0 +

};

/////////////////////////////

Hpre.cpp 文件

#include "HPre.h"

#include "HPre.h"

HP::HP(int inte)

{

if(inte0) sign_bit=1;

else sign_bit=0;

num.clear();

num.push_back(0);

if(inte==0)

for(len=0;inte0;)

}

HP::HP(const char*str)

{

num.clear();

num.push_back(0);

if(str[0]!='-') sign_bit=0,str++;

else sign_bit=1;

len=strlen(str);

for(int i=1;i=len;i++) num.push_back(str[len-i]-'0');

}

HP HP::operator=(int inte)

{

if(inte0) sign_bit=1;

else sign_bit=0;

num.clear();

num.push_back(0);

if(inte==0)

for(len=0;inte0;)

return (*this);

}

HP HP::operator=(const char *str)

{

if(str[0]!='-') sign_bit=0,str++;

else sign_bit=1;

len=strlen(str);

num.push_back(0);

for(int i=1;i=len;i++) num.push_back(str[len-i]-'0');

return (*this);

}

HP HP::operator*(const HP b)

{

int i,j;

int c_len=len+b.len;

HP c(0);

c.num.resize(c_len+1,0);

if(this-sign_bit!=b.sign_bit) c.sign_bit=1;

else c.sign_bit=0;

for(i=1;i=len;i++)

for(j=1;j=b.len;j++) c.num[i+j-1]+=num[i]*b.num[j];

for(i=1;ic_len;i++)

while(c.num[i])

while(i1 !c.num[i]) i--;

c.len=i;

return c;

}

HP HP::operator-(const HP b)

{

int i,j;

HP c;

int tlen=0;

if(b.lenthis-len) tlen=b.len;

else tlen=this-len;

c.num.resize(tlen+1,0);

if(Compare(b)=0) c.sign_bit=0;

else c.sign_bit=1;

for(i=1,j=0;i=len;i++)

{

c.num[i]=num[i]-j;

if(i=b.len) c.num[i]-=b.num[i];

if(c.num[i]0)

else j=0;

}

c.len=len;

while(c.len1 !c.num[c.len]) c.len--;

return c;

}

HP HP::operator/(const HP b)

{

int i,j;

HP d(0),c;

int tlen=0;

if(b.lenthis-len) tlen=b.len;

else tlen=this-len;

c.num.resize(tlen+1,0);//商

d.num.resize(tlen+1,0);//余数

if(this-sign_bit!=b.sign_bit) c.sign_bit=1;

else c.sign_bit=0;

for(i=len;i0;i--)

{

if(!(d.len==1 d.num[1]==0))//除数不为0

{

for(j=d.len;j0;j--)

d.num[j+1]=d.num[j];

++d.len;

}

d.num[1]=num[i];c.num[i]=0;

while( (j=d.Compare(b))=0)

{ d=d-b; c.num[i]++;

if(j==0) break;

}

}

c.len=len;

while((c.len1)(c.num[c.len]==0)) c.len--;

return c;

}

HP HP::operator+(const HP b)

{

int i;

HP c;

int tlen=0;

if(b.lenthis-len) tlen=b.len;

else tlen=this-len;

c.num.resize(tlen,0);

c.num[1]=0;

for(i=1;i=len||i=b.len || c.num[i];i++){

if(i=len) c.num[i]+=num[i];

if(i=b.len) c.num[i]+=b.num[i];

c.num.push_back(c.num[i]/10); c.num[i]%=10;

}

c.len=i-1; if(c.len==0) c.len=1;

return c;

}

int HP::Compare(const HPy)

{

if(leny.len) return 1;

if(leny.len) return -1;

int i=len;

while((i1) (num[i]==y.num[i])) i--;

return num[i]-y.num[i];

}

HP HP::operator %(const HP b)

{

int i,j;

HP d(0);

int tlen=b.len;

d.num.resize(tlen+3,0);

for(i=len;i0;i--)

{

if(!(d.len==1 d.num[1]==0))

{

int t=d.num.size()-1;

if(t==d.len) d.num.push_back(0);

for (j=d.len;j0;j--)

d.num[j+1]=d.num[j];

++d.len;

}

d.num[1]=num[i];

while ((j=d.Compare(b)=0))

{

d=d-b;

if(j==0) break;

}

}

return d;

}

HP HP::GCD(HP b)

{

HP d(1);

const HP zero(0);

int d_len=0;

if(lenb.len) d_len=b.len;

else d_len=len;

d.num.resize(d_len+2);

d=*this%b;

if(d.Compare(zero)==0)

else return b.GCD(d);

}

//////////////////////

main.cpp文件

#include iostream

#include "HPre.h"

using namespace std;

#include iostream

#include "HPre.h"

using namespace std;

int main()

{

HP t("18446744073709551616");//2^64

HP a(12);

HP b(9);

HP c(3);

a=a*t;

b=b*t;

couta.GCD(b)endl;

coutc*tendl;

return 1;

}

验算没错 不知道有其他错误没 自己写的类


网站名称:c语言高精度乘法函数 c++高精度乘法
文章链接:http://scjbc.cn/article/dospisd.html

其他资讯