With ULP_ONE_PLUS
and
ULP_ONE_MINUS
in hand from the previous sections,
we recompute the radix B
and define
some constants used throughout the remainder of the code.
BIG_B_NTH
is the power of B
one larger
than the longest string of B-1
digits.
We can determine B
from the ratio of ULP_ONE_PLUS
and
ULP_ONE_MINUS
. While the following example is 6-digit
decimal, the number pattern would be the same in
any radix.
The ratio of the ulp values should be exactly B
, but
the code uses the idiom foor(0.1 + ratio)
to
guard against problems in division and perhaps because of fuzziness
in log arithmetic, which is to be discussed separately.
If the recalculation of B
doesn't jibe with the first
try, we proclaim it a MYSTERY and forge ahead. We leave
the matter for the user to resolve. Then we note as a defect
a radix larger than \( 16 \) and as a flaw a radix neither
\( 2 \) nor \( 10 \).
BIG_B_NTH = ONE / ULP_OF_ONE_MINUS
ONE_MINUS_ULP = (ONE_HALF - ULP_OF_ONE_MINUS) + ONE_HALF
save_b = B
B = floor(0.01 + ULP_OF_ONE_PLUS / ULP_OF_ONE_MINUS)
B_OVER_TWO = B / TWO
ONE_OVER_B = ONE / B
if (B == save_b):
print("B confirmed.")
else:
print("MYSTERY: recalculated B = {:0.7e} .".format(B))
test_cond(err_defect, B <= EIGHT + EIGHT,
"B is too big: roundoff problems")
test_cond(err_flaw, (B == TWO) or (B == 10)
or (B == ONE), "B is not as good as 2 or 10")
Exercise: Complete the calculation
of BIG_B_NTH
in binary, and look at the value
\( 1 \) less.