/* PROOF OF CORRECTNESS: DIV(X,Y): compute X / Y (integer) and X % Y (remainder or modulo) Trace: div(5,2) = 2 with remainder 1 x y z z*Y+x ------------------- 5 2 0 5 3 2 1 5 1 2 2 5 As the loop iterates, z*Y+x stays constant at 5 (X). This is an unusual situation and results in a differnt looking INVARIANT: X=z*Y+x This diagram shows how the algorithm works: +--------- x=X=5 5| + subtract y=2, z=1= # of times y has been subtracted 4| +--------- 3| + subtract y=2, z=2= # of times y has been subtracted 2| +--------- 1| cannot subtract y=2 anymore, x=1 is now the remainder + 0+--------- 1. start x at X=5, keep subtracting y=2 from x 2. stop when it is not possible to subtract anymore y, x is the remainder Back to the INVARIANT: X=z*Y+x which says that z represents how many times it has substracted (or Y) from x. In the beginning, z*Y is zero, and all the weight is on x. As the loop iterates, the weight is transferred from x onto z*Y. But they always stay in balance: X is always equal to the amounts of Y's that have been substracted plus the remainder x. The final result has subtracted as much as possible and x must be < y. */ #include int div(int X, int Y) { int x, y, z; // PRE: X > 0 and Y > 0 x = X; // x = X and x > 0 y = Y; // x = X and x > 0 and y = Y and y > 0 z = 0; // x = X and x > 0 and y = Y and y > 0 and z = 0 // INVARIANT: X = z * Y + x and x >= 0 and y = Y while (x >= y) { // X = z * Y + x and x >= 0 and y = Y and x >= y z = z + 1; // X = (z-1) * Y + x and x >= 0 and y = Y and x >= y // X = z * Y - Y + x and x >= 0 and y = Y and x >= y // X = z * Y + x - Y and x >= 0 and y = Y and x >= y // X = z * Y + x - y and x >= 0 and y = Y and x >= y x = x - y; // X = z * Y + x and x >= 0 and y = Y } // end while // INVARIANT: X = z * Y + x and x >= 0 and y = Y and EXIT: x < y // X = z * Y + x and 0 <= x < Y // x must be 0..Y-1 to be a modulo // POST: z = Div(X,Y) and x = Mod(X,Y) return z; } int main() { printf("div(5,2)=%d\n",div(5,2)); }