java 解惑

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 所作的那样。

这两种方式都可能会遭受与其相关的性能方面的损失。降低缄默溢出的另一种方式是支持目标确定类型,但是这么做会显著地增加类型系统的复杂度




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值