Це питання мені так сподобалось, що я став предметом свого блогу 4 червня 2013 року . Дякую за чудове запитання!
До великих справ легко дістатись. Наприклад:
a = 1073741823;
b = 134217727;
c = 134217727;
тому що b * cпереливається на від’ємне число.
Я хотів би додати до цього той факт , що в перевірили арифметична різниця між a / (b * c)і (a / b) / cможе бути різниця між програмою , яка працює і програма, аварій. Якщо добутокb іc переповнює межі цілого числа, то перше зазнає аварії в перевіреному контексті.
Для малих натуральних чисел, скажімо, достатньо малих, щоб вміститися в короткі, слід зберігати ідентичність.
Тімоті Шилдс щойно опублікував доказ; Я представляю тут альтернативний доказ. Припустимо, що всі числа тут невід’ємні цілі числа, і жодна з операцій не переповнюється.
Цілочисельний поділ x / yзнаходить значення qтаким, що q * y + r == x, де0 <= r < y .
Тож поділ a / (b * c)знаходить значення q1таким, що
q1 * b * c + r1 == a
де 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
де 0 <= r2 < c і 0 <= r3 < b.
Дві речі, рівні одному, рівні між собою, отже, маємо
q1 * b * c + r1 == q2 * b * c + b * r2 + r3
Припустимо, 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)
де
0 <= r1 < b * c
0 <= r2 < c
0 <= r3 < b
Можна x бути більше нуля? Ні. У нас є нерівності:
b * r2 + r3 - r1 <= b * r2 + r3 <= b * (c - 1) + r3 < b * (c - 1) + b == b * c
Отже, чисельник цього дробу завжди менший за b * c , тому xне може бути більшим за нуль.
Може xбути менше нуля? Ні, за подібним аргументом, залишеним читачеві.
Тому ціле число xдорівнює нулю, а отже q1 == q2.