Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

Edge case conversions, exceptions to IEEE FPA



I got the feeling that the two of you were partially talking past each
other, instead of actually disagreeing on the conversion of floats to
intervals.  But after trying to work out the details, I come to the
conclusion that, in the context of a language-independent interval
standard,  Arnold's original proposal "Inf -> Empty" is the only one
that is consistent.  The difficulties that this leads to can for the
most part be avoided in languages with explicit interval support, but
in general intermediate values of Inf must be avoided by the programmer,
and the standard should provide the means to do so.

Part of this comes from a certain ambiguity in a statement like:
   X = intval(1e400)

Does "1e400" stand for the value of a floating-point variable, or
does it stand for a literal string in some programming language?
(It could well be a value -- exact in IEEE 754-2008 Decimal128,
or an approximation thereof in IEEE 754-2008 Binary128.)

If it is a language literal (which I think is the position Siegfried
takes), language rules determine the type of the literal.  If the
language itself supports Interval types, it may well do the "right
thing", i.e. one-step conversion.  If not, there is not much an IA
standard (that purports to be language-independent) can do about it.

If it is a value, it is no different from 0.1 -- it simply CAN't be
the value of a binary FP variable, but it would be fine with DFP.
So the question becomes whether '1e400' is used as shorthand for
the exact value 0x1B4EC7F91973FF3CB1CCF26FBC178p1216 (Binary128)
or not.  We don't know that in general, so the programmer needs to
say so, in a language that does not support native Interval types.

That's why Arnold suggests using string literals, because string
syntax allows various formats that can supply the missing information.

Now, with respect to Inf conversion, i.e what happens when 1e400 is
converted to Inf "under the cover".  Can we deal with this?

Perhaps so, given that both of you agree that the underlying model
is the non-extended Reals.  It is therefore possible to interpret
the 754 value Inf as standing for "a large finite value" -- but
what exactly does this mean?  If we knew that the value was larger
than realmax in the IA implementation format (aka HUGE), Siegfried's
translation to [realmax, Inf] would make perfect sense.  There are
the following issues however.

(1)  IEEE arithmetic can yield exact Inf -- but only in contexts
     that involve division by zero.  This could be dealt with by
     trapping or monitoring the IEEE divideByZero exception.

     For example, the IA runtime could clear the DZ flag initially,
     and when converting Inf to an interval, it would return Empty
     when DZ was set, and [realmax,inf] if not.

     This leaves the issue of when to clear the DZ flag...

(2)  IEEE arithmetic propagates Inf -- but although an original Inf
     (as the result of overflow) denotes a value that exceeds realmax,
     a propagated Inf does not.  There is not much we can do about
     this, as Inf propagation is silent under IEEE 754.

     This suggests that Inf can only be mapped to Entire, which is no
     better than Empty, in my opinion.  (The result of a computation
     that overflowed could be anything if it had been carried out with
     a larger exponent range that avoided overflow.)


Now, Siegfried says:
> My interpretation of the input inf is a huge number, so that ...

This would be acceptable if we knew that this inf was in fact an
input, i.e. the direct result of a conversion of something that
did not fit in the floating-point format.  My point (2) however
shows that this cannot be depended on -- which is why it is better
to supply the "something" directly to the interval constructor.
The "something" could be a string, or a float in a wider format
than the IA implementation format.

Later Siegfried gets into trouble:

> Converting 1e400 into ?realmax,realmaxÙ would also be strange to me
> because, e.g.,
>    intval(1e500) / 1e400 = ?1,1Ù
> in this definition.  In your (original) definition it would be empty,
> in mine ?1,infÙ.

What if the example reversed 1e500 and 1e400?  Then both definitions
based on realmax would be wrong, but "empty" would still be right,
even if bothersome.

> Both interpretations are consistent, one has to be chosen.

Sorry, but I'm afraid this is not so -- at least not if we want to
believe enclosure properties.  The best we can do is AVOID coming
across Inf (except as a bound, which is mostly(*) an internal IA
concept), which means monitoring the floating-point exceptions
divideByZero and Overflow outside of IA.  The IA implementation
may well encounter exceptions internally, but it would hide them
from the programmer.  The monitoring of exceptions can be done
by checking IEEE flags before submitting floats to conversion,
or by checking for (possibly propagated) Empty intervals later.

Michel.

(*)  The Interval->Float functions inf() and sup() that return the
     bounds can return Inf -- and if this is fed into an interval
     constructor as a value (instead of as a bound), an exception
     should arise.  Arnold's proposal covers this; the result of a
     violation is simply Empty.
Sent: 2008-11-11 20:30:18 UTC