C++ 如何提高大整数乘法的效率?
这个周末,我按照程序实现了基本的大整数乘法。我使用Toom-3算法来实现。但开始时出乎意料地花费的时间比长乘法(小学乘法)慢,而且一去不复返了。我希望这个程序能在500位以内完成小学乘法,请问我该怎么办 我尝试优化,保留向量容量并删除多余代码。但效果不是很好 我应该使用C++ 如何提高大整数乘法的效率?,c++,algorithm,performance,multiplication,biginteger,C++,Algorithm,Performance,Multiplication,Biginteger,这个周末,我按照程序实现了基本的大整数乘法。我使用Toom-3算法来实现。但开始时出乎意料地花费的时间比长乘法(小学乘法)慢,而且一去不复返了。我希望这个程序能在500位以内完成小学乘法,请问我该怎么办 我尝试优化,保留向量容量并删除多余代码。但效果不是很好 我应该使用向量作为我的基本数字吗 整个源代码如下所示: typedef long long BigIntBase; typedef向量BigIntDigits; //ceil(数字限制::数字10/2.0)-1; 静态常数整数位数\u基数\
向量作为我的基本数字吗
整个源代码如下所示:
typedef long long BigIntBase;
typedef向量BigIntDigits;
//ceil(数字限制::数字10/2.0)-1;
静态常数整数位数\u基数\u长度=9;
//b
静态常量BigIntBase位\u base=100000000;
类BigInt{
公众:
BigInt(整数位数+容量=0,布尔内加=false){
负=负;
位数。保留(位数+容量);
}
BigInt(BigIntDigits _digits,bool nega=false){
负=负;
位数=_位数;
}
BigInt(常数范围和范围,布尔内加=假){
负=负;
digits=BigIntDigits(range.begin(),range.end());
}
BigInt运算符+(常量BigInt和rhs){
如果((*this.negative==rhs.negative)
返回BigInt(加上(*this.digits,rhs.digits),(*this.negative);
if(更大((*此.位,右.位))
返回BigInt(减((*this.digits,rhs.digits),(*this.negative);
返回BigInt(减(rhs.digits,(*this.digits),rhs.negative);
}
BigInt运算符-(const-BigInt&rhs){return*this+BigInt(rhs.digits,!rhs.negative);}
BigInt运算符*(常量BigInt和rhs){
if((*this).digits.empty()| | rhs.digits.empty()){
返回BigInt();
}else如果((*this.digits.size()==1&&rhs.digits.size()==1){
BigIntBase val=(*this.digits[0]*rhs.digits[0];
返回BigInt(val数字.empty())
返回“0”;
细流ss;
如果(此->负)
ss digits.rbegin()+1;it!=this->digits.rend();+it)
ss w?lhs[w]:0)-(rhs.size()>w?rhs[w]:0);
对于(int w=0;w=0;--w){
result.digits.insert(result.digits.begin(),提醒[w]/除数);
提醒[w-1]+=(提醒[w]%除数)*数字基数;
}
而(!result.digits.empty()&&!result.digits.back())
result.digits.pop_back();
返回结果;
}
BigInt乘法(常数BigInt&lhs,常数int乘法器){
BigInt结果(左侧数字,左侧负数);
对于(int w=0;w=数字基数){
如果(w+1==result.digits.size())
结果.数字.推回(结果.数字[w]/数字基数);
其他的
结果.数字[w+1]+=结果.数字[w]/数字基数;
结果:数字[w]=数字基数;
}
返回结果;
}
布尔更大值(常数大整数位数和左、常数大整数位数和右){
如果(lhs.size()==rhs.size()){
int w=lhs.size()-1;
而(w>=0&&lhs[w]==rhs[w])
--w;
返回w>=0&&lhs[w]>rhs[w];
}否则
返回lhs.size()>rhs.size();
}
};
数字
小学
Toom-3
10
4588
10003
50
24147
109084
100
52165
286535
150
92405
476275
200
172156
1076570
250
219599
1135946
300
320939
1530747
350
415655
1689745
400
498172
1937327
450
614467
2629886
500
863116
3184277
问题是,除了其他的toom3\u slice\u num
,您在这里可以使用std::span
(或std::对实际部分的迭代器),因为您给出的数字是常量<代码>toom3
也是分配器地狱
乘法
可能会再分配1次。数一数所需的位,或者只需在大小上加1
而且向量
s应该是pmr
(使用适当的分配器)以实现几乎无锁的分配
如果不使用-O2
或-O3
编译,所有这些都是浪费的。您是在计时发布还是优化版本?发布版本是什么?发布版本意味着您正在编译启用了优化的应用程序版本。由于发布容量
的默认参数为0,这最终调用了reserve(0)
,这并不能完成很多事情。在同一个构造函数中,digits=bigintdights()
也完全不做任何事情,因为数字
已经是默认构造的。不是很大的浪费,但却是一种浪费。另一个构造函数也不保留任何内容。因此,只要看一看,就会发现一些明显的疏忽,因此我认为其他算法可能也缺少明显的优化。根据编译器的不同,它可能需要一些类似