在Java中,当你将int(或byte / short / long)增加到超出它的最大值时会发生什么?它会回绕到最大负值吗?
AtomicInteger.getAndIncrement()
的行为方式是否相同?
答案 0 :(得分:61)
来自Java Language Specification section on integer operations:
内置整数运算符没有 表示任何溢出或下溢 方式。
结果由语言指定,与JVM版本无关:Integer.MAX_VALUE + 1 == Integer.MIN_VALUE
和Integer.MIN_VALUE - 1 == Integer.MAX_VALUE
。其他整数类型也是如此。
原子整数对象(AtomicInteger
,AtomicLong
等)在内部使用普通整数运算符,因此getAndDecrement()
等行为也是如此。
答案 1 :(得分:9)
如果您这样做:
int x = 2147483647;
x++;
如果您现在打印x
,则其值为-2147483648
。
答案 2 :(得分:5)
正如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
答案 3 :(得分: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 );
答案 4 :(得分:3)
如果整数加法溢出,那么 结果是低位 数学和如表示 有些足够大 二进制补码格式。如果溢出 发生,那么结果的标志是 不一样的标志 两个操作数的数学和 值。
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#13510
答案 5 :(得分:0)
这是一个变通方法的答案,因此您仍然可以继续基本无限。 我建议使用if(int> nearmax)然后传递给new 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,我的意思是......你可以继续这样做......你...
当然,如果你想使用负数,你可以更进一步......
答案 6 :(得分:0)
我知道这有点死板,但是我碰到了这一点,我认为我应该将自己所做的一切分享给任何想要“解决”或尝试解决的人< / p>
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]);
}
}
}