1

在 Java 中进行 unsigned int 转换时,我得到了一些“异常”结果,我已将其缩减为如下所示的最小情况。C 中的相同代码会产生相似的结果。

问题是,当我使用高斯求和公式 n(n+1)/2 计算所有整数值的绝对值的理论总和时(参见https://en.wikipedia.org/wiki/Summation),值 I如果我实际上将所有绝对值一一相加,则计算与总数不匹配。

请注意,当我使用求和公式计算总数时,将省略除以 2 "/2",因为我将负数和正数都添加为绝对值,最后我必须添加 (longIntegerMax + 1),因为负数末尾有一个额外的数字 (Integer.MIN),其绝对值为 Integer.MAX + 1。

public static void main( String[] asArguments ){
    long longAbsoluteTotal = 0;
    long longNumberOfIntegers = 0;
    long longIntegerMax = Integer.MAX_VALUE;
    long longIntegerMin = Integer.MIN_VALUE;
    for( int i = Integer.MIN_VALUE;; i++ ){
        longNumberOfIntegers++;
        if( i < 0 ){
            longAbsoluteTotal += i * -1;
        } else {
            longAbsoluteTotal += i;
        }
        if( i == Integer.MAX_VALUE ) break;
    }
    long longCalculatedTotal = longIntegerMax * (longIntegerMax + 1) + longIntegerMax + 1; 
    System.out.println( "count of all integers: " + longNumberOfIntegers ); 
    System.out.println( "total of absolute value of all integers: " + longAbsoluteTotal );
    System.out.println( "calculated total of absolute value of all integers: " + longCalculatedTotal );
}

输出:

 count of all integers: 4294967296
 total of absolute value of all integers: 4611686014132420608
 calculated total of absolute value of all integers: 4611686018427387904

如您所见,计算出的总数接近实际总数,但并不完全匹配。为什么不?

4

3 回答 3

7

问题在这里..

longAbsoluteTotal += i * -1;

( i * -1 )仍然是整数运算,它产生一个大于 Integer.MAX_VALUE 的数字并溢出回 Integer.MIN_VALUE ;

您可以按照@Evgeniy 的建议解决此问题,或者您可以使用

longAbsoluteTotal += i * -1L; 

强制长算术。

于 2012-12-12T18:27:50.133 回答
0

改变

for( int i = Integer.MIN_VALUE;; i++ ){

for( long i = Integer.MIN_VALUE;; i++ ){

一切都会好的

它类似于 -Integer.MIN_VALUE == -2147483648

于 2012-12-12T18:18:24.393 回答
0
4611686014132420608 - 4611686018427387904 = -4294967296 = Integer.MIN_VALUE * 2

原因是

Integer.MIN_VALUE * -1 == Integer.MIN_VALUE

由于我们使用二进制补码来表示负值。

Integer.MIN_VALUE(0x80000000) = 0x7fffffff + 0x1 = 0x80000000 的二进制补码。

于 2012-12-12T18:45:31.787 回答