To pytanie tak mi się spodobało, że 4 czerwca 2013 r . Uczyniłem je tematem mojego bloga . Dzięki za świetne pytanie!
Duże skrzynie są łatwe do zdobycia. Na przykład:
a = 1073741823;
b = 134217727;
c = 134217727;
ponieważ b * c
przepełnia do liczby ujemnej.
Dodałbym do tego fakt, że w sprawdzonej arytmetyce różnica między a / (b * c)
i (a / b) / c
może być różnicą między działającym programem a programem, który ulega awarii. Jeśli iloczyn liczby całkowitej b
i c
przekracza granice liczby całkowitej, poprzednia ulegnie awarii w sprawdzonym kontekście.
W przypadku małych dodatnich liczb całkowitych, powiedzmy, dostatecznie małych, aby pasowały do skrótu, należy zachować tożsamość.
Timothy Shields właśnie przesłał dowód; Przedstawiam tutaj alternatywny dowód. Załóżmy, że wszystkie liczby są nieujemnymi liczbami całkowitymi i żadna z operacji nie przepełnia się.
Dzielenie liczb całkowitych x / y
znajduje wartość q
taką, że q * y + r == x
, gdzie 0 <= r < y
.
Więc podział a / (b * c)
znajduje taką wartość q1
, że
q1 * b * c + r1 == a
gdzie 0 <= r1 < b * c
dzielenie ( a / b ) / c
najpierw znajduje wartość qt
taką, że
qt * b + r3 == a
a następnie stwierdza wartość q2
w taki sposób,
q2 * c + r2 == qt
Więc zastąp to w for qt
i otrzymamy:
q2 * b * c + b * r2 + r3 == a
gdzie 0 <= r2 < c
i 0 <= r3 < b
.
Dwie równe sobie rzeczy są sobie równe, więc mamy
q1 * b * c + r1 == q2 * b * c + b * r2 + r3
Załóżmy, że q1 == q2 + x
dla jakiejś liczby całkowitej x
. Zastąp to w i rozwiąż x
:
q2 * b * c + x * b * c + r1 = q2 * b * c + b * r2 + r3
x = (b * r2 + r3 - r1) / (b * c)
gdzie
0 <= r1 < b * c
0 <= r2 < c
0 <= r3 < b
Czy może x
być większe niż zero? Nie. Mamy nierówności:
b * r2 + r3 - r1 <= b * r2 + r3 <= b * (c - 1) + r3 < b * (c - 1) + b == b * c
Zatem licznik tego ułamka jest zawsze mniejszy niż b * c
, więc x
nie może być większy od zera.
Czy może x
być mniejsze niż zero? Nie, za pomocą podobnego argumentu pozostawiono czytelnikowi.
Dlatego liczba całkowita x
jest równa zero, a zatem q1 == q2
.