[std-interval] interval(NaN)

Guillaume Melquiond guillaume.melquiond at ens-lyon.fr
Sat Sep 16 15:29:08 PDT 2006


Le vendredi 15 septembre 2006 à 15:27 -0500, George Corliss a écrit :

> First, interval(NaN) should not be used by the programmer as a means for
> constructing an instance of the empty set.  There is a constructor for that,
> and the internal representation of empty should be hidden from the
> applications programmer.

Agreed. And note that's precisely this argument that makes me want
"interval(NaN,NaN)" to be an erroneous construct and hence undefined, as
in the current proposal. In particular, it allows an implementation to
abort on such an interval.

"interval(NaN)" was also undefined before. But it was changed after our
discussions at Dagstuhl, since we agreed there should be a way to
convert any floating-point value to an enclosing interval. The changes
were mainly motivated by infinities and it may have been a mistake to go
as far as defining the behavior for NaNs.

> Hence, interval(NaN) is likely to come up in a context such as
>    double w, x;
>    x = mess of double code which happened to result in NaN;
>    y = interval(x);
>    z = interval(w, x);

> 1. Empty.  If the NaN arose as, say, SQRT(-1), then y = empty is consistent
> with the exception-free operation of the proposal.  For w, I see no value
> that makes sense.
> 
> 2. Whole is attractive in the set sense - if there is a number y or z, they
> must belong to the universal set, but set difference can lead to a
> containment failure, so whole is not 100% safe.

In my opinion, there isn't any clear winner for the default constructor
when considering empty and whole (and singular may actually be a better
choice). But for interval(x), I feel like whole could be a better choice
than empty. Rationale: some clever interval algorithms first perform
efficient computations on floating-point numbers, and then verify/adjust
their computations with interval arithmetic. During the floating-point
computations, rounding errors could cause a square root of a negative
number or a division 0/0. Then whole would make more sense than empty.

Still, these clever algorithms could already be taking into account such
exceptional results. As a consequence, they would not be impacted by
whatever choice we made, since the constructor would never be called
with a NaN argument.

> 3. We want to avoid exceptions to the extent possible.
> 
> 4. Tag.  If we had a set of Boolean flags or similar associated with each
> interval object, one of those bits could be turned on to represent "Not an
> Interval."
> 
> The problem again is that two double word bit patterns lack the expressive
> power we need.

Not necessarily. Depending on the implementation, some pairs of
floating-point words may not qualify as valid intervals. For example,
you might imagine the following patterns:

- [5,0] empty interval
- [5,1] uninitialized interval (for debugging purpose)
- [5,2] not-an-interval (as a non-standard feature)
- etc

> The more of these examples I consider, the more attracted I
> become to the concept of tags, as variously promoted by Kahan and by Winter.
> However, many suspect a tagged implementation is slow, and we have no
> experience to prove otherwise.  I favor the standard allowing tags, as I
> believe it does, but it is not appropriate to require them.

Slowness is not my only concern. The less imaginative we are in adding
new fields, the more binary compatible we will be with other interval
implementations, be they in C++ or in other languages.

> Especially for interval(w, NaN), and by association also for interval(NaN),
> I am reluctantly led to prefer exceptions.  If you are so badly lost that
> your code is trying to form an interval, at least one of whose endpoints is
> Not a Number, it is probably time to quit.

Then it is better to flag it as undefined behavior in my opinion.

Best regards,

Guillaume



More information about the Std-interval mailing list