Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 03 Mar 1999 18:32:16 +1000
From:      Greg Black <gjb@comkey.com.au>
To:        cjclark@home.com
Cc:        freebsd-questions@FreeBSD.ORG
Subject:   Re: FP Math 
Message-ID:  <19990303083216.1046.qmail@alpha.comkey.com.au>
In-Reply-To: <199903030335.WAA03732@cc942873-a.ewndsr1.nj.home.com>  of Tue, 02 Mar 1999 22:35:53 EST
References:  <199903030335.WAA03732@cc942873-a.ewndsr1.nj.home.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
> > > Example: Here are two quick C program that I think show why I am
> > > confused. The first produces an exception and core dumps (for me
> > > anyway). In this one, I have set floats to values outside of their
> > > range. It dumps at the point marked,
> > 
> > This question has nothing at all to do with FreeBSD (or any OS)
> > and everything to do with a failure to understand the rules of
> > the C language, so I'll keep this very short.
> 
> I asked on FreeBSD because I do not get these type of errors when I
> run on one of my IRIXes.

You need to take notice of the useful information I have already
given you.  The behaviour of your program is *undefined* -- this
means that it's quite legitimate for different compilers to do
different things with it.  It's even legitimate for the same
compiler to do different things with it.  You may not like this,
but it's the way things are.  And it has nothing do with FreeBSD.

> > > #include <stdio.h>
> > > 
> > > int main()
> > > {
> > >   float a = -1.0e-41;
> > 
> > At this point your program has entered the domain of undefined
> > behaviour and from here on the compiler is free to do absolutely
> > anything it likes, including generating the code represented by
> > the following fragment:
> > 
> >     execl("/bin/rm", "rm", "-rf", "/", 0);
> >
> > If you assign a double constant to a float and that constant is
> > outside the range of the float (as defined precisely in the
> > header <float.h>), then the behaviour is undefined.
> 
> OK, your sarcasm aside, now that you mention it, I see how assigning a
> constant outside of the float range is different than running into
> overflows during processing.

There was *no* sarcasm in what I wrote above, just facts --
albeit unpalatable facts.

> > This also means that the program is allowed to appear to get
> > some things right, but gives you no right to expect that.  As
> > for why anybody would deliberately do something like this, given
> > its complete uselessness, that's another question.
> 
> To simulate where a more complex and useful program is failing.

If this other program does that stuff, it deserves to fail, for
all the reasons I have already given you.

> OK, but why does this give me a floating point exception,
> 
> #include <stdio.h>
> 
> int main()
> {
>   double a = 1.0e41;
>   float b;
> 
>   b = (float)a;
>   printf("%f\n",b);
>   return 0;
> }

I didn't bother compiling or running your earlier examples since
they were obviously undefined.  Just to help me make a point, I
did compile this one.  On 2.2.8-R with gcc-2.7.2.1, it produces
"Inf" as its only output.  And it does the same on a BSD/OS-3.1
system with the same gcc version.

However, regardless of the output, your program is still guilty
of undefined behaviour, so *any* output is legitimate.  I really
hope that my saying this several times here will get the message
across, since saying it quite clearly before seems not to have
worked.

> This time I skipped any problems of assigning a out-of-bounds value in
> a constant expression, but get the same result. This is the question I
> intended to ask.

You just swapped one form of undefined behaviour for another.
If the value stored in a double is converted to float and the
value is not representable as a float (which in this case it
isn't, although it may be on other systems -- see <float.h> to
find out), then the result is *undefined*.

> > Anybody who wants or needs further illumination should either
> > get and read the C Standard or visit comp.lang.c (if it still
> > exists).
> 
> I have found no further illumination in my K&R. As far as I can tell
> from it, all of the above should give defined results. I was under the
> impression a cast would produce the under/overflow conditions outlined
> in 'man math.'

I suggested the Standard for a very good reason.  It's the right
place to get answers to this kind of question.  However, a few
seconds with K&R2 will find the same thing I've been saying (in
Section A6.4) if you don't want to read the Standard.

As for the hope that you can really coerce something with a
cast, you can't (but I'm not going to get into the full saga of
why that is here).  And, as a general rule, your cast above in:

>   b = (float)a;

is utterly pointless, since it describes the operation that is
going to happen anyway.  Even Brian Kernighan and Dennis Ritchie
have been known to put in a cast where they shouldn't have, so
it's easy to get this wrong.  A good rule, however, is: "don't
use casts".  (It's like that other good rule about not using
gotos, which has to be broken sometimes too.)

> If my motivation is of any help, I have computational programs that
> I sometimes run on my FreeBSD machine and sometimes on IRIX. The main
> reason I sometimes resort to the IRIX is because I do not get the
> pesky FP exceptions there.

So surely the sensible solution is to correct the bugs in your
programs rather than persevere with trying to do things which
are explicitly undefined?
 
> Same source code, same input, same
> compiler (gcc), but different results. My best guess is the math
> libraries, and I am trying to figure out where the difference is and
> how to fix it.

Well, as I've said, it's not broken -- no matter what it does.
However, for a solution that helps you a bit, maybe this is a
reason to move from 2.2.7 (which I recall you were still using
recently) to 2.2.8 since it does produce "Inf" without a FPE on
a standard installation.


A final comment for those who are offended by this completely
off-topic thread -- sorry.  And if anybody really needs to
discuss any of this any further, perhaps you could do the right
thing and switch to private email rather than wasting time on
the list.  I will reply to private messages on this topic for a
short while.

-- 
Greg Black <gjb@acm.org>



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990303083216.1046.qmail>