While doing unsigned int conversions in Java I got some “anomalous” results, which I have cut down to the minimal case shown below. The same code in C generates similar results.
The problem is that when I calculate the theoretical sum of the absolute value of all integer values using the Gauss summation formula n(n+1)/2 (see https://en.wikipedia.org/wiki/Summation) the value I calculate does not match the total if I actually add up all the absolute values one by one.
Note that when I calculate the total using the summation formula the division by 2 “/2” is omitted because I am adding both the negative and positive numbers as absolute values, and at the end I have to add (longIntegerMax + 1) because the negative numbers have one extra number at the end (Integer.MIN) which has the absolute value of 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 );
}
output:
count of all integers: 4294967296
total of absolute value of all integers: 4611686014132420608
calculated total of absolute value of all integers: 4611686018427387904
As you can see, the calculated total is close to the real total, but does not match it exactly. Why not?
The problem is here ..
The
( i * -1 )is still integer arithmetic, it produces a number greater than Integer.MAX_VALUE and overflows back to Integer.MIN_VALUE;You could fix this as @Evgeniy suggested, or you could use
to force long arithmetic.