2011-02-28 80 views
4

範圍我有int值懷疑具有int變量

int x=2147483647;  /*NO Error--this number is the maximum range 
         of int value no error*/ 
int y=2147483648;  /*Error--one more than the 
         maximum range of int*/ 
int z=2147483647+1; /*No Error even though it is one more 
         than the maximum range value*/ 

爲什麼範圍內的疑問?

回答

8

下面是關於Java語言規範的解釋。

上整數常量(JLS 3.10.1)的部分這樣說:

最大十進制字面int類型是2147483648(2 )。從02147483647的所有十進制文字可以出現在可能出現整型文字的任何位置,但文字2147483648可能僅出現在一元否定運算符-的操作數中。

所以......

  • 第一條語句是一個合法的整數文字值的分配。沒有編譯錯誤。

  • 第二個聲明是編譯錯誤,因爲2147483648不在一元否定運算符之前。

  • 第三條語句不包含超出範圍的整數字面值,因此從該角度看它不是編譯錯誤。

而是,第三種說法是如JLS 15.18.2中所述的二進制加法表達式。這說明了整數大小寫如下:

如果整數加法溢出,那麼結果就是以一些足夠大的二進制補碼格式表示的數學和的低位。如果發生溢出,則結果的符號與兩個操作數值的數學和的符號不同。

因此,2147483647 + 1溢出幷包裝到-2147483648


@Peter Lawrey的建議(輕率?)第三語句可「由編譯器重寫」爲+2147483648,導致編譯錯誤。

這是不正確的。

JLS中沒有任何內容表明常量表達式可以與非常量表達式具有不同的含義。相反,在例如1/0的情況下,JLS翻轉事物並且說該表達式不是一個常量表達式,因爲它異常終止。 (它在JLS 15.28

JLS極力避免某些Java構造意味着不同事情的情況,這取決於編譯器。例如,「明確賦值」規則非常特別,以避免只有智能編譯器可以推斷出該變量在使用之前始終被初始化的情況。從代碼可移植性的角度來看,這是一件好事。

編譯器實現者爲了執行特定於平臺的事情而存在「擺動空間」的唯一重要領域是併發性和Java內存模型。有一個合理的實用原因 - 允許多線程Java應用程序在多核/多處理器硬件上快速運行。

1

因爲第三個被稱爲整數溢出。你正在做計算,你溢出。其他的只是常數。

+0

對不起,我沒有得到你 – satheesh 2011-02-28 09:36:07

1

由於

int z=2147483647+1; 

會溢出,這是不等於2147483648

+0

它是在運行時進行名義上的評估,但編譯器可以在編譯時簡化這個表達式。 ;)'z ==(int)2147483648' – 2011-02-28 09:38:11

+1

但它是常量表達式rite.all常量表達式將在編譯時自己評估知道 – satheesh 2011-02-28 09:38:26

+0

優化不應該改變某些東西的行爲。僅僅因爲編譯器可以優化代碼不應該導致它產生錯誤。例如'Integer i = 0/0;即使它在運行時產生aException,它仍然會編譯。我的IDE顯示此表達式的警告。 – 2011-02-28 09:41:10

0

第三個表達式是基於INT-此外,因此它將結果轉換爲INT的範圍內的值。

0

int的範圍是Integer.MIN_VALUEInteger.MAX_VALUE。 Java很容易溢出,因此編譯器無法檢測到計算結果。 (但可能被你的IDE來檢測)

其中最令人吃驚的溢出業務是-Integer.MIN_VALUE

2

int範圍從Integer.MIN_VALUE (-2147483648)Integer.MAX_VALUE (2147483647)

但是,只有int文字會根據範圍進行檢查。

Java不檢查任何給定的常量值表達式是否在該範圍內。

計算「允許」通過這些邊界,但這會導致溢出(即只有結果值的低位將被存儲)。因此,計算2147483647 + 1int計算中明確定義的,它是-2147483648。

+0

你給java沒有檢查任何給定的常量值表達式適合在該範圍內。是否適用於每個地方 – satheesh 2011-02-28 09:48:09

+0

是的,正如運行時計算一樣,常量值表達式只會溢出。只檢查文字值(並且會導致編譯器錯誤)。嘗試打印'Double.MIN_VALUE/10'或'Double.MAX_VALUE + 10 - Double.MAX_VALUE'。 – 2011-02-28 09:50:37

+0

那麼爲什麼我得到編譯時錯誤字節r = 127 + 1 – satheesh 2011-02-28 09:58:42

1

前兩種情況似乎很明顯。第三種情況將無聲無息地溢出。所以在這種情況下,您應該始終在您的調用代碼中處理該問題。