Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何提高大整数乘法的效率?_C++_Algorithm_Performance_Multiplication_Biginteger - Fatal编程技术网

C++ 如何提高大整数乘法的效率?

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基数\

这个周末,我按照程序实现了基本的大整数乘法。我使用Toom-3算法来实现。但开始时出乎意料地花费的时间比长乘法(小学乘法)慢,而且一去不复返了。我希望这个程序能在500位以内完成小学乘法,请问我该怎么办

我尝试优化,保留向量容量并删除多余代码。但效果不是很好

我应该使用
向量
作为我的基本数字吗

整个源代码如下所示:

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()
也完全不做任何事情,因为
数字
已经是默认构造的。不是很大的浪费,但却是一种浪费。另一个构造函数也不保留任何内容。因此,只要看一看,就会发现一些明显的疏忽,因此我认为其他算法可能也缺少明显的优化。根据编译器的不同,它可能需要一些类似