《Java解惑》系列——01表达式之谜——谜题03:长整除

知识点:

byte、short、int的四则运算的结果是int类型的。

问题:

下面的代码会打印什么:


// 一毫秒中有多少微妙
public class LongDivision{
	public static void main(String args[ ]){
		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
// 时间结果:5

结果是不是出乎大家的意料呢?的确如此。
产生这个结果的原因:

除数和被除数都是 long类型的,long类型大到了可以很容易地保存这两个乘积
而不产生溢出。因此,看起来程序打印的必定是 1000。  
遗憾的是,它打印的是5。这里到底发生了什么呢?  
问题在于常数MICROS_PER_DAY的计算“确实”溢出了。尽管计算的结果适合放
入long中,并且其空间还有富余,但是这个结果并不适合放入int中。这个计
算完全是以int运算来执行的,并且只有在运算完成之后,其结果才被提升到
long,而此时已经太迟了:计算已经溢出了,它返回的是一个小了200倍的数值。
从int提升到long是一种拓宽原始类型转换(widening primitive conversion),
它保留了(不正确的)数值。这个值之后被MILLIS_PER_DAY整除,而
MILLIS_PER_DAY的计算是正确的,因为它适合int运算。这样整除的结果就得
到了5。  
那么为什么计算会是以 int 运算来执行的呢?因为所有乘在一起的因子都是 int
数值。当你将两个 int 数值相乘时,你将得到另一个 int 数值。Java不具有目
标确定类型的特性,这是一种语言特性,其含义是指存储结果的变量的类型会影
响到计算所使用的类型。 


解决方法:

通过使用 long常量来替代 int常量作为每一个乘积的第一个因子


// 一毫秒中有多少微妙
public class LongDivision{
    public static void main(String args[ ]){
        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);
    }
}


总结:



当你在操作很大的数字时,千万要提防溢出。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值