Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2006-05-16 23:42:49


"Robert Ramey" <ramey_at_[hidden]> writes:

> John Maddock wrote:
>
>> Hold on a second, C++ implements what the IEEE-754 standard requires
>> FP arithmetic to do,

Well, not quite. Most C++ implementations do implement IEEE-754.

>> and infinities and NaN are definitely part of that standard.
>
> Hmmm - I want to clarifiy this. (The quoted text is from
> http://docs.sun.com/source/806-3568/ncg_goldberg.html)

Well, no offense, but you did a very bad job of clarifying. It seems
like you went to an authoritative document and tried to use it to
support a number of incorrect conclusions. A casual reader might be
fooled into thinking that this document backs up your argument, but it
doesn't.

> a) IEEE-754 does specify infinities and NaN

Correct.

> C++ doesn't - C++ leaves it undefined and up to the
> implementation.

No and yes. C++ does not leave NaN and infinity undefined, but
whether to supply them is up to the implementation... just like
whether to supply int with value > 32767 is up to the implementation.

> b) IEEE-754 specifies flags to inquire as to the result of the last
> floating point operation. C++ doesn't specify anything about this.

Correct, it does not specify.

> c) "The IEEE standard strongly recommends that implementations allow trap
> handlers to be installed."
> C++ doesn't permit this.

Incorrect. C++ absolutely does permit implementations to allow trap
handlers to be installed. C++ simply does not require it.

> On the other hand, the C++ standard library does support throwing
> exceptions from functions sine(x) for domain errors and such.

That's not an "on the other hand," it's a case of identical treatment!

C++ supports the installation of trap handlers to precisely the same
degree that it supports throwing exceptions from sin(x): both are 100%
up to the implementation.

> So there's a mismatch here.

Incorrect. There's no mismatch; there's perfect consistency, as noted above.

> d) "Another ambiguity in most language definitions concerns what
> happens on overflow, underflow and other exceptions. The IEEE
> standard precisely specifies the behavior of exceptions, and so
> languages that use the standard as a model can avoid any ambiguity
> on this point. " But C++ doesn't permit exceptions to be thrown in
> these instances.

Incorrect. Exceptions can be thrown anywhere that undefined behavior
is specified. Overflow, underflow, and divide-by-zero all induce
undefined behavior.

>> I assure you that they do have legitimate uses,
>
> Actually, the paper cited about give a good example of a such
> legitimate use. I believe such uses are far less common than people
> seem to think. Even the example cited in the paper wouldn't require
> saving and recovering from a text stream.
>
>> but more to the point, it's not only divide by zero that generates
>> infinities, heck even addition (or subtraction) can generate
>> infinities if push comes to shove.
>
> Of course, I'm just using divide by zero as a one of the most common
> cases. But it occurs in other cases.
>
> So C++ is out of sync with IEEE-754.

It's not out of sync, and IEEE-754 is much better supported than any
number of other optional features of the language. Explicit
provisions are made for it in the standard.

> I see two ways to put it into sync.
>
> a) define what C++ should do for currently undefined operations like divide
> by zero and the others.
>
> b) require that C++ implementations throw exceptions when undefined
> operations are invoked.

b) is just a special case of a). I will agree that eliminating
undefined floating point behaviors will make C++ more predictable.

> Until one of the above (or maybe something else) is done. There can really
> be no unambiguous resolution to the problem of passing results from
> undefined operations from one machine to another.

Of course there can be. All you need to do is write a specification
for it that describes what happens in all cases, and it will be
unambiguous. If you can do this for ints that have nonportable values
greater than 32767, you can do it for floats and doubles, too.

> Obviously, I believe that the adoption of b) above would result in
> fewer programs with hidden bugs.

That's almost certainly wrong. Floating point divide-by-zero is
almost never due to a program bug. And you can get the same effects
when dividing by a nonzero number if the result can't be represented.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk