Java学习之路(五)--Thinking in Java

  写程序要细心,遇到bug要善于排查。

  今天在用Java写几个小程序的时候,由于极力追求优化与功效,忽视了一个小小的细节问题。但最终找到了bug并且解决了它。

  我们都知道,在使用for循环的时候,比如:

for(int i = 0; i < n; i++){...}

  我们一般都这儿写。但是仅仅这样是不够的,因为这段语句还可以进行优化。比如i<n,就不如直接判断i!=n,这样在计算机内部可以节省运算时间。还有,i++还可以改写成++i,因为i++需要计算机保存i之前的值之后再+1,++i直接让i+1并没有临时变量。可是,正因为如此,一个小小的不易察觉的bug发生了。

  原题目很简单,就是求整数a,b之间的全部素数。开始我是这么写的:

import java.io.*;
import java.util.*;
public class number2 {
	public static void main(String[] args) throws IOException{
		int begin, end;
		String str;
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		str = br.readLine();
		begin = new Integer(str);
		BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
		str = br1.readLine();
		end = new Integer(str);
		for (; begin != end; ++begin){
			boolean b = true;
			for(int i = 2; i != Math.sqrt(begin); ++i){
				if(0 == begin % i){
					b = false;
					break;
				}
			}
			if(b)
				System.out.println(begin);
		}
	}
}

注意仔细看代码着色部分,乍看之下没什么不对,追求了性能。可是运算的结果却是令人大吃一惊。求101到200的素数,出现121,169两个数。经过我仔细排查之后发现原来bug正是出在这里:Math.sqrt()是double,i是一个int,在与double的比较过程中是永远不相等的。或者我们把着色语句强制转换成(int),或者,改写成 i<Math.sqrt(begin)。

  修改之后成功运行,代码如下:

 1 import java.io.*;
 2 import java.util.*;
 3 public class number2 {
 4     public static void main(String[] args) throws IOException{
 5         int begin, end;
 6         String str;
 7         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 8         str = br.readLine();
 9         begin = new Integer(str);
10         BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
11         str = br1.readLine();
12         end = new Integer(str);
13         for (; begin != end; ++begin){
14             boolean b = true;
15             for(int i = 2; i < Math.sqrt(begin); ++i){
16                 if(0 == begin % i){
17                     b = false;
18                     break;
19                 }
20             }
21             if(b)
22                 System.out.println(begin);
23         }
24     }
25 }
关于代码中出现的输入输出流以后再做讨论。

原文地址:https://www.cnblogs.com/zhaoyansheng/p/4836375.html