Multiplication: Loop Invariant Example

Using only adding, halving, doubling, and decrementing, the product of two natural numbers can be computed efficiently based upon the following characterization of multiplication:

k·m = { 0   if k = 0(1)
(k/2)·(2m)   if k>0 ∧ k is even (2)
(k−1)·m + m   if k>0 ∧ k is odd (3)

Consider this example:

 25·7 
=24·7 + 7by (3)
=12·14 + 7by (2)
=6·28 + 7by (2)
=3·56 + 7by (2)
=2·56 + 56 + 7by (3)
=1·112 + 56 + 7by (2)
=0·112 + 112 + 56 + 7by (3)
=0 + 112 + 56 + 7by (1)
=175by addition

A Java method to compute multiplication based upon this approach is as follows:

/* Returns the product of the two given numbers.
** pre: k≥0 ∧ m≥0
*/
public static int productOf(int k, int m) {
   final int K = k;
   final int M = m;
   int r = 0;
   /* loop invariant: K*M = k*m + r, where K and M are the initial
   **                 values of k and m, respectively.
   */
   while (k != 0) {
      if (k % 2 == 0)            // k is even
         { k = k/2; m = m+m; }
      else                       // k is odd
         { k = k-1; r = r + m; }
      assert K*M = k*m + r;
   }
   // k is zero; hence k*m + r is just r.
   return r;
}

The figure below illustrates how the method's execution, when the parameters passed to it are 25 and 7, respectively, relates to the evaluation of 25·7 detailed above. On the left is shown the values of the method's variables initially and after each loop iteration. Notice how they correspond to the calculation on the right (repeated from above).

kmr
2570
2477
12147
6287
3567
25663 (i.e., 56+7)
111263 (i.e., 56+7)
0112175 (i.e., 112+56+7)
   
 25·7 
=24·7 + 7by (3)
=12·14 + 7by (2)
=6·28 + 7by (2)
=3·56 + 7by (2)
=2·56 + 56 + 7by (3)
=1·112 + 56 + 7by (2)
=0·112 + 112 + 56 + 7by (3)
=0 + 112 + 56 + 7by (1)
=175by addition