简体   繁体   中英

What happens when you increment an integer beyond its max value?

In Java, what happens when you increment an int (or byte/short/long) beyond it's max value? Does it wrap around to the max negative value?

Does AtomicInteger.getAndIncrement() also behave in the same manner?

From the Java Language Specification section on integer operations :

The built-in integer operators do not indicate overflow or underflow in any way.

The results are specified by the language and independent of the JVM version: Integer.MAX_VALUE + 1 == Integer.MIN_VALUE and Integer.MIN_VALUE - 1 == Integer.MAX_VALUE . The same goes for the other integer types.

The atomic integer objects ( AtomicInteger , AtomicLong , etc.) use the normal integer operators internally, so getAndDecrement() , etc. behave this way as well.

If you do something like this:

int x = 2147483647;
x++;

If you now print out x , it will have the value -2147483648 .

As jterrace says, the Java run-time will "wrap' the result to the Integer.MIN_VALUE of -2147483648.

But that is Mathematically incorrect! The correct Mathematically answer is 2147483648. But an 'int' can't have a value of 2147483648. The 'int' boundaries are -2147483648 to 2147483647

So why doesn't Java throw an exception? Good question! An Array object would.

But language authors know the scope of their primitive types, so they use the 'wrapping' technique to avoid a costly exception.

You, as a developer, must test for these type boundaries. A simple test for incrementing would be

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

A simple test for decrementing would be

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

A complete test for both would be

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

What happens is an extra bit is added to the furthest right bit and the order decrements as a negatively signed int ... Notice what happens after '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 );

If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.

http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#13510

This is a workaround answer so you can still continue to basically infinite. I recommend a if(int > nearmax) then pass to new int Example:

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

then you can unstack when necessary too...

say x = 0

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

this gives 2000000000 x 2000000000 and i mean...you could keep doing this so...ya...

of course you could go even further if you want to use negative numbers...

I'm aware that this is a bit of a necropost, but I came across this and I thought I should share what I've done on my end to anyone who wants the "solved" or my attempt at a solve

package main;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Adder {
public static final int DIGITS = 25;

public static void main(String[] args) throws FileNotFoundException {
    Scanner input = new Scanner(new File("/Users/swapnil/IdeaProjects/Sum/src/Sum.txt"));
    analyze(input);
}

public static void analyze(Scanner input) {
    int lines = 0;
    while (input.hasNextLine()) {
        String line = input.nextLine();
        Scanner tokens = new Scanner(line);
        int[] operand = new int[DIGITS];
        initAdd(tokens, operand);
        while (tokens.hasNext()) {
            contAdd(tokens, operand);
        }
        System.out.print(" = ");
        printAsNumber(operand);
        System.out.println();
        lines++;
    }
    System.out.println();
    System.out.println("Total lines = " + lines);
}

public static int[] getNextOperand(Scanner tokens) {
    String number = tokens.next();
    int lastDigitIndex = DIGITS - number.length();
    int[] nextOp = new int[DIGITS];
    for (int i = lastDigitIndex; i < DIGITS; i++) {
        nextOp[i] = Character.getNumericValue(number.charAt(i - lastDigitIndex));
    }
    return nextOp;
}

public static void addColumns(Scanner tokens, int operand[], int nextOp[]) {
    for (int i = DIGITS - 1; i >= 0; i--) {
        operand[i] += nextOp[i];
        if (operand[i] > 9) {
            int currentDigit = operand[i] % 10;
            operand[i] = currentDigit;
            operand[i - 1]++;
        }
    }
}

public static void initAdd(Scanner tokens, int operand[]) {
    int[] nextOp = getNextOperand(tokens);
    printAsNumber(nextOp);
    addColumns(tokens, operand, nextOp);
}

public static void contAdd(Scanner tokens, int operand[]) {
    int[] nextOp = getNextOperand(tokens);
    System.out.print(" + ");
    printAsNumber(nextOp);
    addColumns(tokens, operand, nextOp);
}

public static void printAsNumber(int number[]) {
    int lastDigitIndex = DIGITS - 1;
    for (int i = 0; i < DIGITS; i++) {
        if (number[i] != 0) {
            lastDigitIndex = i;
            break;
        }
    }
    for (int i = lastDigitIndex; i < DIGITS; i++) {
        System.out.print(number[i]);
    }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM