一个标定素数的小程序,运行结果自相矛盾,没找到出错原因,求助

天天向上欣欣向荣 发布于 2016/05/29 12:04
阅读 496
收藏 0

各位前辈,我是初学菜鸟,今天编了一个标定素数的小程序,运行结果自相矛盾,没找到出错原因,求助

该程序在100以内貌似都正常,从103开始,以及107、109等素数都未能标定出来,详见截屏。

另,我的电脑上运行cmd.exe时窗口只有一半宽,点全屏也没用,同样求助。

谢谢大侠指点。

加载中
2
月生无界
月生无界
追加:目测代码逻辑完全没错,只是K值的问题,long类型的K值因为不断的相乘,超过long的上限值,恭喜,在某一次相乘的时候,k值duang一下变成0了,所以,换一种方法吧,题主可以自己断点测试一下,最后k是变成0的
月影南溪
月影南溪
回复 @月生无界 : 客气客气
月生无界
月生无界
回复 @月影南溪 : 感谢提出
月影南溪
月影南溪
数据溢出不会变0的
2
tcxu
tcxu

月生无界正确地说出了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循环语句输出116的阶乘

   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


0
阿信sxq
阿信sxq
算法有问题,怎么判断素数,这个数学问题先搞清楚,然后再写程序,要不然全是乱的
0
月生无界
月生无界
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);
	}
}

//好人都是直接贴代码的



0
tcxu
tcxu

埃拉托色尼筛选法(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);// 打印出该元素的下标
	}
}




0
tcxu
tcxu

我已经将 tcxu 和 月生无界 所出示的代码,翻译成 PHP, 运行结果证明两种算法有效。

http://www.oschina.net/code/snippet_2756874_56652

0
tcxu
tcxu

查看楼主的代码发现, 你应当把 7 行的右花括号”}“,移到17行后边。这样,你的意向就对了:

从 第 9 行 至 第 17 行 处理 (k==0)的情况。从 18行 至 21 行,处理的是 (k != 0 的情况)

0
Cobbage
Cobbage
k*(i%j)数值过大溢出了。
for(long j=2;j<i;j++){
     k=i%j
     if(k==0)
      System.out.print("          "+i+"不是素数,有约数:");
     break
}



0
tcxu
tcxu

不明白 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取值范围:-9223372036854775808 -到9223372036854775807,明天再测试一下,long的最大值再乘其他数在代码中是否会变成0返回
0
月生无界
月生无界

引用来自“tcxu”的评论

月生无界正确地说出了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循环语句输出116的阶乘

   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,会出现各种结果,不是很懂其中的原理



返回顶部
顶部