簡體   English   中英

乘法怪異輸出

[英]Multiplication weird output

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 ,因此它們溢出了(該數字太大而無法存儲在int )。 分解時,可以將值轉換為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

您面臨着最常見的整數溢出問題,
用這個

long thirtyDayInMillis = 1L * 30 * 24 * 60 * 60 * 1000;

根據Lexical Literals文檔,其中提到:

文字的類型確定如下:
-以L或l結尾的整數文字(§3.10.1)的類型很長(§4.2.1)。
-任何其他整數文字的類型為int(第4.2.1節)。

因此,您的表達式30 * 24 * 60 * 60 * 1000被評估為int原始數據類型,因為在任何數值中均未提及lL 其結果是2,592,000,000
即在Binary中,它是1001 1010 0111 1110 1100 1000 0000 0000int是32位,因此如例4.2.2-1所述采用低32位 整數運算 ,結果為-1702967296因為最高有效位用於表示符號。

你應該做:

long thirtyDayInMillis = 30L * 24 * 60 * 60 * 1000;

Java中數字的默認值為int 因此,當您執行30 * 24 * 60 * 60 * 1000您將得到int計算,這會溢出。

參見文檔

如果整數文字以字母Ll結尾,則其類型為long; 否則為int類型 建議使用大寫字母L,因為小寫字母l很難與數字1區分開。

嘗試long thirtyDayInMillis = 30 * 24 * 60 * 60 * 1000L;

默認情況下,它被認為是int add L ,以使編譯器知道您正在傳遞long值,但正如Tim B所指出的那樣*這樣做很危險,因為30 * 24 * 60 * 60將以整數形式處理,並且僅用於最后一個乘法轉換為long *

所以這樣

long thirtyDayInMillis = 30L * 24 * 60 * 60 * 1000;

這是由於您要乘以最大值為2147483647的整數,所以等式的右邊保持為int類型。 因此,只要在類型上加“ l”,就可以使long的乘數之一變長,這樣您將得到正確的結果, 例如long三十DayInMillis = 30l * 24 * 60 * 60 * 1000;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM