繁体   English   中英

当你增加一个整数超过它的最大值时会发生什么?

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

在 Java 中,当你增加一个整数(或字节/短/长)超过它的最大值时会发生什么? 它是否环绕到最大负值?

AtomicInteger.getAndIncrement()是否也有同样的行为?

关于整数运算Java 语言规范部分

内置整数运算符不以任何方式指示上溢或下溢。

结果由语言指定,与 JVM 版本无关: Integer.MAX_VALUE + 1 == Integer.MIN_VALUEInteger.MIN_VALUE - 1 == Integer.MAX_VALUE 其他整数类型也是如此。

原子整数对象( AtomicIntegerAtomicLong等)在内部使用普通整数运算符,因此getAndDecrement()等也以这种方式运行。

如果你做这样的事情:

int x = 2147483647;
x++;

如果您现在打印出x ,它将具有值-2147483648

正如 jterrace 所说,Java 运行时会将结果“包装”到 -2147483648 的 Integer.MIN_VALUE。

但这在数学上是不正确的! 正确的数学答案是 2147483648。但是“int”的值不能为 2147483648。“int”的边界是 -2147483648 到 2147483647

那么为什么 Java 不抛出异常呢? 好问题! 一个 Array 对象会。

但是语言作者知道他们的原始类型的范围,所以他们使用“包装”技术来避免代价高昂的异常。

作为开发人员,您必须测试这些类型边界。 一个简单的递增测试是

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

发生的事情是在最右边的位上添加一个额外的位,并且顺序递减为负符号 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 );

如果整数加法溢出,则结果是数学和的低位,以某种足够大的二进制补码格式表示。 如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。

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

这是一个解决方法的答案,因此您仍然可以继续基本上无限。 我推荐一个 if(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 我的意思是......你可以继续这样做......你......

当然,如果你想使用负数,你可以走得更远......

我知道这有点像 necropost,但我遇到了这个,我想我应该将我所做的一切分享给任何想要“解决”或我尝试解决的人

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]);
    }
}

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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