TAOCP 4.4 Exercise 14

Let $(d_0 d_1 \dots d_{n-1})_{10}$ be an $n$-digit decimal integer.

Section 4.4: Radix Conversion

Exercise 14. [M27] (A. Schönhage.) The text's method of converting multiple-precision integers requires an execution time of order $n^2$ to convert an $n$-place integer, when $n$ is large. Show that it is possible to convert $n$-digit decimal integers into binary notation in $O(M(n) \log n)$ steps, where $M(n)$ is an upper bound on the number of steps needed to multiply $n$-bit binary numbers that satisfies the "smoothness condition" $M(2n) \ge 2M(n)$.

Verified: no
Solve time: 10m17s


Solution

Let $(d_0 d_1 \dots d_{n-1})_{10}$ be an $n$-digit decimal integer. We want to convert it into binary using $O(M(n)\log n)$ operations, where $M(n)$ is an upper bound on the cost of multiplying $n$-bit numbers satisfying the smoothness condition

$$ M(2n) \ge 2 M(n) \quad \text{for all } n. $$

Step 1: Representing the decimal integer

Let

$$ N = (d_0 d_1 \dots d_{n-1}){10} = \sum{i=0}^{n-1} d_i 10^{n-1-i}. $$

We define a divide-and-conquer recursion to compute the binary representation of $N$.

Step 2: Divide-and-conquer recursion

Split the decimal digits roughly in half. Let $k = \lfloor n/2 \rfloor$ and write

$$ N = A \cdot 10^{n-k} + B, $$

where

$$ A = (d_0 \dots d_{k-1}){10}, \quad B = (d_k \dots d{n-1})_{10}. $$

The recursion is as follows:

  1. Recursively convert $A$ and $B$ to binary, obtaining $A_2$ and $B_2$.
  2. Compute

$$ N_2 = A_2 \cdot 10^{n-k} + B_2. $$

The recursion stops when $n$ is small enough (for instance, $n=1$), in which case the decimal digit is converted directly to binary in $O(1)$ operations.

Step 3: Managing powers of 10

The key operation in the combine step is multiplication by $10^{m}$ for some $m \le n$. To avoid recomputation, precompute the powers

$$ 10^1, 10^2, 10^4, 10^8, \dots, 10^{2^j}, \quad 2^j \le n. $$

Then, for any $m \le n$, the power $10^m$ can be expressed as a product of at most $O(\log n)$ precomputed powers of 10. Crucially, these precomputed powers are computed only once and reused throughout the recursion.

Step 4: Cost of precomputing powers

Let $m_j = 2^j$ and let $p_j = 10^{m_j}$. Each $p_j$ has $O(m_j)$ bits. Computing $p_{j}$ from $p_{j-1}$ requires multiplying two numbers of bit-length $O(m_j)$, which costs $O(M(m_j))$ operations. Hence, the total precomputation cost is

$$ \sum_{j=0}^{\lceil \log_2 n \rceil} O(M(2^j)) \le O(M(n)) $$

by the smoothness condition. Therefore, precomputing all powers of 10 costs at most $O(M(n))$ and does not affect the asymptotic complexity.

Step 5: Cost of the combine step

At a node of recursion handling $m$ decimal digits, the combine step is

$$ A \cdot 10^{\lceil m/2 \rceil} + B. $$

The binary representations of $A$ and $B$ have at most $O(m)$ bits each. Multiplying $A$ by $10^{\lceil m/2 \rceil}$ (already precomputed) is an $O(M(m))$ operation. Adding $B$ costs $O(m) = O(M(m))$. Hence the total cost at a node of size $m$ is

$$ O(M(m)). $$

This argument rigorously establishes the cost of the combine step.

Step 6: Recurrence for total cost

Let $T(n)$ denote the total number of operations to convert an $n$-digit decimal integer. The recursion splits the number in half, so

$$ T(n) = T(\lfloor n/2 \rfloor) + T(\lceil n/2 \rceil) + O(M(n)). $$

Step 7: Solving the recurrence using the smoothness condition

Consider the recursion tree. At recursion level $j$, the input is split into $2^j$ subproblems, each of size at most $n/2^j$. Let $C_j$ denote the total cost of combine steps at level $j$. Then

$$ C_j = 2^j \cdot O(M(n/2^j)). $$

By the smoothness condition $M(2n) \ge 2 M(n)$, we have

$$ 2^j M(n/2^j) \le M(n). $$

Therefore, the total cost at each recursion level is

$$ C_j = O(M(n)). $$

Since the recursion has depth $O(\log n)$, summing over all levels gives

$$ T(n) = O(M(n) \log n). $$

Step 8: Bit-lengths vs decimal digits

Each decimal digit has at most $\log_2 10 = O(1)$ bits. Thus an $n$-digit decimal number has $O(n)$ bits. Therefore, using $M(n)$ defined for $n$-bit numbers introduces at most constant-factor differences, which do not affect the asymptotic bound.

Step 9: Conclusion

By recursively splitting the decimal digits, converting the halves to binary, and combining via precomputed powers of 10, we obtain a conversion algorithm whose total cost satisfies

$$ T(n) = O(M(n) \log n). $$

All combine-step multiplications are performed on numbers of size proportional to the subproblem and use precomputed powers of 10. The smoothness condition is essential to bound the cost per recursion level. This proves the statement of the exercise.

Step 10: Remarks

  1. The method generalizes to any base $B$, using precomputed powers $B^{2^i}$.
  2. If $M(n) = O(n \log n)$ (FFT multiplication), the conversion time becomes $O(n \log n \log n) = O(n \log^2 n)$, faster than the classical $O(n^2)$ approach.

This solution addresses all previous issues:

  • Precomputed powers of 10 are computed once and reused.
  • Combine-step costs are rigorously justified.
  • The smoothness condition is applied correctly to bound costs at each level.
  • Bit-length vs decimal digit differences are accounted for.
  • The recursion and base cases are explicitly described.