11.001001000011111101101010100010001000 Arithmazium
Home

Recalculate radix

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.

ONE    100000 exhibit decimal point alignment ULP_ONE_MINUS    0000001 the 1 falls one digit to the right ONE / ULP_ONE_MINUS   1000000 10**6, where 6 = precision # 1 less    999999 10**6 - 1

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.

ONE    100000 exhibit decimal point alignment ULP_ONE_PLUS    000001 adds to 1.0 exactly ULP_ONE_MINUS    0000001 should be 1/B smaller

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")

Your turn

Exercise: Complete the calculation of BIG_B_NTH in binary, and look at the value \( 1 \) less.

ONE    100 ... 00 binary point alignment ULP_ONE_MINUS    000 ... 001 one bit further right
Home