乘法奇怪的输出

kan*_*rbk 1 java

long thirtyDayInMillis = 30 * 24 * 60 * 60 * 1000;
Run Code Online (Sandbox Code Playgroud)

它应该返回,2592000000但它返回-1702967296.

但是,如果我将声明分成两个陈述.

long dayInMillis = 24 * 60 * 60 * 1000;
long thirtyDayInMillis = 30 * dayInMillis;
Run Code Online (Sandbox Code Playgroud)

它返回正确的值.

为什么它返回-170296729630 * 24 * 60 * 60 * 1000

T.J*_*der 12

默认情况下,Java中int的数字文字是s.因此,第一个乘法的各个部分是ints,而不是longs,因此它们会溢出(数字太大而无法存储在a中int).当你分解它时,你将值转换为long溢出之前.

你可以通过添加L文字来解决这个问题,使它们变长; 只是第一个是你真正需要的,因为那时结果30L * 24将是a long,依此类推:

thirtyDayInMillis = 30L * 24 * 60 * 60 * 1000;
Run Code Online (Sandbox Code Playgroud)

请注意,我把它L放在第一个文字上.这是因为乘法是从左到右进行的,所以我们要从一开始就确保我们处理的是long值,而不是int值.例如,它的处理方式如下:

thirtyDayInMillis = (((30L * 24) * 60) * 60) * 1000;
Run Code Online (Sandbox Code Playgroud)

首先30L * 24完成,然后结果是* 60,依此类推.因此,如果那些早期的(没有L仍然作为int值完成)溢出,结果将是错误的.

你的特定表达式在最后一次乘法之前不会溢出,但让我们使用先前会溢出的值:

thirtyDayInMillis = 1000 * 24 * 6000 * 7000 * 30;
Run Code Online (Sandbox Code Playgroud)

这给了我们(不正确的)结果-864731136而不是30240000000000.现在让我们把它L放在错误的地方:

thirtyDayInMillis = 1000 * 24 * 6000 * 7000 * 30L;
// L in wrong place ----------------------------^
Run Code Online (Sandbox Code Playgroud)

我们得到了-39519436800.把它放在正确的地方:

thirtyDayInMillis = 1000L * 24 * 6000 * 7000 * 30;
Run Code Online (Sandbox Code Playgroud)

......我们得到了30240000000000.