java – 算法找到所有素数从2到1000不起作用
发布时间:2020-12-14 05:32:58 所属栏目:Java 来源:网络整理
导读:这是一段代码,使用该语句计算所有素数从2到1000,数字n是素数iff: 在第一个版本中,我认为我正确地实现了算法: public class Giuga { public static void main(String[] args){ int n = 2; while(n=1000){ int k = 1; long sum = 0; while(k=n-1){ sum = sum
这是一段代码,使用该语句计算所有素数从2到1000,数字n是素数iff:
在第一个版本中,我认为我正确地实现了算法: public class Giuga { public static void main(String[] args){ int n = 2; while(n<=1000){ int k = 1; long sum = 0; while(k<=n-1){ sum = sum+(long)Math.pow((double)k,(double)n-1); k++; } if(sum%n==n-1){ System.out.println(n + " is a prime."); } n++; } } } 但是,由于变量总和快速增长,所以溢出发生,而在素数17之后,将不再有输出. 为了防止我不得不使用这个: 嗯,我做到了,这里是我的2.版本: public class Giuga { public static void main(String[] args){ int n = 2; while(n<=1000){ int k = 1; long sum = 0; while(k<=n-1){ sum = sum+((long)Math.pow((double)k%n,(double)n-1))%n; //Here are the changes k++; } if(sum%n==n-1){ System.out.println(n + " is a prime."); } n++; } } } 我想我做的很正确,但现在输出在素数13之后停止. 现在我试图找到我的错误了一段时间.我究竟做错了什么? 解决方法
如已经指出的那样,只有大约16位精度的双精度不够精确,不足以维持足够数量的计算的正确余数.
您可以切换到longs并执行您自己的模幂运算. int k = 1; long sum = 0; while(k<=n-1){ long pow = 1; for (int i = 0; i < n - 1; i++) pow = (pow * k) % n; sum = (sum + pow)%n; k++; } 这种算法可以通过将这种直接的模幂变换通过重复平方使用模幂运算来改进,而不是最有效的求主算法,但现在是正确的. 2 is a prime. 3 is a prime. 5 is a prime. 7 is a prime. 11 is a prime. 13 is a prime. 17 is a prime. 19 is a prime. 23 is a prime. 29 is a prime. 31 is a prime. (剪断) 977 is a prime. 983 is a prime. 991 is a prime. 997 is a prime. 通过重复平方得到模幂运算,替换 long pow = 1; for (int i = 0; i < n - 1; i++) pow = (pow * k) % n; 同 long pow = 1; long square = k; int exp = n - 1; while (exp > 0) { if ((exp & 1) == 1) { pow = (pow * square) % n; } square = (square * square) % n; exp >>= 1; } 它连续测试指数的每一位,如果设置,将当前平方和乘以pow. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |