| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 31024 人关注过本帖
标题:各位老师好!求助编辑一个大整数的快速乘除法可调用程序
取消只看楼主 加入收藏
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
回复 76楼 smitest
搜索不到,是qq还是微信?
2020-02-18 01:19
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
回复 71楼 wmf2014
您好!有qq或微信吗?欢迎联系!大整数的快速乘法除法程序至今我也弄不出来,请帮忙!
2020-02-18 10:23
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
回复 79楼 wmf2014
谢谢!已经不错了,辛苦了!我的除法没有其它功能,只是分类计算的,比如除数小于8位的就转为MCC()了。可能是这样吧,也是调试多少次多种类型才弄对的,有的类型过不去正常,只是一时找不到哪里错,慢慢会找到的,你可以重新编个除法程序,谢谢!
2020-02-18 12:33
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
输出余数的除法结果:123456789876543/987654321=124999/987405864,
输出带小数点的除法:123456789876543/987654321=124999.9997484372。
2020-02-18 12:53
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
我的除法只算到整数部分,要得到小数点后的商值被除数末尾必须补0,精确几位补几个0.
2020-02-18 12:57
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
回复 79楼 wmf2014
当余数为0的时候不要输出/0,因为判断是否整除的时候是以有没有/号为标准的,这一点要注意!
2020-02-18 18:41
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
回复 79楼 wmf2014
下面是网上找到的用vc编程的fft快速高精度乘法程序,我看不懂,请看看,翻译成vb可调用程序,谢谢!
#include<bits/stdc++.h>
using namespace std;
//complex是stl自带的定义复数的容器
typedef complex<double> cp;
#define N 2097153
//pie表示圆周率π
const double pie=acos(-1);
int n;
cp a[N],b[N];
int rev[N],ans[N];
char s1[N],s2[N];
//读入优化
int read(){
    int sum=0,f=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return sum*f;
}
//初始化每个位置最终到达的位置
{
    int len=1<<k;
    for(int i=0;i<len;i++)
    rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
}
//a表示要操作的系数,n表示序列长度
//若flag为1,则表示FFT,为-1则为IFFT(需要求倒数)
void fft(cp *a,int n,int flag){
    for(int i=0;i<n;i++)
    {
     //i小于rev[i]时才交换,防止同一个元素交换两次,回到它原来的位置。
      if(i<rev[i])swap(a[i],a[rev[i]]);
    }
    for(int h=1;h<n;h*=2)//h是准备合并序列的长度的二分之一
    {
    cp wn=exp(cp(0,flag*pie/h));//求单位根w_n^1
     for(int j=0;j<n;j+=h*2)//j表示合并到了哪一位
     {
      cp w(1,0);
       for(int k=j;k<j+h;k++)//只扫左半部分,得到右半部分的答案
       {
         cp x=a[k];
         cp y=w*a[k+h];
         a[k]=x+y;  //这两步是蝴蝶变换
         a[k+h]=x-y;
         w*=wn; //求w_n^k
       }
     }
     }
     //判断是否是FFT还是IFFT
     if(flag==-1)
     for(int i=0;i<n;i++)
     a[i]/=n;
}
int main(){
    n=read();
    scanf("%s%s",s1,s2);
    //读入的数的每一位看成多项式的一项,保存在复数的实部
    for(int i=0;i<n;i++)a[i]=(double)(s1[n-i-1]-'0');
    for(int i=0;i<n;i++)b[i]=(double)(s2[n-i-1]-'0');
    //k表示转化成二进制的位数
    int k=1,s=2;
     while((1<<k)<2*n-1)k++,s<<=1;
    init(k);
    //FFT 把a的系数表示转化为点值表示
    fft(a,s,1);
    //FFT 把b的系数表示转化为点值表示
    fft(b,s,1);
    //FFT 两个多项式的点值表示相乘
    for(int i=0;i<s;i++)
    a[i]*=b[i];
    //IFFT 把这个点值表示转化为系数表示
    fft(a,s,-1);
    //保存答案的每一位(注意进位)
    for(int i=0;i<s;i++)
    {
    //取实数四舍五入,此时虚数部分应当为0或由于浮点误差接近0
    ans[i]+=(int)(a[i].real()+0.5);
    ans[i+1]+=ans[i]/10;
    ans[i]%=10;
    }
    while(!ans[s]&&s>-1)s--;
    if(s==-1)printf("0");
    else
    for(int i=s;i>=0;i--)
    printf("%d",ans[i]);
    return 0;
}
2020-02-18 23:23
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
回复 79楼 wmf2014
给出一个超大整数快速求商的原理图,您是否能编程vb版程序:
图片附件: 游客没有浏览图片的权限,请 登录注册

对于超大整数步骤是这样:
初始:c=0,i>=0
1,满足被除数>=2^i*除数,得到最大的i0.c=c+2^i0.
新的被除数=被除数-2^i0*除数。
2,满足新被除数>=2^i*除数的最大的i1.c=c
3,若2^0=1>=2^i的i不存在,则商c=c+2^0.
我是这么理解的。
速度取决于求2^i的速度,以及比较大小的速度,行不行?请指导!
(我的理解第一步和第二步都是迭代,第三步i已经等于0,无需迭代仅是个判断。)

[此贴子已经被作者于2020-2-19 06:24编辑过]

2020-02-19 06:05
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
我觉得i不用从0开始算就可以得到i0及i1,方法:
被除数的位数减掉除数的位数,设差为x,x乘以0.3010就是i,因为log2=0.3010,而x*log2是2^i的位数,此时结果要小一点,比如减1或2,再迭代就可以减少迭代次数,(试了一下,不对,太大,应该令x1=x+1,迭代,当x1*log2=x时的x1的值。)
下一步类似,求出i1的近似值,要小于i1,就是新被除数的位数减掉除数的位数 ,再用上面的方法求出i1的近似值再迭代,直到i等于0为止。
当然,若被除数的位数和除数的位数的比值是1,那就可以从0开始算了。
我先试一下,如果成立把程序发一下,请您优化一下。

[此贴子已经被作者于2020-2-19 10:01编辑过]

2020-02-19 07:04
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
这种方法不能实现,速度也许快,弄不准确,第一步就无法调整,多乘一次2则过大,远大于实际,少乘一次又过小。请把我发在84楼的vc程序翻译成vb程序吧,谢谢!欢迎指导!欢迎沟通!
2020-02-19 11:33
快速回复:各位老师好!求助编辑一个大整数的快速乘除法可调用程序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016023 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved