11.001001000011111101101010100010001000 Arithmazium
Home

find_ulp_of_one_minus() – the setup

This function is the factor \(1 / B\) smaller cousin of find_ulp_of_one_plus, which you can refer to for more elaboration of the fine points.

We start with the value \(2 / 3\), which rounds in any radix not a multiple of \(3\). It's bigger than one-half, so it lies in the exponent range just below 1.0 in any of radix 2, 8, 10, or 16.

0.1 1.0 2/3

Following the earlier discussion, \(2 / 3\) has the decimal value \(0.6666\cdots\) and the binary value \(0.101010\cdots _{2}\). Analogous to the case of \(4 / 3\), the value TWO / THREE evaluates to \(2/3 + \epsilon\). The rounding error \(\epsilon\) is \(+1 / 3, +4 / 3, +7 / 3, \ldots\) or \(-2 / 3, -5 / 3, -8 / 3, \ldots\) ulps of values just less than 1.0.

We then isolate and triple \(\epsilon\) by computing \[ | (1/6 + \epsilon) + ((1/6 + \epsilon) \times 2) - 1/2) | \] which reduces to \[ | (1/6 + \epsilon) + (-1/6 + 2\epsilon) | \] all in exact arithmetic. As in the cousin function, it simplifies to \( | 3 \epsilon |\).

Here is a binary diagram showing the case of odd precision.

x = TWO / THREE    0101...10101010 the highlighted bit must be rounded, regardless of the precision sixth = x - ONE_HALF    0001...101? the subtraction is exact, preserving the rounding error third = sixth + sixth    0010...01?0 doubling shifts the rounding error x = third - ONE_HALF   -0001...1??0 negative 1/6 is rounded in the opposite direction of sixth fabs(x + sixth)    0000...0??? some ulps of values just less than 1.0

The value \(1 / 6\) is subtracted out, leaving a whole number of ulps of values just less than 1.0, regardless of the radix.

def find_ulp_of_one_minus(guess):
    """Compute u such at 1-u is the next smaller value than 1."""
    x = TWO / THREE
    sixth = x - ONE_HALF
    third = sixth + sixth
    x = third - ONE_HALF
    x = fabs(x + sixth)
    if (x < guess):
        x = guess
    # Now  x == (unknown no.) ulps of 1-.

Your turn

Exercise: Replay the binary case with even precision to see that it also proudces an ulp of 1.0.

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

x = TWO / THREE    0666666666 the low-order 6s will round off sixth = x - ONE_HALF    0166667 1/6 is rounded up in the low digit of 1.0- third = sixth + sixth    0333334 1/3 is rounded up

Can you complete the computation of x?

Exercise: This diagram illustrates the computation of x in 6-digit octal arithmetic. We assume chopped arithmetic, as found on Burroughs computers of the 1960s.

x = TWO / THREE    0525252552 the low-order digits will be chopped sixth = x - ONE_HALF    0125252 1/6 is chopped in the low digit of 1.0- third = sixth + sixth    0252524 the rounding error is doubled x = third - ONE_HALF   -0125254 larger than 1/3 by x + sixth   -0000002 two ulps of 1-

Now rerun the computation in 7-digit octal.

Home