I was reading about why the following code is buggy:
int tadd_ok ( int x, int y ) {
int sum = x + y;
return ( sum - x == y ) && ( sum - y == x );
}
The explanation was that two's complement addition forms an abelian group and so the expression(x + y) - x
with evaluate to y
regardless if whether or not the addition overflows.
(Same for (x + y) - y)
which will evaluate to x
).
I don't understand this explanation or the abelian group reference. Two's complement addition is basically unsigned modulo arithmetic that is "converted" to two's complement, right?
So for example if we have 4 bits we have the range [-8, 7].
In the example if we had x = 7
and y = 6
the result overflows to 6. And that is not equal to either y
or x
.
So why is the explanation that the equality is always valid regardless of the overflow?
An "abelian" group just means that the order that you add things doesn't matter - (a+b)+c = a+(b+c) and (a+b) == (b+a).
This is true of the integers in C. It is technically true as @ouah points out that overflow is undefined, but this is to support the C standard easily on processors that do not use two's compliment math. Most do.
On those, unless something very strange (or not so strange, but optimized - thanks @ouah) is going on in the compiler, unsigned math will function as an abelian group.
In your example, 7+6 = 0111 + 0110 == 1101 is -(0010+1) = -3. Negative numbers "count downward" in binary in a twos' complement signed system: 1111 is -1. Subtracting back yields 1010, or 0101+1 = 6.
来源:https://stackoverflow.com/questions/25963827/check-of-overflow-in-signed-addition-and-abelian-groups