18

For three n-bit signed integers a, b, and c (such as 32-bit), is it always true that a * (b + c) == (a * b) + (a * c), taking into account integer overflow?

I think this is language-independent, but if it's not, I'm specifically interested in the answer for Java.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Taymon
  • 24,950
  • 9
  • 62
  • 84
  • 1
    +1 Using underflows and overflows is rarely useful, and even when it is, it is confusing for most people. If you are relying on this behaviour, you should document it in detail. – Peter Lawrey Jan 07 '13 at 09:15
  • Agreed. In this case, I'm doing compiler optimization of arithmetic expressions and need to be careful not to change the semantics. – Taymon Jan 08 '13 at 18:59

5 Answers5

14

Yes, it holds, because integer arithmetic is modulo arithmetic over finite rings.

You can see some theoretical discussion here: https://math.stackexchange.com/questions/27336/associativity-commutativity-and-distributivity-of-modulo-arithmetic

Community
  • 1
  • 1
DuckMaestro
  • 15,232
  • 11
  • 67
  • 85
6

Yes, this is always true.

It is a property that holds because you are effectively doing arithmetic modulo 2^32. The fact that Java ints are signed complicates things slightly (and means that you can't assume you are doing the equivalent of modulo arithmetic in general), but doesn't affect this particular distributive property.

A thought experiment is to consider implementing it using repeated addition, and consider what happens when it overflows. Since the order of doing additions doesn't affect the result with ints (even with overflows) then neither does doing the multiplications as repeated additions in a different order. And since int multiply is always equivalent to repeated addition, the results must also be the same for re-ordered multiplication. Q.E.D.

mikera
  • 105,238
  • 25
  • 256
  • 415
2

The distributive property holds for modulo arithmetic; since, fixed bit length two's complement integer arithmetic is homomorphic to modulo arithmetic for the same (unsigned) bit length, the distributive property holds when using two's complement arithmetic.

A more detailed explanation can be found here.

Community
  • 1
  • 1
andand
  • 17,134
  • 11
  • 53
  • 79
1

Yes, it does hold in Java, including in the overflow case. (Certain other languages don't specify overflow behavior, in which case no guarantees are made.)

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
0

For 2's complement math on signed integer the question boils down to:

is (a*(b+c))%(2**32) === (a*b+a*c)%(2**32)

so for 2's complement signed integer math it's always true.

For non-2's complement signed integer math I guess it depends on how overflows are handled. If it reflects modulo math then it's true.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • @MelNicholson: Care to explain? Overflow is basically modulo math. – slebetman Jan 07 '13 at 03:29
  • First, the range size is 2-pwr-32, not 32. Second, modulo arithmetic has a non-negative range, which Java + and * do not. There is a proof that multiplication for java integers will overflow in such a way that the distributed principle holds, but it is not a trivial proof, especially given that MAX_INT is not the opposite of MIN_INT. – Mel Nicholson Jan 07 '13 at 03:34
  • 1
    @MelNicholson: Which is why I stated for 2's complement signed integer. 2's complement math is the same as unsigned integer math so 2's complement signed integer math boils down to signed integer math which in turn boils down to modulo math – slebetman Jan 07 '13 at 03:47