Java:为什么 "long" 数字会变成负数?

Java: Why does "long" number get negative?

我有这个代码:

    long i = 0;
    while (true) {  
        i += 10*i + 5;
        System.out.println(i);
        Thread.sleep(100);      
    }

为什么 long i 印了几次就变成底片了?如果超出范围,应该不会报错吧?

如果运算溢出,结果返回到最小值并从那里继续。

没有抛出异常。

如果您的代码会溢出,您可以改用 BigInteger

如果在最大值之后增加数字,

Java 不会抛出错误。如果您希望有这种行为,可以使用 Java 8 中的 Math.addExact(long x, long y) 方法。如果您传递 Long.MAX_VALUE.[=16=,此方法将抛出 ArithmeticException ]

Java 不抛出异常而您收到负数的原因与数字的存储方式有关。对于长原语,第一个字节用于指示数字的符号(0 -> 正数,1 -> 负数),其余字节用于表示数值。这意味着最大正值 Long.MAX_VALUE 将存储为 01111...111(0 后跟 63 位 1)。由于您向 Long.MAX_VALUE 添加一个数字,您将开始接收负整数,因为符号字节更改为 1。这意味着您有数字溢出,但 Java.[=16 不会引发此错误=]

摘自 Math javadoc:

"The platform uses signed two's complement integer arithmetic with int and long primitive types. The developer should choose the primitive type to ensure that arithmetic operations consistently produce correct results, which in some cases means the operations will not overflow the range of values of the computation. The best practice is to choose the primitive type and algorithm to avoid overflow."

对于Java 8:

"In cases where the size is int or long and overflow errors need to be detected, the methods addExact, subtractExact, multiplyExact, and toIntExact throw an ArithmeticException when the results overflow. For other arithmetic operations such as divide, absolute value, increment, decrement, and negation overflow occurs only with a specific minimum or maximum value and should be checked against the minimum or maximum as appropriate"