Satan loves extended precision

David G. Hough at validgh dgh
Thu Jan 19 10:04:55 PST 1995


> 
> On chips like the 486DX that have internal extended precision registers,
> is it possible to calculate the single or double precision result of a
> single operation by performing the operation in extended precision, then
> storing the result to memory?

One IEEE op as in c = a op b produces the same result in single precision
whether the intermediates are rounded to single or extended precision,
except possibly for problems with underflow on x86.   [m68k doesn't have
the underflow problem.]   Also except if the
compiler doesn't force c to be rounded to single precision, usually by
storing.    The same does not apply to double precision, however, nor does
it apply to multiple IEEE ops as in c = a op b op c.

> 53 bits can produce a different answer than rounding directly to 53 bits.
> However, it is possible for a chip that stores 80-bit extended precision
> numbers internally to save a little extra state to ensure that when a
> number is stored to memory, it is rounded just as it would have if it had
> originally been rounded to 53 bits, thereby complying with the IEEE 754
> standard.

Another way to obtain the effect of rounding precision for c = a ob b - 
not expressible portably yet, and even less efficient -
is to compute a op b in extended round to zero mode, so the lsb is effectively
sticky.   If the subsequent store is performed in the intended rounding mode,
then it will be correctly rounded.   This works for single or double, but
not for c = a op b op d.

>     x := a + b
>     e := x - a
>     y := b - e

I think you could count on this to always produce x+y == a+b if you could
count on the compiler forcing storage to rounding precision on explicit
assignments.    volatile doesn't always seem to accomplish that.

More generally, compilers for PC's don't usually seem to handle extended
precision very well.   Some of the rules for maximum performance consistent
with predictability could be fairly simply stated:

Implicit temporaries may be left unrounded in extended precision registers
but explicit assignments to named variables must cause rounding to the
storage precision of those variables; one way that always works is to
generate a round and store instruction following by a load instruction.
Future x86 hardware might be designed to recognized that idiom and optimize
it somehow.   Function parameters must be rounded to declared precision by
the caller and function return values must be rounded to declared precision
by the callee; the x86 ABI practice of returning function value in the
top of the floating-point stack doesn't point compiler writers in the right
direction here.

One situation that might be argued about is

	if ( var >= expression)

should a type be inferred for the comparison, and expression rounded 
accordingly prior to comparison?   Then what about

	if (expression1 >= expression2)

Consider the case

	c = a + b ;
	if ( c == (a + b) ) ...

Some programs would want this to work one way, others another.
Are there any more uncertain cases like that?

Fortran is different from C in one respect:  generic intrinsic functions
don't have to force any kind of conversion since they can operate on 
several types.   So should the semantics of sqrt(expression) vary 
depending on whether the extended type is supported in the language?
Should one be obliged to insert explicit type conversions to get extended
precision sqrt in the case

	z = sqrt( x*x + y*y)

It would be preferable for this case to evaluate in extended automatically,
but that rule might be problematic in other cases.



More information about the Numeric-interest mailing list