[英]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
原始數據類型,因為在任何數值中均未提及l
或L
其結果是2,592,000,000
即在Binary中,它是1001 1010 0111 1110 1100 1000 0000 0000
而int
是32位,因此如例4.2.2-1所述采用低32位。 整數運算 ,結果為-1702967296
因為最高有效位用於表示符號。
你應該做:
long thirtyDayInMillis = 30L * 24 * 60 * 60 * 1000;
Java中數字的默認值為int
。 因此,當您執行30 * 24 * 60 * 60 * 1000
您將得到int
計算,這會溢出。
參見文檔 :
如果整數文字以字母L或l結尾,則其類型為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.