求算法???

tondayong1981 2005-12-06 08:35:55
实现一个高精度无符号整数乘法的函数,函数原型为void Multiply(WORD *R, WORD* A, WORD *B, unsigned int N),其中R为结果,A与B为两个乘数,N为乘数的长度(单位为WORD)。WORD为你们定义的存储长整数每一部分的类型.其中A和B都是二进制,使用http://www.gdcp.cn/jpkc/sjjg/app/jm/bignumber_mul/solution.htm
上的算法写递归程序.把下面的函数原型改了就可以了,谢谢大家了,我实在写不出

function MULT(X,Y,n); {X和Y为2个小于2n的整数,返回结果为X和Y的乘积XY}begin S:=SIGN(X)*SIGN(Y); {S为X和Y的符号乘积}
X:=ABS(X); Y:=ABS(Y); {X和Y分别取绝对值}
if n=1 then
if (X=1)and(Y=1) then return(S)
else return(0)
else
begin
A:=X的左边n/2位;
B:=X的右边n/2位;
C:=Y的左边n/2位;
D:=Y的右边n/2位;
ml:=MULT(A,C,n/2);
m2:=MULT(A-B,D-C,n/2);
m3:=MULT(B,D,n/2);
S:=S*(m1*2n+(m1+m2+m3)*2n/2+m3);
return(S);
end;
end;

...全文
431 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
jixingzhong 2005-12-09
  • 打赏
  • 举报
回复
楼主, 你先看看 现成的 巨型数的类吧 ~
类中的 乘法的思想就是分段,你可以学习,对比一下,
应该有所帮助 ~
tondayong1981 2005-12-09
  • 打赏
  • 举报
回复
大家帮我写一下把,我不会啊
cozil 2005-12-08
  • 打赏
  • 举报
回复
我个人认为这样的算法没有意义,因为从题来看,所谓的高精度也只限于计算机能处理的最大整型数(LONG型),对于32位的数据,CPU相乘后的结果是作为64位存储在EDX和EAX中的,通过将这两个值拼接可以得到。
楼主所要求的高精度整数乘法,据题可知
1.参数只限于计算机能处理的最大整型数;
2.这一复杂的运算并不比CPU本身去处理两个数相乘要快
所以这样的做法没有意义。
如果能处理超出计算机整型数范围的乘法,并且速度上也有优势,才有意义。
比如说,输入的参数是字符串格式,输出也以字符串格式,参数长度没有限制才体现出优势。
tondayong1981 2005-12-08
  • 打赏
  • 举报
回复
应该是这样,不过奇数位的数进行计算,还是不对,不知为什么
#include<stdio.h>
#include<math.h>
void MULTIPLY(long *C,long *A,long *B,int len)
{
long a,b,c,d;
long m1,m2,m3;
long sub1,sub2;
if(len==1)
{
*C=(*A)*(*B);
printf("c=%d\n",*C);
}
else
{

long multiply=pow(10,(len/2));
//A的左边len/2位
a=((*A)/multiply);
//A的右边len/2位
b=((*A)%multiply);
//A的左边len/2位
c=((*B)/multiply);
//A的右边len/2位
d=((*B)%multiply);
sub1=a-b;
sub2=d-c;
MULTIPLY(&m1,&a,&c,len/2);
MULTIPLY(&m2,&sub1,&sub2,len/2);
MULTIPLY(&m3,&b,&d,len/2);
(*C)=m1*pow(10,len)+(m1+m2+m3)*pow(10,len/2)+m3;
printf("C=%d\n",*C);


}

}
int main()
{
//输入的A和B的长度相同
long A,B,C;

scanf("%ld",&A);
scanf("%ld",&B);
int len=0,x;
x=A;
//计算输入值的长度
while(x)
{
x=x/10;
len++;

}
printf("%d",len);
MULTIPLY(&C,&A,&B,len);
return 0;
}

tondayong1981 2005-12-08
  • 打赏
  • 举报
回复
大家帮帮我啊, 不要就我一个人自问自答
tondayong1981 2005-12-08
  • 打赏
  • 举报
回复
加法
void (int *C,int *A,int *B,unsigned int N)
{
int ireg=0;
for(int i=N-1;i>=0;i--)
{
ireg=A[i]+B[i]+(ireg)/10;;
C[i]=ireg%10;
}


}
减法我已经晕了,我连138-197相减我都搞不轻怎么减的了
tondayong1981 2005-12-08
  • 打赏
  • 举报
回复
加,减,我可以实现,但是移位我不能怎么办,关键以前连益出数据的意识都没有.
我把大数的加减法,做出,你在帮我看看.我的A和B用整形数组来存合适吗??
gxqcn 2005-12-08
  • 打赏
  • 举报
回复
原代码:
(*C)=m1*pow(10,len)+(m1+m2+m3)*pow(10,len/2)+m3;
printf("C=%d\n",*C);
应改为:
(*C)=m1*pow(10,(len>>1)<<1)+(m1+m2+m3)*pow(10,len/2)+m3;
printf("C=%d\n",*C);

公式没吃透!(最好是自己推导一遍)

这是 Karatsuba 大数乘法,必须先实现大数的加、减、移位等算法,而后才方便实现。
(绝不可使用 pow 函数来位运算,否则非常受局限)
tondayong1981 2005-12-08
  • 打赏
  • 举报
