2011-02-27 98 views
41

在Java中當你增加一個int(或字節/短/長)超過它的最大值時會發生什麼?它是否環繞到最大負值?當你增加一個整數超過其最大值時會發生什麼?

AtomicInteger.getAndIncrement()的行爲方式是否相同?

+0

[This PDF](http://pages.cs.wisc.edu/~willb/cs302/spring-07/why-integer-overflow-cl.pdf)給出了一個簡潔的解釋/爲什麼它的作品。是的,原子版本會做同樣的事情。 – TofuBeer 2011-02-27 03:04:47

回答

53

Java Language Specification section on integer operations

內置整數運算符 表示任何 方式的上溢或下溢。

結果由語言指定,並獨立於JVM版本:Integer.MAX_VALUE + 1 == Integer.MIN_VALUEInteger.MIN_VALUE - 1 == Integer.MAX_VALUE。其他整數類型也是如此。

原子整數對象(AtomicIntegerAtomicLong等)在內部使用正常的整數運算符,因此getAndDecrement()等也以這種方式表現。

7

如果你做這樣的事情:

int x = 2147483647; 
x++; 

如果現在打印出X,這將是價值-2147483648

+0

增量時x在二進制級別會發生什麼? – AJPennster 2016-04-21 01:02:30

+1

'01111111111111111111111111111111' - >'10000000000000000000000000000000'。用[二的補碼](https://en.wikipedia.org/wiki/Signed_number_representations#Two.27s_complement),第二個數字是負數。 – jterrace 2016-04-21 15:38:25

+0

那麼,10000000000000000000000000000000相當於-2147483648,對嗎? – AJPennster 2016-04-21 17:31:02

5

由於jterrace說,Java運行時間將「包裝」的結果-2147483648的Integer.MIN_VALUE的。

但是,這是不正確數學! 正確答案數學是2147483648 但是一個「詮釋」不能有2147483648 的值。「詮釋」邊界-2147483648到2147483647

那麼,爲什麼不是Java拋出異常? 好問題!一個數組對象會。

但語言作者知道他們原始類型的範圍,所以他們使用'包裝'技術來避免代價高昂的異常。

作爲開發人員,您必須測試這些類型邊界。 遞增一個簡單的測試將是

if(x++ == Integer.MIN_VALUE) 
    //boundary exceeded 

的遞減一個簡單的測試將是

if(x-- == Integer.MAX_VALUE) 
    //boundary exceeded 

兩個完整的測試將是

if(x++ == Integer.MIN_VALUE || x-- == Integer.MAX_VALUE) 
    //boundary exceeded 
+6

在最後一個例子中,我認爲你不能使用++和 - 操作符來檢查邊界,因爲它們實際上正在改變x的值。相反,應該被重構爲if(x + 1 == Integer.MIN_VALUE || x - 1 == Integer.MAX_VALUE) – ronkot 2016-02-01 12:38:45

4

會發生什麼是一個額外的位添加到最右邊的位,順序遞減爲一個帶負號的int ...注意'int_32'後發生了什麼;

int _0 = 0b0000000000000000000000000000000; 
    int _1 = 0b0000000000000000000000000000001; 
    int _2 = 0b0000000000000000000000000000010; 
    int _3 = 0b0000000000000000000000000000100; 
    int _4 = 0b0000000000000000000000000001000; 
    int _5 = 0b0000000000000000000000000010000; 
    int _6 = 0b0000000000000000000000000100000; 
    int _7 = 0b0000000000000000000000001000000; 
    int _8 = 0b0000000000000000000000010000000; 
    int _9 = 0b0000000000000000000000100000000; 
    int _10 = 0b0000000000000000000001000000000; 
    int _11 = 0b0000000000000000000010000000000; 
    int _12 = 0b0000000000000000000100000000000; 
    int _13 = 0b0000000000000000001000000000000; 
    int _14 = 0b0000000000000000010000000000000; 
    int _15 = 0b0000000000000000100000000000000; 
    int _16 = 0b0000000000000001000000000000000; 
    int _17 = 0b0000000000000010000000000000000; 
    int _18 = 0b0000000000000100000000000000000; 
    int _19 = 0b0000000000001000000000000000000; 
    int _20 = 0b0000000000010000000000000000000; 
    int _21 = 0b0000000000100000000000000000000; 
    int _22 = 0b0000000001000000000000000000000; 
    int _23 = 0b0000000010000000000000000000000; 
    int _24 = 0b0000000100000000000000000000000; 
    int _25 = 0b0000001000000000000000000000000; 
    int _26 = 0b0000010000000000000000000000000; 
    int _27 = 0b0000100000000000000000000000000; 
    int _28 = 0b0001000000000000000000000000000; 
    int _29 = 0b0010000000000000000000000000000; 
    int _30 = 0b0100000000000000000000000000000; 
    int _31 = 0b1000000000000000000000000000000; 
    int _32 = 0b1111111111111111111111111111111; 
    int _XX = 0b10000000000000000000000000000000; // numeric overflow. 
    int _33 = 0b10000000000000000000000000000001; 
    int _34 = 0b11000000000000000000000000000000; 
    int _35 = 0b11100000000000000000000000000000; 
    int _36 = 0b11110000000000000000000000000000; 
    int _37 = 0b11111000000000000000000000000000; 
    int _38 = 0b11111100000000000000000000000000; 
    int _39 = 0b11111110000000000000000000000000; 
    int _40 = 0b11111111000000000000000000000000; 
    int _41 = 0b11111111100000000000000000000000; 
    int _42 = 0b11111111110000000000000000000000; 
    int _43 = 0b11111111111000000000000000000000; 
    int _44 = 0b11111111111100000000000000000000; 
    int _45 = 0b11111111111110000000000000000000; 
    int _46 = 0b11111111111111000000000000000000; 
    int _47 = 0b11111111111111100000000000000000; 
    int _48 = 0b11111111111111110000000000000000; 
    int _49 = 0b11111111111111111000000000000000; 
    int _50 = 0b11111111111111111100000000000000; 
    int _51 = 0b11111111111111111110000000000000; 
    int _52 = 0b11111111111111111111000000000000; 
    int _53 = 0b11111111111111111111100000000000; 
    int _54 = 0b11111111111111111111110000000000; 
    int _55 = 0b11111111111111111111111000000000; 
    int _56 = 0b11111111111111111111111100000000; 
    int _57 = 0b11111111111111111111111110000000; 
    int _58 = 0b11111111111111111111111111000000; 
    int _59 = 0b11111111111111111111111111100000; 
    int _60 = 0b11111111111111111111111111110000; 
    int _61 = 0b11111111111111111111111111111000; 
    int _62 = 0b11111111111111111111111111111100; 
    int _63 = 0b11111111111111111111111111111110; 
    int _64 = 0b11111111111111111111111111111111; 

    System.out.println(" _0 = " + _0 ); 
    System.out.println(" _1 = " + _1 ); 
    System.out.println(" _2 = " + _2 ); 
    System.out.println(" _3 = " + _3 ); 
    System.out.println(" _4 = " + _4 ); 
    System.out.println(" _5 = " + _5 ); 
    System.out.println(" _6 = " + _6 ); 
    System.out.println(" _7 = " + _7 ); 
    System.out.println(" _8 = " + _8 ); 
    System.out.println(" _9 = " + _9 ); 
    System.out.println(" _10 = " + _10); 
    System.out.println(" _11 = " + _11); 
    System.out.println(" _12 = " + _12); 
    System.out.println(" _13 = " + _13); 
    System.out.println(" _14 = " + _14); 
    System.out.println(" _15 = " + _15); 
    System.out.println(" _16 = " + _16); 
    System.out.println(" _17 = " + _17); 
    System.out.println(" _18 = " + _18); 
    System.out.println(" _19 = " + _19); 
    System.out.println(" _20 = " + _20); 
    System.out.println(" _21 = " + _21); 
    System.out.println(" _22 = " + _22); 
    System.out.println(" _23 = " + _23); 
    System.out.println(" _24 = " + _24); 
    System.out.println(" _25 = " + _25); 
    System.out.println(" _26 = " + _26); 
    System.out.println(" _27 = " + _27); 
    System.out.println(" _28 = " + _28); 
    System.out.println(" _29 = " + _29); 
    System.out.println(" _30 = " + _30); 
    System.out.println(" _31 = " + _31); 
    System.out.println(" _32 = " + _32); 
    System.out.println(" _xx = " + _xx); // -2147483648 
    System.out.println(" _33 = " + _33); 
    System.out.println(" _34 = " + _34); 
    System.out.println(" _35 = " + _35); 
    System.out.println(" _36 = " + _36); 
    System.out.println(" _37 = " + _37); 
    System.out.println(" _38 = " + _38); 
    System.out.println(" _39 = " + _39); 
    System.out.println(" _40 = " + _40); 
    System.out.println(" _41 = " + _41); 
    System.out.println(" _42 = " + _42); 
    System.out.println(" _43 = " + _43); 
    System.out.println(" _44 = " + _44); 
    System.out.println(" _45 = " + _45); 
    System.out.println(" _46 = " + _46); 
    System.out.println(" _47 = " + _47); 
    System.out.println(" _48 = " + _48); 
    System.out.println(" _49 = " + _49); 
    System.out.println(" _50 = " + _50); 
    System.out.println(" _51 = " + _51); 
    System.out.println(" _52 = " + _52); 
    System.out.println(" _53 = " + _53); 
    System.out.println(" _54 = " + _54); 
    System.out.println(" _55 = " + _55); 
    System.out.println(" _56 = " + _56); 
    System.out.println(" _57 = " + _57); 
    System.out.println(" _58 = " + _58); 
    System.out.println(" _59 = " + _59); 
    System.out.println(" _60 = " + _60); 
    System.out.println(" _61 = " + _61); 
    System.out.println(" _62 = " + _62); 
    System.out.println(" _63 = " + _63); 
    System.out.println(" _64 = " + _64); 
0

這是一個解決方案的答案,所以你仍然可以繼續基本無限。 我建議,如果(int>的nearmax),然後傳遞給新的INT 例子:

int x = 2000000000; 
x++; 
int stacker = 0; 
if (x > 2000000000) 
{ 
int temp = x; 
x = temp - 2000000000 
stacker++; 
} 

那麼你可以拆散必要時太...

說,X = 0

x--; 
if (x < 0 && stacker > 0) 
{ 
int temp = x; 
x = 2000000000 + temp;//plus because it's negative 
stacker--; 
} 

這給了2000000000 x 2000000000,我的意思是......你可以繼續這樣做,所以...亞...

當然,如果你想使用nega,你甚至可以走得更遠tive numbers ...

相關問題