Next we compute $\overline{b} - \underline{b}$
for the three methods other than policy iteration, where
$I$ is the number of iterations required to fulfill the termination condition, and
$$
\begin{aligned}
\underline{b} &= \frac{\beta}{1-\beta} \min\left[T(v^{I-1}) - v^{I-1}\right], \\\\
\overline{b} &= \frac{\beta}{1-\beta} \max\left[T(v^{I-1}) - v^{I-1}\right].
\end{aligned}
$$

It appears that our value iteration with span-based termination is different in some details
from the corresponding algorithm (successive approximation with error bounds) in Rust.
In returing the value function, our algorithm returns
$T(v^{I-1}) + (\overline{b} + \underline{b})/2$,
while Rust's seems to return $v^{I-1} + (\overline{b} + \underline{b})/2$.
In fact: