预测以下程序的输出
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); } } |
解决方案:
除数和被除数都是long类型,它很容易大到足以容纳任意一个乘积而不会溢出。那么,程序似乎必须打印1000。不幸的是,它会打印 5. .这到底是怎么回事?问题是,计算每天的常量微秒确实会溢出。虽然计算的结果适合一个有空闲空间的long,但它不适合int。计算完全在int算法中执行,只有在计算完成后,结果才会提升为long。到那时,已经太晚了:计算已经溢出。 从int到long的提升是一种扩大的原语转换,它保留了(不正确的)数值。然后将该值除以每_天的毫_,该值的计算是正确的,因为它符合整数。此除法的结果是5。那么,为什么计算是用int算法进行的呢?因为所有相乘的因子都是int值。 当你把两个int值相乘时,你会得到另一个int值。 Java没有目标类型,这是一种语言特性,其中存储结果的变量类型会影响计算的类型 。在每个产品中,使用长文字代替int作为第一个因素,很容易修复程序。这迫使表达式中的所有后续计算都使用长算术完成。虽然只有在表示每天微秒数时才有必要这样做,但在这两种产品中都这样做是很好的形式。 类似地,在产品中并不总是需要使用long作为第一个值,但这样做是很好的形式。用长值开始两次计算可以清楚地表明它们不会溢出。该程序按预期打印1000张:
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
教训很简单: 当处理大量数据时,要小心溢出,因为它是一个无声的杀手。
本文由 Shubham Juneja .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 贡献极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。
如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。