2015-08-24 76 views
1

我有一個函數需要一個長的值作爲參數之一。不能在函數調用中解析的算術表達式

void doSomething(long limit, ...) { 
//statements 
} 
在函數調用我傳遞參數如

doSomething(5 * 1024 * 1024 * 1024, ...); 

功能從未接收到該表達的最終值5368709120,它代替接收1073741824。我無法理解爲什麼會發生這種情況。

+1

把它'5L * 1024 * 1024 * 1024'(注意*後5 *)爲'長' –

+0

另外,你應該避免幻數;而是使用「長」常數,例如'private static final long SIZE = 5L * 1024 * 1024 * 1024;'。 –

回答

3

看數字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 
+0

像'5 * 1024 * 1024 * 1024L'這樣的表達式是危險的*因爲'*'是左關聯的:在* 5 * 1024 * 1024 ... * *之前*可以有*整數溢出* 1024L'。 Safier的方法是用'L'後綴標記'5':*以下表達式很長* –

+0

@DmitryBychenko Ah.fair point。編輯。 –

0

作爲int執行的操作將溢出Integer.MAX_VALUE2147483647)並返回不期望的結果。

你可以投你的操作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