java解惑之表达式之谜(谜题3)

谜题3:长整除

该谜题涉及两个long型数值进行整除,所以称为长整除。先看看典型代码:

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,这是什么原因呢?

问题在于常数MICROS_PER_DAY的计算溢出了。虽然计算的结果放入long中,空间还有多余,但是这个结果并不适合放入int中,而恰巧的是整个计算的过程都是以int数值来进行运算的,在运算结束后,其结果才被提升为long。而此时早在计算时就已经溢出了,所以最终long里面的数值是一个比预期数值小了200倍的数,而MILLIS_PER_DAY的计算是正确的,所以最后打印的值比预期的值小了200倍,是5。

那么为什么计算是以int运算来执行的呢?因为所有进行运算的因子都是int类型的,所以当所有数运算完之后最开始的值是int类型的(此时发生溢出),之后才提升为long类型,所以,根据这个情况,我们可以将int类型的运算转换成long类型的变量,将代码改成如下即可:

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 );

    }

}

这个示例告诉我们,当你在操作很大的数字时,千万要提防溢出。即使用来保存结果的变量已足够大,也并不意味着要产生结果的计算具有正确的类型。当你拿不准时,就使用long运算来执行整个运算。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值