From owner-freebsd-questions Thu Mar 4 2: 5:46 1999 Delivered-To: freebsd-questions@freebsd.org Received: from alpha.comkey.com.au (alpha.comkey.com.au [203.9.152.215]) by hub.freebsd.org (Postfix) with SMTP id 4FE68150C3 for ; Thu, 4 Mar 1999 02:05:36 -0800 (PST) (envelope-from gjb@comkey.com.au) Received: (qmail 6470 invoked by uid 1001); 4 Mar 1999 10:02:59 -0000 Message-ID: <19990304100259.6469.qmail@alpha.comkey.com.au> X-Posted-By: GBA-Post 1.04 06-Feb-1999 X-PGP-Fingerprint: 5A91 6942 8CEA 9DAB B95B C249 1CE1 493B 2B5A CE30 Date: Thu, 04 Mar 1999 20:02:59 +1000 From: Greg Black To: cjclark@home.com Cc: freebsd-questions@FreeBSD.ORG Subject: Re: FP Math References: <199903031856.NAA05394@cc942873-a.ewndsr1.nj.home.com> In-reply-to: <199903031856.NAA05394@cc942873-a.ewndsr1.nj.home.com> of Wed, 03 Mar 1999 13:56:30 EST Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Well, I've tried to take this off-list, but with no success. Since nobody has actually flamed me yet for responding, I'll risk it one more time. > > There was *no* sarcasm in what I wrote above, just facts -- > > albeit unpalatable facts. > > So, when I rolled my eyes at those who claim that C is a "dangerous" > language, I was wrong. A single typo in a constant expression will > erase my home diretory. I know this whole paragraph was intentionally over the top, but I think it's important to note that you have claimed two things here that I did not say. I did not say that a typo "will" erase your "home" directory -- I said that a compiler is allowed to generate anything it likes in response to undefined input; and my example erased the root directory, not just your home dir :-) Obviously, nobody would even contemplate using a C compiler which was likely to generate such code. However, we all use C compilers which generate unpredictable code when we give them undefined input. If you want consistent results across platforms, you first need to write code that is defined by the C language. This is hardly an imposition. > > 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. > > Ah, good. Now I understand why you had such objections to my silly > test programs. I was under the impression that converting from a > floating point type with higher overflow to one with lower was > defined. I was confused by the fact that the analogous operation is > defined for integer types. I don't know why you refuse to read the references you have available. I suggested the Standard, but you don't want to use it. You said you had K&R but that it didn't cover this stuff. I gave you a reference to K&R that does cover it. Now you make up new stuff that you'd find is wrong if you looked at K&R. Surprise, surprise! The very pragraph before the one I quoted from K&R for floating conversions discusses integer to float conversions and it makes clear (as does the Standard) that conversion of a floating type to an integral type is undefined if the value (after discarding the fractional part) cannot be represented in the integral type. You have a lot of "facts" in your head that are simply not facts in the real world. This is a common problem when people with limited C knowledge start playing with certain parts of the language, in particular floating point operations. The answer is to take time to read carefully from reliable sources and to try to understand the actual language, without letting one's preconceptions get in the way of the facts. > > 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.) > > Do you mean do not use casts in arithmetic operations? There is a phrase "usual arithmetic conversions" which is to be found in the indexes of both K&R and the Standard which describes exactly what happens for these things. In general, casts only mask errors here. If you cast something, you're telling the compiler you know what you're doing and it will believe you. If you leave out the cast, the compiler will tell you when you have it wrong. If you're doing maths, then the compiler will be right. If you're fiddling with bits for some clever purpose that you actually understand, then you may need a cast. For all the stuff you've shown, casts are a mistake. > If you don't > use casts at all, you must get lots of grief from compilers when you > have all of those null pointers from memory allocations being assigned > to typed pointers. I've read this three times and cannot parse it. Can you give me a one line example of what you mean? (I don't use casts when they are not required and I never get any grief from compilers.) If, by chance, you mean that it's necessary to use a cast like the one at the bottom of p.142 of K&R2 then you're wrong because that cast is a mistake, as Dennis Ritchie has confirmed when I challenged him on that. > I have fixed the bug in the test program. No casting goes on in the RL > programs that cause troublesome FPEs. I am still trying to get a > handle on how the FP works and where the problems are. It's been > getting more interesting. I have tossed aside the attempts to create > overflows by casting, since, a pointed out, they are undefined > operations. The program below (finally, I think) has no such issues > yet creates a SIGFPE core dump, [Code snipped to show only the parts of interest.] > int main() > { > double a = 1e200; > double b; > > b = a*a; All bets are off right here. The largest double, according to is a little under 1.8e308 -- but you have set b to 1e400 which is outside its range, and that means that the bit pattern stored at b doesn't have to be a valid floating point number -- of course, in any reasonable implementation, it should be +infinity. [Rest of code snipped.] > Which returns, > > fpgetmask: 15 > a: 1.000000e+200 > isinf: 0 > isnan: 0 > Floating exception (core dumped) That's not what I see. Look at this: $ uname -srm FreeBSD 2.2.8-RELEASE i386 $ ./fptest fpgetmask: 15 a: 1.000000e+200 isinf: 1 isnan: 0 b: Inf This looks like what you're expecting. The question you now have to asnwer is why you have set up your system to behave differently from the default (at least in 2.2.8-R). I don't have the beginning of a clue about that, since I barely know which side of freeBSD is up. > I went back and checked and the previous programs do the same thing, > they have been core dumping in the fprintf(). So I tracked the problem > to vfprintf.c which dies at the line with the arrow (->), I'm not going to discuss the internals of something like printf here. I think it's beyond the possible interest of the list (and probably outside the ability of most people to understand). -- Greg Black To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message