C 涉及Wilson'的素性检验;s定理没有按计划工作
我刚刚开始编程,遇到了一个似乎无法解决的问题。我编写了这个函数,C 涉及Wilson'的素性检验;s定理没有按计划工作,c,C,我刚刚开始编程,遇到了一个似乎无法解决的问题。我编写了这个函数,isPrime,它似乎总是通过平等性测试。我可以确认,factorial函数是有效的,因为我已经单独测试了它 威尔逊定理指出,如果(p-1)!+1是p的倍数 #include <stdio.h> #include <math.h> void isPrime(double p); double factorial(double n); int main(void) { double userInpu
isPrime
,它似乎总是通过平等性测试。我可以确认,factorial
函数是有效的,因为我已经单独测试了它
威尔逊定理指出,如果(p-1)!+1是p的倍数
#include <stdio.h>
#include <math.h>
void isPrime(double p);
double factorial(double n);
int main(void) {
double userInput;
while(1) {
scanf("%lf", &userInput);
isPrime(userInput);
}
return 0;
}
//
double factorial(double n) {
if(n <= 1)
return n;
else
return n * factorial(n - 1);
}
void isPrime(double p) {
if(modf(factorial(p - 1) + 1, &p) == 0)
printf("Prime!\n");
else
printf("Not prime!\n");
}
#包括
#包括
无效质(双p);
双阶乘(双n);
内部主(空){
双用户输入;
而(1){
scanf(“%lf”、&userInput);
iPrime(用户输入);
}
返回0;
}
//
双阶乘(双n){
如果(nmodf
不能像您期望的那样执行模数。引用:
The modf() break value into integral and fractional parts, each of which
has the same sign as the argument. They return the fractional part, and
store the integral part (as a floating-point number) in the object
pointed to by iptr
不要使用双精度来保存整数。舍入错误将使相等测试完全是假的。请参阅“”。我猜您的阶乘函数返回0,因为(n您的代码中有一个小错误
将测试更改为以下内容:
if (modf((factorial(p - 1) + 1)/p, &p) == 0)
另外,正如其他人指出的,使用双精度可能不是最好的方法。double
如果n大于23左右,则无法准确存储阶乘。从那时起,您的结果将完全是假的。如果您想使用威尔逊定理进行素性测试,请使用模运算
uint64_t modFactorial(uint64_t n, uint64_t m) {
uint64_t f = 1;
for(; n > 1; --n) {
f = (n*f) % m;
}
return f;
}
int isPrime(uint64_t p) {
if (p < 2) return 0;
return modFactorial(p-1,p) + 1 == p;
}
uint64-modFactorial(uint64-n,uint64-m){
uint64_t f=1;
对于(;n>1;--n){
f=(n*f)%m;
}
返回f;
}
int iPrime(uint64\u t p){
if(p<2)返回0;
返回因子(p-1,p)+1==p;
}
它可以正确地处理小于2^32的输入。然而,它相当慢,威尔逊定理在实践中不是检验素性的好方法,它的价值在于在数论中的应用
如果您需要处理大整数,请使用GMP(随-概率-素性测试一起提供)。您是否尝试打印收到的内容?(printf(“%lf Prime!\n”,p)
)这段代码不适用于大数的素性测试。我需要这段代码来处理非常大的数,大于一个int所能容纳的数。顺便感谢链接!@isosine,对大的非单整数使用unsigned long long
。使用double
是完全没有用的。@isosine:如果你使用double
你的非常大的数字将是近似值,因此您的测试将完全没有意义。您可能需要使用一些大整数库(例如GMP).噢,哇,我还没意识到还有另一个这样的函数。真是个误会。无论如何,非常感谢!这似乎解决了问题。@isosine如果我的回答解决了你的问题,请接受:)