java解惑------长整除(解惑)

程序没有获得预期的输出,是因为常数MICROS_PER_DAY的计算确实溢出了。虽然计算的结果适合仿佛long中,并且其空间还有富余,但是这个结果并不适合放入int中。这个计算完全是以int运算来执行的,并且只有在运算完成之后,其结果猜被提升为long。而此时已经太迟:计算已经溢出,它返回的是一个小了200倍数的数值。从int提升为long是一种拓宽原生类转换,它保留了不正确的数值。这个值之后被MILLIS_PER_DAY整除,而MILLS_PER_DAY的计算结果是正确的,因为它适合int运算。于是整除结果为5.

 

那么为什么计算是以int来执行的呢?因为所有乘在一起的因子全是int数值。当两个int数值相乘时候,你将得到一个int数值。java不具有目标确定类型的特性,这是一种语言特性,其含义是指存储结果的变量类型会影响计算所使用的类型。

 

通过使用long常量来代替int常量作为每一个乘积的第一个因子,我们就可很容易的改正这个程序。这样做可以强制表达式中的所有后续计算都使用long运算来完成。尽管这么做只在MICROS_PER_DAY表达式中是必需的,但是在两个乘积中多这么做是一种很好的方式。相似的,使用long作为乘积的第一个数值也不是总必需的,但是这么做也是一种很好的形式。两个计算都已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);
    }
}  

 

将打印我们所预期的结果:1000

 

在操作很大的数字时候,千万要提防溢出,即使用来保存结果的变量已经足够大,也并不意味着产生的结果的计算具有正确的类型。

你可能感兴趣的:(java)