// Inv1: a > 0 && b < 0 |
|
c = a * b; |
|
// Inv2: a > 0 && b < 0 && c == a * b && c < 0 |
// or equivalently |
// Inv2: Inv1 && c == a * b && c < 0 |
|
a = -a |
|
// Inv3: a < 0 && b < 0 && c == (-a)*b && c < 0 |
|
// Pre-Condition: a is defined. |
|
b = a; |
|
// Inv1: b == a |
|
if ( b % 2 ) { |
// Inv2.1: Inv1 && b is odd |
|
b = b + 1; |
|
// Inv2.2: b == a + 1 && b is even |
} |
else { |
// Inv3.1: b is even |
} |
|
// Inv4: b is even && ( b == a || b == a + 1) |
|
// Post-Condition: b is the smallest even integer >= a |
|
// Pre-Condition: a, b are defined |
|
r = 0; |
p = a; |
q = b; |
|
while ( p ) { |
if ( p & 1 ) { |
r = r + q; |
} |
p = p >> 1; |
q = q + q; |
} |
|
// Post-Condition: r = a * b |
// Pre-Condition: a, b are defined |
|
r = 0; |
p = a; |
q = b; |
|
// Base: r == a * b - p * q |
|
while ( p ) { |
// Inv1: r == a * b - p * q |
|
// Inv1 (assumed true at top of the loop, due to |
// Base for the first time, |
// Induction at end of loop for remaining times |
|
|
if ( p & 1 ) { |
r = r + q; |
|
// Inv2: p is odd && r = a * b - p * q + q; |
} |
|
// Inv3: (p is even && r == a * b - p * q) || |
// (p is odd && r == a * b - p * q + q) |
|
// Point *1: |
p = p >> 1; |
// Point *2: |
|
// Inv4: r == a * b - (2 * p * q) |
|
// Point *3: |
q = q + q; |
// Point *4: |
|
// Inv5: r == a * b - (2 * p * q/2) |
// Induction: r == a * b - p * q |
} |
|
// if we get here, it is because p == 0 |
// so, r == a * b - 0 * q == a * b |
|
// Post-Condition: r = a * b |
|
Case 1: p is even, i.e. p & 1 == 0
At *1
r == a * b - p * q
At *2 p has been shifted right 1, i.e. divided by 2, with no remainder so
r == a * b - (2 * p) * q
Case 2: p is odd, i.e. p & 1 == 0
At *1
r == a * b - p * q + q
At *2 p has been shifted right 1, i.e. divided by 2, but with remainder 1 so
r == a * b - (2 * p + 1) * q + q
== a * b - (2 * p) * q - q + q
== a * b - (2 * p) * q
So both cases give the same result:
r == a * b - (2 * p * q)
r == a * b - (2 * p * (q/2)) == a * b - p * q
8. Reasoning About Programs Tangible Computing / Version 3.20 2013-03-25 |