一个标定素数的小程序,运行结果自相矛盾,没找到出错原因,求助? 400 报错
各位前辈,我是初学菜鸟,今天编了一个标定素数的小程序,运行结果自相矛盾,没找到出错原因,求助
该程序在100以内貌似都正常,从103开始,以及107、109等素数都未能标定出来,详见截屏。
另,我的电脑上运行cmd.exe时窗口只有一半宽,点全屏也没用,同样求助。
谢谢大侠指点。
追加:目测代码逻辑完全没错,只是K值的问题,long类型的K值因为不断的相乘,超过long的上限值,恭喜,在某一次相乘的时候,k值duang一下变成0了,所以,换一种方法吧,题主可以自己断点测试一下,最后k是变成0的######回复 @月生无界 : 客气客气######回复 @月影南溪 : 感谢提出######数据溢出不会变0的######
月生无界正确地说出了long 型的取值范围。特此,我将从前写的代码展示如下, 来表明JAVA不同类型的变量的取值范围:
public class Limits{
public static void main(String args[]){
/* 打印六种数字基本类型变量的最大值和最小值 */
System.out.println("长型最大值 LONG_Max: " + Long.MAX_VALUE);
System.out.println("长型最小值 LONG_Min: " + Long.MIN_VALUE);
System.out.println("整型最大值 Int_Max: " + Integer.MAX_VALUE);
System.out.println("整型最小值 Int_Min: " + Integer.MIN_VALUE);
System.out.println("短型最大值 SHORT_Max: " + Short.MAX_VALUE);
System.out.println("短型最小值 SHORT_Min: " + Short.MIN_VALUE);
System.out.println("字节型最大值 BYTE_Max: " + Byte.MAX_VALUE);
System.out.println("字节型最小值 BYTE_Min: " + Byte.MIN_VALUE);
//System.out.println("浮点型最大值 FLOAT_Max: " + Float.MAX_VALUE);
//System.out.println("浮点型最小值 FLOAT_Min: " + Float.MIN_VALUE);
//System.out.println("双精度型最大值 DOUBLE_Max: " + Double.MAX_VALUE);
//System.out.println("双精度型最小值 DOUBLE_Min: " + Double.MIN_VALUE);
}
}
输出:
长型最大值 LONG_Max: 9223372036854775807
长型最小值 LONG_Min: -9223372036854775808
整型最大值 Int_Max: 2147483647
整型最小值 Int_Min: -2147483648
短型最大值 SHORT_Max: 32767
短型最小值 SHORT_Min: -32768
字节型最大值 BYTE_Max: 127
字节型最小值 BYTE_Min: -128
..........
就拿计算阶乘为例,以下代码,可以检查JAVA 输出数据的有效性。
public class Factoria {
public static void main(String args[]) { //主方法代码块开始
int iFactoria=1; //用整型存储阶乘
long lFactoria=1; //用长型存储阶乘
for (int i=1; i<17;i++){ //用for循环语句输出1到16的阶乘
iFactoria *=i; //将i的阶乘存入整型变量
lFactoria *=i; //将i的阶乘存入长型变量
/* 分别输出存于整型变量和长型变量的阶乘 */
System.out.printf(" %d 的阶乘:\t %10d(int), %15d(long)\n",
i, iFactoria, lFactoria);
}
System.out.printf("最大整型:%12d, 最大长型: %d\n",
Integer.MAX_VALUE,Long.MAX_VALUE);
} //主方法 main 代码块结束结束
} // 类 Factoria 定义结束
输出:
1 的阶乘: 1(int), 1(long)
2 的阶乘: 2(int), 2(long)
3 的阶乘: 6(int), 6(long)
4 的阶乘: 24(int), 24(long)
5 的阶乘: 120(int), 120(long)
6 的阶乘: 720(int), 720(long)
7 的阶乘: 5040(int), 5040(long)
8 的阶乘: 40320(int), 40320(long)
9 的阶乘: 362880(int), 362880(long)
10 的阶乘: 3628800(int), 3628800(long)
11 的阶乘: 39916800(int), 39916800(long)
12 的阶乘: 479001600(int), 479001600(long)
13 的阶乘: 1932053504(int), 6227020800(long)
14 的阶乘: 1278945280(int), 87178291200(long)
15 的阶乘: 2004310016(int), 1307674368000(long)
16 的阶乘: 2004189184(int), 20922789888000(long)
最大整型: 2147483647, 最大长型: 9223372036854775807
这里,
* 阶乘指从1乘以2乘以3乘以4一直乘到所要求的数。N的阶乘可表示为n!=1×2×3×……×n 或 n!=n×(n-1)!
* 用整型(int), 13的阶乘是: 6227020800,超过了 整型变量 int可以表示的最大正整数: 2147483647。 因此,13 或更大的阶乘数据,不能用整型int 表示。以上输出结果表明,用整型int变量存储的阶乘数据,若阶数超过12, 均不正确。
* 以上用长型变量输出的阶乘,尚且是正确的。但,它也有个限度, 17以上的阶乘, 就是“垃圾”了。
* 数学家定义,0!=1,所以0!=1!
package test; public class Test { public static void main(String[] args) { String num = "素数:"; for(int i=2;i<=1000;i++){ //特殊值处理 if(i == 2){ num += i+","; //System.out.println("素数:"+i); }else{ //素数判断条件,从2开始除,取余,如果余值为0,表示不是素数,跳出这个数的循环判断, for(int j=2;j<i;j++){ if(i%j == 0){ break; } //判断是否是素数,能除到比该值小一,且余数不为0,肯定是素数 if(i%j != 0 && j == i-1){ num += i+","; //System.out.println("素数:"+i); } } } } System.out.println(num); } }
//好人都是直接贴代码的
埃拉托色尼筛选法(Sieve of Eratosthenes) 也可以尝试。
import java.util.*; public class Eratosthenes{ // 埃拉托色尼筛选法 public static void main(String args[]){ int i,j; boolean b[]=new boolean[50]; for(i=0;i<b.length;i++) b[i]=true; //将数组的元素全部赋以true for ( i = 2; i < b.length; i++ ) // 从下标2开始递增循环 if ( b[ i ] ==true){// 每次找到值为true的元素 for (j =i+1;j < b.length;j++ ){ /* 就用其下标作为除数,去除往后余下的元素的下标*/ if (j%i == 0 ) //一旦能除尽 b[j] = false;// 将对应的元素值改为false } } for (i=2;i<b.length;i++ )//从2起,打印50以内的质数 if (b[ i ]) //若元素值为true System.out.printf("%4d", i);// 打印出该元素的下标 } }
我已经将 tcxu 和 月生无界 所出示的代码,翻译成 PHP, 运行结果证明两种算法有效。
http://www.oschina.net/code/snippet_2756874_56652
######查看楼主的代码发现, 你应当把 7 行的右花括号”}“,移到17行后边。这样,你的意向就对了:
从 第 9 行 至 第 17 行 处理 (k==0)的情况。从 18行 至 21 行,处理的是 (k != 0 的情况)
######k*(i%j)数值过大溢出了。for(long j=2;j<i;j++){ k=i%j if(k==0) System.out.print(" "+i+"不是素数,有约数:"); break }
不明白 ”k*(i%j)数值过大溢出了” 的情况 是什么情况? 指的是 这里的数值过大? 超过了 long型所能存储的最大数值 (2的63次方减 1)? 这里的数值并不大呀。
我这里没有安装Java环境,所以,参照楼主的代码,写出java脚本 代码,JavaScript 如下:
测试证明,楼主确实应当把 11 行 的 右花括号 ’ } ‘,移到 17 行:System.out.println(); 的后面。
<html>
<head>
<meta charset="gb2312">
<title>求1000以内的素数</title>
<style>
</style>
</head>
<body>
<script>
var n=1;
for (var i=1; i<1000;i++){
var k=1;
for (var j=2;j<i;j++){
k=k*(i%j);
}
if (k==0){ //处理 不是素数的情况
document.write( i + " 不是素数,有约数: ");
for (var j=2;j<i;j++)
if (i%j==0){
document.write( j + " "); }
document.write("<br>");
} else if (k !=0){ //处理素数的情况
document.write( "第 " + n + " 个素数是:" + i + "<br>");
n++;
}
}
</script>
</body>
</html>
月生无界正确地说出了long 型的取值范围。特此,我将从前写的代码展示如下, 来表明JAVA不同类型的变量的取值范围:
public class Limits{
public static void main(String args[]){
/* 打印六种数字基本类型变量的最大值和最小值 */
System.out.println("长型最大值 LONG_Max: " + Long.MAX_VALUE);
System.out.println("长型最小值 LONG_Min: " + Long.MIN_VALUE);
System.out.println("整型最大值 Int_Max: " + Integer.MAX_VALUE);
System.out.println("整型最小值 Int_Min: " + Integer.MIN_VALUE);
System.out.println("短型最大值 SHORT_Max: " + Short.MAX_VALUE);
System.out.println("短型最小值 SHORT_Min: " + Short.MIN_VALUE);
System.out.println("字节型最大值 BYTE_Max: " + Byte.MAX_VALUE);
System.out.println("字节型最小值 BYTE_Min: " + Byte.MIN_VALUE);
//System.out.println("浮点型最大值 FLOAT_Max: " + Float.MAX_VALUE);
//System.out.println("浮点型最小值 FLOAT_Min: " + Float.MIN_VALUE);
//System.out.println("双精度型最大值 DOUBLE_Max: " + Double.MAX_VALUE);
//System.out.println("双精度型最小值 DOUBLE_Min: " + Double.MIN_VALUE);
}
}
输出:
长型最大值 LONG_Max: 9223372036854775807
长型最小值 LONG_Min: -9223372036854775808
整型最大值 Int_Max: 2147483647
整型最小值 Int_Min: -2147483648
短型最大值 SHORT_Max: 32767
短型最小值 SHORT_Min: -32768
字节型最大值 BYTE_Max: 127
字节型最小值 BYTE_Min: -128
..........
就拿计算阶乘为例,以下代码,可以检查JAVA 输出数据的有效性。
public class Factoria {
public static void main(String args[]) { //主方法代码块开始
int iFactoria=1; //用整型存储阶乘
long lFactoria=1; //用长型存储阶乘
for (int i=1; i<17;i++){ //用for循环语句输出1到16的阶乘
iFactoria *=i; //将i的阶乘存入整型变量
lFactoria *=i; //将i的阶乘存入长型变量
/* 分别输出存于整型变量和长型变量的阶乘 */
System.out.printf(" %d 的阶乘:\t %10d(int), %15d(long)\n",
i, iFactoria, lFactoria);
}
System.out.printf("最大整型:%12d, 最大长型: %d\n",
Integer.MAX_VALUE,Long.MAX_VALUE);
} //主方法 main 代码块结束结束
} // 类 Factoria 定义结束
输出:
1 的阶乘: 1(int), 1(long)
2 的阶乘: 2(int), 2(long)
3 的阶乘: 6(int), 6(long)
4 的阶乘: 24(int), 24(long)
5 的阶乘: 120(int), 120(long)
6 的阶乘: 720(int), 720(long)
7 的阶乘: 5040(int), 5040(long)
8 的阶乘: 40320(int), 40320(long)
9 的阶乘: 362880(int), 362880(long)
10 的阶乘: 3628800(int), 3628800(long)
11 的阶乘: 39916800(int), 39916800(long)
12 的阶乘: 479001600(int), 479001600(long)
13 的阶乘: 1932053504(int), 6227020800(long)
14 的阶乘: 1278945280(int), 87178291200(long)
15 的阶乘: 2004310016(int), 1307674368000(long)
16 的阶乘: 2004189184(int), 20922789888000(long)
最大整型: 2147483647, 最大长型: 9223372036854775807
这里,
* 阶乘指从1乘以2乘以3乘以4一直乘到所要求的数。N的阶乘可表示为n!=1×2×3×……×n 或 n!=n×(n-1)!
* 用整型(int), 13的阶乘是: 6227020800,超过了 整型变量 int可以表示的最大正整数: 2147483647。 因此,13 或更大的阶乘数据,不能用整型int 表示。以上输出结果表明,用整型int变量存储的阶乘数据,若阶数超过12, 均不正确。
* 以上用长型变量输出的阶乘,尚且是正确的。但,它也有个限度, 17以上的阶乘, 就是“垃圾”了。
* 数学家定义,0!=1,所以0!=1!
真有耐心,我只做了一个简单的测试,发现一些有趣的事情,希望得到正确的解答
上代码
long min = -9223372036854775808L; long max = 9223372036854775807L; System.out.println(min*1+","+min*2+","+min*3+","+min*4); System.out.println(max*1+","+max*2+","+max*3+","+max*4);
结果:-9223372036854775808,0,-9223372036854775808,0
9223372036854775807,-2,9223372036854775805,-4
long的最小最大值从1乘到4,会出现各种结果,不是很懂其中的原理
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。