回复
可能是我写的不对,或者是其他原因。但是这个算法就是进行大整数相乘的快速算法,由于老师限制原型,所以我必须把原形中的各个变量变成相应的整形。而不能用字符性,因为老师回用十进制数据来测试我的程序来证明正确性。大家能帮我的就帮我把,我实在无能为力啊
chengzanmiao 2005-12-07
  • 打赏
  • 举报
回复
mark
順便問下倆個很大數的乘法算法?希望有大俠路過解答!~
Mr_Yang 2005-12-07
  • 打赏
  • 举报
回复
mark
jixingzhong 2005-12-07
  • 打赏
  • 举报
回复
这个算法,限定了数据的长度是 2 次方的 ...
也就是说,算法不是很... 的
tycoona 2005-12-07
  • 打赏
  • 举报
回复
没有明白楼主的意思,是不是乘积溢出了,要不就用链表表示把,每个节点保存一位数。然后打印链表,肯定不会溢出。不过要判断每位数需不需要进位,如果进位的话,就新增节点保存之。
tondayong1981 2005-12-07
  • 打赏
  • 举报
回复
没有啊,没错啊,我重新测试了,好象是其他的地方有错,我没找出.我该怎么进行大整数的相乘呢?前提是用我上面写的递归,因为这是个快速乘法,是karatsuba算法.一遇到益出,我不会处理啊,连基本的思路也没有.大家帮帮我啊,我现在是无从下手.
jixingzhong 2005-12-07
  • 打赏
  • 举报
回复
#include<stdio.h>
#include<math.h>
void MULTIPLY(long *C,long *A,long *B,int len)
{
long a,b,c,d;
long m1,m2,m3;
long sub1,sub2;
if(len==1)
{
*C=(*A)*(*B);
printf("c=%d\n",*C);
}
else
{

long multiply=pow(10,(len/2));
//A的左边len/2位
a=((*A)/multiply);
//A的右边len/2位
b=((*A)%multiply);
//A的左边len/2位
c=((*B)/multiply);
//A的右边len/2位
d=((*B)%multiply);
sub1=a-b;
sub2=d-c;
MULTIPLY(&m1,&a,&c,len/2);
MULTIPLY(&m2,&sub1,&sub2,len/2);
MULTIPLY(&m3,&b,&d,len/2);
(*C)=m1*pow(10,len)+(m1+m2+m3)*pow(10,len/2)+m3;
printf("C=%d\n",*C);


}

}
int main()
{
//输入的A和B的长度相同
long A,B,C;

scanf("%ld",&A);
scanf("%ld",&B);
int len=0,x;
x=A/10;
//计算输入值的长度
while(x)
{
len++;
x=x/10;
}
//printf("%d",len);
MULTIPLY(&C,&A,&B,len); /*这里!len 这个长度错了*/
return 0;
}
jixingzhong 2005-12-07
  • 打赏
  • 举报
回复
chengzanmiao(高薪為共產當多納稅) ( ) 信誉:100 2005-12-07 12:53:00 得分: 0


mark
順便問下倆個很大數的乘法算法?希望有大俠路過解答!~

---------
巨型数的类,都带有基本运算的。
自己写一个巨型数的类也不麻烦 。
tondayong1981 2005-12-07
  • 打赏
  • 举报
回复
按照上面的算法,我初步写了一下,不过只能计算很小的数,而且输入数据为奇数个,好象结果不对???
大家帮我看看到底该怎么写,我关键不知大数该怎么处理,能力有限,望高手们帮忙??谢谢。
#include<stdio.h>
#include<math.h>
void MULTIPLY(long *C,long *A,long *B,int len)
{
long a,b,c,d;
long m1,m2,m3;
long sub1,sub2;
if(len==1)
{
*C=(*A)*(*B);
printf("c=%d\n",*C);
}
else
{

long multiply=pow(10,(len/2));
//A的左边len/2位
a=((*A)/multiply);
//A的右边len/2位
b=((*A)%multiply);
//A的左边len/2位
c=((*B)/multiply);
//A的右边len/2位
d=((*B)%multiply);
sub1=a-b;
sub2=d-c;
MULTIPLY(&m1,&a,&c,len/2);
MULTIPLY(&m2,&sub1,&sub2,len/2);
MULTIPLY(&m3,&b,&d,len/2);
(*C)=m1*pow(10,len)+(m1+m2+m3)*pow(10,len/2)+m3;
printf("C=%d\n",*C);


}

}
int main()
{
//输入的A和B的长度相同
long A,B,C;

scanf("%ld",&A);
scanf("%ld",&B);
int len=0,x;
x=A/10;
//计算输入值的长度
while(x)
{
len++;
x=x/10;
}
//printf("%d",len+1);

MULTIPLY(&C,&A,&B,len+1);

return 0;


}
petertangpei 2005-12-07
  • 打赏
  • 举报
回复
楼上的好象是台湾同胞
cunsh 2005-12-06
  • 打赏
  • 举报
回复
看半天没看懂...
widowss 2005-12-06
  • 打赏
  • 举报
回复
好像很类似大矩阵相乘的算法
加载更多回复(2)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