long thirtyDayInMillis = 30 * 24 * 60 * 60 * 1000;
它应该返回 2592000000
但它返回 -1702967296
。
但如果我将语句拆分为两个语句。
long dayInMillis = 24 * 60 * 60 * 1000;
long thirtyDayInMillis = 30 * dayInMillis;
它返回正确的值。
为什么 30 * 24 * 60 * 60 * 1000
返回 -1702967296
?
最佳答案
默认情况下,Java 中的数字文字是int
。所以你的第一个乘法的各个部分是 int
,而不是 long
,所以它们会溢出(数字变得太大而无法存储在 >整数
)。当你分解它时,你在它溢出之前将值转换为 long
。
您可以通过在字面值中添加 L
使它们变长来解决这个问题;只有第一个是你真正需要的,因为 30L * 24
的结果将是一个 long
,依此类推:
thirtyDayInMillis = 30L * 24 * 60 * 60 * 1000;
请注意,我将 L
放在文字的第一个 上。这是因为乘法是从左到右进行的,因此我们希望从一开始就确保我们使用的是 long
值,而不是 int
值。例如,它是这样处理的:
thirtyDayInMillis = (((30L * 24) * 60) * 60) * 1000;
首先 30L * 24
完成,然后结果是 * 60
,依此类推。因此,如果那些较早的那些(没有 L
仍然作为 int
值完成)溢出,结果将是错误的。
您的特定表达式直到最后一次乘法才会溢出,但让我们使用会更早溢出的值:
thirtyDayInMillis = 1000 * 24 * 6000 * 7000 * 30;
这给了我们(不正确的)结果 -864731136
而不是 30240000000000
。现在让我们把 L
放在错误的地方:
thirtyDayInMillis = 1000 * 24 * 6000 * 7000 * 30L;
// L in wrong place ----------------------------^
我们得到 -39519436800
。把它放在正确的地方:
thirtyDayInMillis = 1000L * 24 * 6000 * 7000 * 30;
...我们得到 30240000000000
。
关于java - 乘法奇怪的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20631220/