We discovered the radix by looping in search
of a carry into the B
's place of a large power of \(2\).
Now, we discover the precision – the number of significant
digits carried – by adding \(1\) to successive powers of
B
until the addition finally triggers rounding.
The diagram looks the same in any radix. It's shown here
in binary.
The rounding arises when B
is raised to the power that is the
precision of the number system. The code sidelines the case of
radix 1.0
, perhaps because of log
arithmetic.
Otherwise, we call
find_precision_big_B_to_nth()
to
loop on powers of B
until adding 1.0
causes
no increase.
# Compute PRECISION and BIG_B_NTH = B**PRECISION barely too big
# to satisfy (BIG_B_NTH + 1) - BIG_B_NTH == 1 .
# Basic 1240-1270
if B == ONE: # defer to the secondary calculation below
PRECISION = ZERO
BIG_B_NTH = big_2_nth
else:
PRECISION, BIG_B_NTH = find_precision_big_B_to_nth(B)
The N
in BIG_B_NTH
is the precision,
barring very anomalous rounding behavior.
This means that \(B ^ {-(N-1)}\) should be an ulp of 1.0
, and
\(B ^ {-N}\) should be an ulp of numbers just less than 1.0
.
We record these guesses for now and move on to further refinement.
guess_ulp_of_one_minus = ONE / BIG_B_NTH
guess_ulp_of_one_plus = B * guess_ulp_of_one_minus
print("Closest relative separation found is ULP_OF_ONE_MINUS = {:0.7e} ."
.format(guess_ulp_of_one_minus))