我有一個函數需要一個長的值作爲參數之一。不能在函數調用中解析的算術表達式
void doSomething(long limit, ...) {
//statements
}
在函數調用我傳遞參數如
,
doSomething(5 * 1024 * 1024 * 1024, ...);
功能從未接收到該表達的最終值5368709120
,它代替接收1073741824
。我無法理解爲什麼會發生這種情況。
我有一個函數需要一個長的值作爲參數之一。不能在函數調用中解析的算術表達式
void doSomething(long limit, ...) {
//statements
}
在函數調用我傳遞參數如
,
doSomething(5 * 1024 * 1024 * 1024, ...);
功能從未接收到該表達的最終值5368709120
,它代替接收1073741824
。我無法理解爲什麼會發生這種情況。
看數字5368709120
。整數的範圍是-2,147,483,648 to 2,147,483,647
整數溢出發生在那裏。超過int max值限制的參數(5 * 1024 * 1024 * 1024
)中的結果值。轉換任何值到長的,使得因爲你的調用發送int
,之後的操作已爲int
被執行,然後將其裝箱作爲long
結果將被存儲到long
doSomething(5L * 1024 * 1024 * 1024, ...); // look the literal L after 5
像'5 * 1024 * 1024 * 1024L'這樣的表達式是危險的*因爲'*'是左關聯的:在* 5 * 1024 * 1024 ... * *之前*可以有*整數溢出* 1024L'。 Safier的方法是用'L'後綴標記'5':*以下表達式很長* –
@DmitryBychenko Ah.fair point。編輯。 –
。
作爲int
執行的操作將溢出Integer.MAX_VALUE
(2147483647
)並返回不期望的結果。
你可以投你的操作long
像這樣:
doSomething((long)5 * 1024 * 1024 * 1024, ...);
您還可以測試打印出的值:
System.out.println(5 * 1024 * 1024 * 1024); // overflowing
System.out.println((long)5 * 1024 * 1024 * 1024); // casted, not overflowing Long.MAX_VALUE
輸出
1073741824
5368709120
把它'5L * 1024 * 1024 * 1024'(注意*後5 *)爲'長' –
另外,你應該避免幻數;而是使用「長」常數,例如'private static final long SIZE = 5L * 1024 * 1024 * 1024;'。 –