1.奇偶性
public static boolean isOdd(int i){
return i%2==1;
}
这个程序并不一定获得正确答案,因为i有可能是负数。
健壮的写法是这样;
return i%2!=0;
或者这样:
return (i&1)!=0;
2.找零
System.out.println(2.0-1.10);
它不会打印出0.9,更不会打印出0.90.打印出的是0.8999999999999999。
因为1.1这个数字不能精确的表示成为一个double,它被表示成最接近它的double值。
java有两个办法来解决这个问题。一个是用int
System.out.println(200-110);
一个是用java.math.BigDecimal
System.out.println(new BigDecimal("2.0")-new BigDecimal("1.10"));
总之,在需要精确答案的地方,要避免使用float和double
3.长整除
这是一个关于两个long型值的整除。
被除数是一天里的微妙数,除数是一天里的毫秒数
public static void devide(){
final long MICROS_PER_DAY=24*60*60*1000*1000;
final long MILLIS_PER_DAY=24*60*60*1000;
System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);
}
结果应该是1000才对。但是不是。
问题出在了MICROS_PER_DAY的计算溢出了。尽管计算的结果适合放在long中,但是并不适合放在int中。
在计算过程中始终是以int运算执行的,只有在运算完成之后,结果才被提升到long,但是已经溢出。
最后返回的是小了200倍的数。从int提升到double是拓宽的类型转换。
为什么会这样呢?因为计算一直都是按int运算的,并且java不具有目标确定类型的特性。这是一种语言性质
指计算所使用的类型不会受存储结果的变量的类型影响。那是不是应该影响影响呢?各有各的看法。
正确的写法:
public static void devide(){
final long MICROS_PER_DAY=24L*60*60*1000*1000;
final long MILLIS_PER_DAY=24L*60*60*1000;
System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);
}
从开始我们就用Long型计算。
当在操作很大的数字的时候,千万要提防溢出,这是一个缄默的杀手。。。
java之父在《java 解惑》中是这么说的:
语言设计者从中可以吸取的教训是:也许降低缄默溢出产生的可能性确实是值得做的一件事。
这可以通过对不会产生缄默溢出的运算提供支持来实现。程序可以抛出一个异常而不是直接溢出,就像 Ada 所作的那样,
或者它们可以在需要的时候自动地切换到一个更大的内部表示上以防止溢出,就像 Lisp 所作的那样。
这两种方式都可能会遭受与其相关的性能方面的损失。降低缄默溢出的另一种方式是支持目标确定类型,但是这么做会显著地增加类型系统的复杂度