11.001001000011111101101010100010001000 Arithmazium
Home

find_ulp_of_one_plus() – the iteration

So far, we have computed a value x with one or more ulps of 1.0. Next, we exploit a powerful numerical idiom of Paranoia:

When searching for the smallest value with a given property, start with a handy value at least as big and iterate downward.

The iteration exhibits another useful technique: the creation of nonzero low-order digits to encourage an upward round, if there's nearly a half-way case. The binary diagram below shows how u is halved, but with some added nonzero low-order bits. Since u is some ulps of \(1.0\), u * u is some ulps of u. The factor THIRTY_TWO shifts those bits well back into u in radix 2, 8, or 16. The diagram continues the binary tale.

ONE    100 ... 00 1.0, showing binary point alignment u = ...    000 ... 11 suppose u is 3 ulps of 1.0 x = ONE_HALF * u + ...    000 ... 0110??? x is half u, with nonzero low bits

In decimal, the factor THIRTY_TWO ensures some nonzero low-order digits in x.

The expression x + ONE rounds to 1.0 plus some ulps of one. Subtracting ONE is exact, leaving just the ulps. Successively halving the value walks it down to a single ulp.

    while True:
        u = x
        x = ONE_HALF * u + THIRTY_TWO * u * u
        x = x + ONE
        x = x - ONE
        if u <= x or x <= ZERO: break
    return u


Your turn

Exercise: Complete the binary case started in the diagram above to see that it results in one ulp of 1.0.

Exercise: The decimal diagram below starts the iteration in 6-digit rounded decimal arithmetic.

ONE    100000 1.0, showing decimal point alignment u = ...    000005 suppose u is 5 ulps of 1.0 x = ONE_HALF * u + ...    0000025 the 2 will be rounded up after adding then subtracting 1 x = x + ONE    100003 u will be 0.00003 in the next step

Continue the loop to find one ulp of 1.0.

Exercise: Complete the computation in 6-digit chopped octal arithmetic.

u = ...    000005 suppose u is 5 ulps of 1.0 in octal x = ONE_HALF * u + ...    0000024 the 4 will be chopped remember, this is octal! x = x + ONE    100002 half u will be 0.00001 in the next step; almost there
Home