模幂运算
Modular Exponentiation
本文关键字:运算 更新时间:2023-10-16
我试图使用这种方法来分解具有大指数的基数,因为标准c++库中的数据类型不存储那么大的数字。
问题是在最后一个循环中,我使用fmod()
函数对我的大数进行建模。答案应该是1,但我得到的是16。有人发现问题了吗?
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
typedef vector<int> ivec;
ivec binStorage, expStorage;
void exponents()
{
for (int j=binStorage.size(); j>=0; j--)
if(binStorage[binStorage.size()-j-1]!=0)
expStorage.push_back(pow(2, j));
}
void binary(int number)
{
int remainder;
if(number <= 1)
{
cout << number;
return;
}
remainder = number%2;
binary(number >> 1);
cout << remainder;
binStorage.push_back(remainder);
}
int main()
{
int num = 117;
int message = 5;
int mod = 19;
int prod = 1;
binary(num);
cout << endl;
exponents();
cout << "nExponents: " << endl;
for (int i=0; i<expStorage.size(); i++)
cout << expStorage[i] << " " ;
cout << endl;
cout << "nMessage" << "-" << "Exponent" << endl;
for (int i=0; i<expStorage.size(); i++)
{
cout << message << "-" << expStorage[i] << endl;
prod *= fmod(pow(message, expStorage[i]), mod);
}
cout << "nAnswer: " << fmod(prod, mod) << endl;
return 0;
}
结果如下:
1110101
Exponents:
64 32 16 4 1
Message-Exponent
5-64
5-32
5-16
5-4
5-1
Answer: 16
Process returned 0 (0x0) execution time : 0.085 s
Press any key to continue.
编辑:下面是问题循环。
for (int i=0; i<expStorage.size(); i++)
{
cout << message << "-" << expStorage[i] << endl;
prod *= fmod(pow(message, expStorage[i]), mod);
}
您发布的算法是模幂算法。按照您发布的链接中的步骤,该算法缩减为以下代码段:
#include <iostream>
#include <cmath>
// B : Base
// E : Exponent
// M : Modulo
constexpr int powermod(int const B, int const E, int const M) {
return ((E > 1) ? (powermod(B, E / 2, M) * powermod(B, E / 2, M) * powermod(B, E % 2, M)) % M
: (E == 0) ? 1 : B % M);
}
int main() {
int const e = 117;
int const b = 5;
int const m = 19;
std::cout << "Answer: " << powermod(b, e, m) << std::endl;
return 0;
}
注意,我使用了constexpr
。如果你的编译器不支持它,你可以移除它。使用constexpr
,并且假定输入参数是常量表达式,如上面的例子,幂指数的计算将在编译时进行。
现在关于你发布的代码:
似乎
fmod
不能很好地与(5^32
和5^64
)这样的大数字一起工作,并给出错误的结果。你的代码也遭受编译错误和运行时错误,所以我纠正了它。
我编写了一个基于递归计算模的算法。基本上是我上面发布的算法的一个变体,安全防护功率为4。(见下面的
safemod()
函数):
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
typedef vector<int> ivec;
// B : Base (e.g., 5)
// E : Exponent (e.g., 32)
// M : Modulo (e.g., 19)
double safemod(double B, double E, double M) {
return ((E > 4) ? fmod(safemod(B, E / 2, M) * safemod(B, E / 2, M), M)
:
fmod(pow(B, E), M));
}
void exponents(ivec const &binStorage, ivec &expStorage) {
int j(pow(2.0, binStorage.size() - 1));
for (vector<int>::const_iterator it(binStorage.begin()), ite(binStorage.end()); it != ite; ++it) {
if (*it != 0) expStorage.push_back(j);
j /= 2;
}
}
void binary(int const number, ivec &binStorage) {
if (number > 0) {
int remainder = number % 2;
binary(number / 2, binStorage);
binStorage.push_back(remainder);
}
}
int main() {
int num = 117;
int message = 5;
int mod = 19;
int prod = 1;
ivec binStorage, expStorage;
binary(num, binStorage);
for (size_t i(0); i < binStorage.size(); ++i) cout << binStorage[i];
cout << endl;
exponents(binStorage, expStorage);
cout << "nExponents: " << endl;
for (size_t i(0); i<expStorage.size(); ++i) cout << expStorage[i] << " ";
cout << endl;
cout << "nMessage" << "-" << "Exponent" << endl;
for (size_t i(0); i<expStorage.size(); ++i) {
cout << message << "-" << expStorage[i] << endl;
prod *= safemod(message, expStorage[i], mod);
}
cout << "nAnswer: " << fmod(prod, mod) << endl;
return 0;
}
输出:1110101
指数:64 32 16 4 1
Message-Exponent
5 - 64
5 - 32
5 - 16
5 - 1
回答:1
相关文章:
- 使用C++中的模板和运算符重载执行矩阵运算
- GCC本机矩阵运算库
- 位阵列上的快速AND运算
- 字符串中int的加法运算
- 算术运算的结果类似于:C浮点变量中的1/3
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何在两个 boost::multi_arrays (C++) 之间执行数学运算?
- 如何在 vtk Poly 数据上进行布尔运算?
- MSVC 无法根据模板参数进行数学运算,这是一个错误吗?
- 避免指针运算,修复叮当整齐错误
- 使用双精度的浮点运算
- 如何在 c++ 中使用带有数学运算的引用/指针?
- 更快的C++算术运算
- 是否存在用于 C 或 C++ 中常见数学运算(例如最小值、最大值和平均值)的可导入库?
- 为什么循环体中的一个基本算术运算执行得比两个算术运算慢
- 两个字符串之间的数学运算
- 为什么对无符号字符进行算术运算会将它们提升为有符号整数
- 何时使用按位运算而不是算术替代方法?
- Arduino 上数学运算的计时速度 - 异常
- 如何使用按位运算将随机uint64_t转换为范围 (0, 1) 的随机双精度