17

对于三个 n 位有符号整数ab、 和c(例如 32 位),a * (b + c) == (a * b) + (a * c)考虑到整数溢出,总是真的吗?

我认为这是与语言无关的,但如果不是,我对 Java 的答案特别感兴趣。

4

5 回答 5

13

是的,它成立,因为整数算术是有限环上的模算术。

你可以在这里看到一些理论讨论:https ://math.stackexchange.com/questions/27336/associativity-commutativity-and-distributivity-of-modulo-arithmetic

于 2013-01-07T03:19:46.857 回答
6

是的,这总是正确的

这是一个有效的属性,因为您正在有效地进行算术模 2^32。Java 被签名的事实int使事情稍微复杂化(这意味着您不能假设您通常在做与模运算等效的操作),但不会影响这个特定的分配属性。

一个思想实验是考虑使用重复加法来实现它,并考虑它溢出时会发生什么。由于进行加法的顺序不会影响ints 的结果(即使有溢出),所以也不会以不同的顺序将乘法作为重复加法。而且由于int乘法总是等价于重复加法,因此对于重新排序的乘法,结果也必须相同。量子点

于 2013-01-07T03:18:30.157 回答
2

分配性质适用于模算术;因为,对于相同的(无符号)位长度,固定位长度二进制补码整数算术与模算术同态,所以在使用二进制补码算术时分配属性成立。

更详细的解释可以在这里找到。

于 2013-01-07T03:20:29.087 回答
1

是的,它确实适用于 Java,包括溢出情况。(某些其他语言没有指定溢出行为,在这种情况下不做任何保证。)

于 2013-01-07T03:19:24.687 回答
0

对于有符号整数的 2 补码数学,问题归结为:

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

所以对于 2 的补码有符号整数数学,它总是正确的。

对于非 2 的补码有符号整数数学,我想这取决于如何处理溢出。如果它反映了模数学,那么它是真的。

于 2013-01-07T03:21:22.767 回答