确定性米勒-拉宾实现
Deterministic Miller-Rabin implementation
我正在尝试使用确定性的米勒-拉宾算法实现素数检查函数,但结果并不总是正确的:当检查前 1,000,000 个数字时,它只找到 78,495 而不是 78,498。
这是使用 [2, 7, 61] 作为基础获得的,根据维基百科,对于高达 4,759,123,141 的值应该始终正确。
有趣的是,缺少的 3 个素数正是构成基数的素数(2、7 和 61(。
为什么会这样?我使用的代码如下:
T modular_power(T base, T exponent, T modulo) {
base %= modulo;
T result = 1;
while (exponent > 0) {
if (exponent % 2 == 1)
result = (result * base) % modulo;
base = (base * base) % modulo;
exponent /= 2;
}
return result;
}
bool miller_rabin(const T& n, const vector<T>& witnesses) {
unsigned int s = 0;
T d = n - 1;
while (d % 2 == 0) {
s++;
d /= 2;
}
for (const auto& a : witnesses) {
if (modular_power<T>(a, d, n) == 1)
continue;
bool composite = true;
for (unsigned int r = 0; r < s; r++) {
if (modular_power<T>(a, (T) pow(2, r) * d, n) == n - 1) {
composite = false;
break;
}
}
if (composite)
return false;
}
return true;
}
bool is_prime(const T& n) {
if (n < 4759123141)
return miller_rabin(n, {2, 7, 61});
return false; // will use different base
}
当
基数和输入相同时,Miller-Rabin确实不起作用。在这种情况下发生的情况是,d mod n 为零(因为 mod n 为零,所以这实际上是将零提高到一些不相关的幂(,而算法的其余部分无法从零"转义"并得出结论,您正在处理一个复合物。
作为一个特例,Miller-Rabin 从不使用 2 的输入,因为没有可以选择的基数。 2本身是无用的,1也是无用的,那什么也没留下。
相关文章:
- 如果没有malloc,链表实现将失败
- 欧拉项目#8答案是大以获得有效答案
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 内存错误低于在C++年实现埃拉托色尼筛分时的预期
- 单元测试欧拉到四元数实现失败
- 筛子的埃拉托色尼错误实现
- 确定性米勒-拉宾实现
- 拉盖尔插值算法,我的实现有问题
- 米勒-拉宾素数测试 FIPS 186-3 实现
- 如何在Qt中实现下拉词建议
- 这个波拉德·罗实现有什么问题