为什么在Java中,24 * 60 * 60 * 1000 * 1000除以24 * 60 * 60 * 1000的结果不等于1000?

13
为什么在Java中 24 * 60 * 60 * 1000 * 1000 除以 24 * 60 * 60 * 1000 的结果不等于 1000?

25
因为Java岛东西方向很长,所以一天会比86400000000微秒略长 :-) - balpha
8
我认为这个问题需要明确指定它是指 int 而不是 long。如果没有显示实际代码或做出明确说明,这个问题就是模糊不清的。这种类型的问题在学校里的测试中让我很讨厌——我应该回答“它确实等于1000”(如果假设为 long),还是我应该猜测教授的意思是暗示一切都被当作 int 处理,因此要提到溢出? - Peter Recore
3个回答

60

因为乘法溢出了32位整数,但在64位中它是可以的:

public class Test
{
    public static void main(String[] args)
    {
        int intProduct = 24 * 60 * 60 * 1000 * 1000;
        long longProduct = 24L * 60 * 60 * 1000 * 1000;
        System.out.println(intProduct); // Prints 500654080
        System.out.println(longProduct); // Prints 86400000000
   }
}

很明显,在乘法溢出之后,除法不会“撤销”这个溢出。


1
1000天*1000意味着什么? - Joel Coehoorn
25
他们总是提到的“公制年”一定是指现在。 - Don Branson
7
1000天 x 1000天将是1,000,000平方天。这并没有什么神秘的。类似地,1000英寸 x 1000英寸是1,000,000平方英寸。但我不确定"平方天"是什么意思。也许这是一种时间旅行者在处理全维空间时使用的测量单位。 - Jay
13
一天有多少微秒?答案是2460'601000*1000。 :) - nos
我认为这将取决于单位,是一天的微秒还是公制年中的天数? - understack

22

你需要从 24L * 60 * ... 开始,因为 int 类型会溢出。

顺便提一下,你的问题是从 Java Puzzlers谜题3:长除法中复制/粘贴过来的 ;)


3

如果你想进行这个计算,那么你必须重新排列操作(以避免溢出)或使用更大的数据类型。真正的问题在于Java中固定大小整数的算术运算不是结合的;这很麻烦,但这就是权衡。


重新排列数字并不能避免溢出。 - cherouvim
@cherouvim,但重新排列操作可能会。 - Nosredna
1
我相信Thom在谈论重新排列乘法,这样你可以像这样做:((24 * 60)/(24 * 60)) * ((1000 * 1000)/(1000*1000))。 - DeadHead
固定大小整数是模数的整数(剩余类环),因此除除法外的操作具有所有通常的良好属性(结合律,交换律,分配律等)。但浮点数不具备这种特性。 - starblue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接