我非常喜欢这个问题,所以我把它作为主题我的博客2013年6月4日 http://ericlippert.com/2013/06/04/an-integer-division-identity/。感谢您提出的好问题!
大箱子很容易得到。例如:
a = 1073741823;
b = 134217727;
c = 134217727;
because b * c
溢出为负数。
我想补充一点的是,在检查算术, 和...之间的不同a / (b * c)
and (a / b) / c
可能是正常运行的程序和崩溃的程序之间的区别。如果产品b
and c
溢出整数的边界,那么前者将在检查的上下文中崩溃。
对于小的正整数,例如,小到足以适合短路,则应保持恒等式。
蒂莫西·希尔兹 (Timothy Shields) 刚刚发布了一份证明;我在这里提出一个替代证明。假设这里的所有数字都是非负整数并且没有任何操作溢出。
整数除法x / y
找到值q
这样q * y + r == x
, where 0 <= r < y
.
所以划分a / (b * c)
找到值q1
这样
q1 * b * c + r1 == a
where 0 <= r1 < b * c
该部门( a / b ) / c
首先找到值qt
这样
qt * b + r3 == a
然后找到值q2
这样
q2 * c + r2 == qt
所以将其替换为qt
我们得到:
q2 * b * c + b * r2 + r3 == a
where 0 <= r2 < c
and 0 <= r3 < b
.
两个相同的东西彼此相等,所以我们有
q1 * b * c + r1 == q2 * b * c + b * r2 + r3
Suppose q1 == q2 + x
对于某个整数x
。将其代入并求解x
:
q2 * b * c + x * b * c + r1 = q2 * b * c + b * r2 + r3
x = (b * r2 + r3 - r1) / (b * c)
where
0 <= r1 < b * c
0 <= r2 < c
0 <= r3 < b
Can x
大于零?不,我们有不平等:
b * r2 + r3 - r1 <= b * r2 + r3 <= b * (c - 1) + r3 < b * (c - 1) + b == b * c
所以该分数的分子总是小于b * c
, so x
不能大于零。
Can x
小于零?不,通过类似的论证,留给读者。
因此整数x
为零,因此q1 == q2
.