TAOCP 4.3.1 Exercise 12
Exercise 4.
Section 4.3.1: The Classical Algorithms
Exercise 12. [16] Algorithm S assumes that we know which of the two input operands is the larger; if this information is not known, we could go ahead and perform the subtraction anyway, and we would find that an extra borrow is still present at the end of the algorithm. Design another algorithm that could be used (if there is a borrow present at the end of Algorithm S) to complement $(w_{n-1} \ldots w_1 w_0)_b$ and therefore to obtain the absolute value of the difference of $u$ and $v$.
Verified: yes
Solve time: 15m14s
Corrected Solution for Exercise 4.3.1.12
Exercise 4.3.1.12 asks for a method to obtain the absolute value of the difference of two $n$-place numbers $u$ and $v$ in radix $b$, using Algorithm S when it is unknown which operand is larger. Algorithm S computes the digitwise subtraction $(u - v)$ with borrow propagation, assuming the larger operand is known. If the larger operand is not known, performing the subtraction anyway may result in a final borrow $c_n = 1$, indicating that $u < v$.
Let $(w_{n-1}, \dots, w_0)b$ denote the digits produced by Algorithm S. If the final borrow is zero, then $u \ge v$ and the computed digits are already correct. If the final borrow is one, then $(w{n-1}, \dots, w_0)_b$ represents the $b$-complement of the absolute difference $|u-v|$. A correction is required to obtain the true absolute difference.
Step 1: Radix complement principle
Let $W = (w_{n-1} \dots w_0)_b$ be the number computed by Algorithm S. If a final borrow $c_n = 1$ is present, then
$$ W = u - v + b^n = b^n - (v-u), $$
because performing $u - v$ with $u < v$ effectively computes the complement modulo $b^n$. Therefore, the absolute difference is
$$ |u-v| = (b^n - W) = (b^n - 1 - (W-1)) = (b^n - 1 - W) + 1. $$
Equivalently, in terms of digits, complement each digit $w_i$ by
$$ w_i' = (b-1) - w_i, $$
and then add $1$ to the least significant digit, propagating carries as in Algorithm A. This produces the correct absolute difference.
Step 2: Digitwise correction algorithm
Algorithm: Absolute Difference via Complement
Input: digits $(w_{n-1}, \dots, w_0)$ computed by Algorithm S, radix $b$, final borrow $c_n$.
Output: digits $(d_{n-1}, \dots, d_0)$ representing $|u-v|$.
- If $c_n = 0$, set $d_i \gets w_i$ for all $i$ and return. The subtraction result is correct.
- If $c_n = 1$, perform the following complement procedure:
a. For $i = 0$ to $n-1$, compute the digitwise complement:
$$ w_i' \gets (b-1) - w_i $$
b. Initialize carry: $c_0 \gets 1$ (to account for the "+1" in the radix complement).
c. For $i = 0$ to $n-1$, compute
$$ t_i \gets w_i' + c_i $$
$$ d_i \gets t_i \bmod b $$
$$ c_{i+1} \gets \lfloor t_i / b \rfloor $$ 3. Return $(d_{n-1}, \dots, d_0)$ as the absolute difference $|u-v|$.
Step 3: Explanation
If a final borrow is present, the output of Algorithm S represents the complement of $|u-v|$. The complement procedure corrects the digits by inverting each digit relative to $b-1$ and adding one, which restores the true absolute difference. The procedure works digit by digit and is entirely analogous to standard two's complement arithmetic in binary, generalized to radix $b$.
Step 4: Example
Let $b = 10$, $n=3$, $u = 123$, $v = 456$. Applying Algorithm S without knowing which operand is larger produces
$$ W = (w_2, w_1, w_0) = 667, $$
with a final borrow $c_3 = 1$. Digitwise complement:
$$ w_2' = 9 - 6 = 3, \quad w_1' = 9 - 6 = 3, \quad w_0' = 9 - 7 = 2 $$
Add 1 to the least significant digit:
$$ d_0 = 2 + 1 = 3, \quad d_1 = 3, \quad d_2 = 3 $$
No carry beyond the most significant digit. The absolute difference is $|123-456| = 333$, as expected.
Step 5: Summary
The algorithm for correcting a final borrow in Algorithm S proceeds in two stages: first, digitwise complement each output digit, then add one using standard carry propagation. If no final borrow occurs, the original output is already correct. This procedure produces the absolute value of the difference without requiring prior knowledge of which operand is larger. The method generalizes naturally to any radix $b$ and any number of digits $n$.