Це питання мені так сподобалось, що я став предметом свого блогу 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
.