![]() |
isnan or isntnan?
I'm having trouble debugging some apparent nan problem.
Checking with isnan() seems okay, but printf() just prints nan anyway. I'm running gcc 4.2.4, under linux (slackware 12.2 with default packages/libs/etc), and for debugging purposes have compiled with -ffast-math. It's the y2 arg that's the apparent culprit in the following code (which log-linearly interpolates and returns the y-value at input x, given known points x1,y1 and x2,y2)... double loglinterp(x, x1, y1, x2, y2) double x,x1,y1,x2,y2; { double weight; int nanerror = (isnan(y1)?1:0); if ( isnan(y2) ) nanerror += 2; if ( nanerror!=0 || y1<=0.0 || y2<=0.0 ) { printf("loglinterp> y-arg<=0.0(isnan=%d): x=%8.5f; " "x1=%8.5f, y1=%8.5f; x2=%8.5f, y2=%8.5f\n", nanerror,x,x1,y1,x2,y2); return (-1.0); } if ( x2 == x1 ) weight = .5; else weight = (x - x1)/(x2 - x1); return exp( (1.0 - weight)*log(y1) + weight*log(y2) ); } And here's some output where it appears to be catching what it apparently thinks is a y2<=0 (I've manually wrapped and indented the long lines)... loglinterp> y-arg<=0.0(isnan=0): x= 0.17131; x1= 0.16615, y1= 0.59367; x2= 0.17910, y2= nan loglinterp> y-arg<=0.0(isnan=0): x= 0.16898; x1= 0.16615, y1= 0.59367; x2= 0.17910, y2= nan loglinterp> y-arg<=0.0(isnan=0): x= 0.16668; x1= 0.16615, y1= 0.59367; x2= 0.17910, y2= nan It seems that isnan(y2) must be false since it prints 0 for the nanerror variable, but then it prints nan for y2 anyway. What could be going on, and how do I proceed to debug it? Thanks, -- John Forkosh ( mailto: j@f.com where j=john and f=forkosh ) |
Re: isnan or isntnan?
On 11/13/2010 11:48 AM, JohnF wrote:
> I'm having trouble debugging some apparent nan problem. > Checking with isnan() seems okay, but printf() just prints > nan anyway. I'm running gcc 4.2.4, under linux (slackware 12.2 > with default packages/libs/etc), and for debugging purposes > have compiled with -ffast-math. [...] > What could be going on, and how do I proceed to debug it? The info for my copy of gcc says that -ffast-math "can result in incorrect output..." The info doesn't describe the kinds of incorrectness that might occur, but perhaps if you dig into the matter you'll find an explanation. Or you could omit -ffast-math and see what happens ... -- Eric Sosman esosman@ieee-dot-org.invalid |
Re: isnan or isntnan?
On Sat, 13 Nov 2010 16:48:42 +0000, JohnF wrote:
> I'm having trouble debugging some apparent nan problem. Checking with > isnan() seems okay, but printf() just prints nan anyway. [snip three lines of code like double loglinterp(x, x1, y1, x2, y2) double x,x1,y1,x2,y2; { compiled with gcc 4.2.4 on slackware 12.2 with -ffast-math switch etc] > if ( isnan(y2) ) nanerror += 2; > if ( nanerror!=0 || y1<=0.0 || y2<=0.0 ) > { printf("loglinterp> y-arg<=0.0(isnan=%d): x=%8.5f; " > "x1=%8.5f, y1=%8.5f; x2=%8.5f, y2=%8.5f\n", > nanerror,x,x1,y1,x2,y2); [snip other code and some output like next:] > loglinterp> y-arg<=0.0(isnan=0): x= 0.16668; x1= 0.16615, > y1= 0.59367; x2= 0.17910, y2= nan > It seems that isnan(y2) must be false since it prints 0 for the nanerror > variable, but then it prints nan for y2 anyway. What could be going on, > and how do I proceed to debug it? Thanks, For more discussion of debugging, perhaps try comp.programming, not c.l.c. (Added c.p to newsgroups and set followups there.) If Eric Sosman's suggestion re -ffast-math doesn't help, try printing y2 also in hex, both before calling loglinterp() and within loglinterp(). Eg, write a function printFX (double y) and in printFX() declare a union u with double and long or long long members u.f and u.l; set u.f to y; and printf ("...%f...%0lx...", u.f, u.l). Use an integer type of the same size as a double. If you want to print characters as well, have a member u.c declared with char c[sizeof(double)], and putchar each u.c[i]. Then, if the hex versions look like characters or like integers, look for a string copy or array copy spilling out of bounds, or assignment to an integer alias of y2, etc. -- jiw |
Re: isnan or isntnan?
Eric Sosman wrote:
> JohnF wrote: >> I'm having trouble debugging some apparent nan problem. >> Checking with isnan() seems okay, but printf() just prints >> nan anyway. I'm running gcc 4.2.4, under linux (slackware 12.2 >> with default packages/libs/etc), and for debugging purposes >> have compiled with -ffast-math. [...] >> What could be going on, and how do I proceed to debug it? > > The info for my copy of gcc says that -ffast-math "can > result in incorrect output..." The info doesn't describe the > kinds of incorrectness that might occur, but perhaps if you > dig into the matter you'll find an explanation. > Or you could omit -ffast-math and see what happens ... Thanks, Eric. Actually, I first compiled it without any special -switches at all, and got some nan's in the output. The -ffast-math helped pin down the culprit by exaggerating the nan problem. Otherwise, it didn't show up in loglinterp() at all. And anyway, I wouldn't want to "solve" the problem by hiding it. I'd think a correct program should run correctly with or without -ffast-math. -- John Forkosh ( mailto: j@f.com where j=john and f=forkosh ) |
Re: isnan or isntnan?
In article <ibmfh9$foe$1@reader1.panix.com>,
JohnF <john@please.see.sig.for.email.com> wrote: >I'm having trouble debugging some apparent nan problem. >Checking with isnan() seems okay, but printf() just prints >nan anyway. I'm running gcc 4.2.4, under linux (slackware 12.2 This is plausibly a compiler bug, so before digging too deep, you should first try to reproduce the result with the newest version of the compiler you can get your hands on. The first rule of compiler bugs is that if you think you found one, you probably didn't. The second rule is if you did find one, it's probably already been found and fixed by someone else. Besides, gcc-4.2 is no longer a maintained branch, which means that even if you did find a previously unknown bug, nobody will care unless a newer version is also affected. -- Alan Curry |
Re: isnan or isntnan?
On 11/14/2010 2:06 PM, JohnF wrote:
> Eric Sosman wrote: >> JohnF wrote: >>> I'm having trouble debugging some apparent nan problem. >>> Checking with isnan() seems okay, but printf() just prints >>> nan anyway. I'm running gcc 4.2.4, under linux (slackware 12.2 >>> with default packages/libs/etc), and for debugging purposes >>> have compiled with -ffast-math. [...] >>> What could be going on, and how do I proceed to debug it? >> >> The info for my copy of gcc says that -ffast-math "can >> result in incorrect output..." The info doesn't describe the >> kinds of incorrectness that might occur, but perhaps if you >> dig into the matter you'll find an explanation. >> Or you could omit -ffast-math and see what happens ... > > Thanks, Eric. Actually, I first compiled it without any > special -switches at all, and got some nan's in the output. > The -ffast-math helped pin down the culprit by exaggerating > the nan problem. Otherwise, it didn't show up in loglinterp() > at all. And anyway, I wouldn't want to "solve" the problem by > hiding it. I'd think a correct program should run correctly > with or without -ffast-math. -ffast-math can easily provoke a NaN from a sequence of operations which would produce finite results without that option. For example, x/y could in effect become (1/y) * x; should 1/y overflow, a zero could be produced "erroneously," then, further arithmetic involving those results could produce NaN. Also, -ffast-math allows parentheses to be treated K&R fashion (ignored, according to usual algebraic rules), in violation of standard C rules. It's certainly possible that making your code more reliable will allow it to work with and without -ffast-math. -- Tim Prince |
Re: isnan or isntnan?
Tim Prince wrote:
> JohnF wrote: >> Eric Sosman wrote: >>> JohnF wrote: >>>> I'm having trouble debugging some apparent nan problem. >>>> Checking with isnan() seems okay, but printf() just prints >>>> nan anyway. I'm running gcc 4.2.4, under linux (slackware 12.2 >>>> with default packages/libs/etc), and for debugging purposes >>>> have compiled with -ffast-math. [...] >>>> What could be going on, and how do I proceed to debug it? >>> >>> The info for my copy of gcc says that -ffast-math "can >>> result in incorrect output..." The info doesn't describe the >>> kinds of incorrectness that might occur, but perhaps if you >>> dig into the matter you'll find an explanation. >>> Or you could omit -ffast-math and see what happens ... >> >> Thanks, Eric. Actually, I first compiled it without any >> special -switches at all, and got some nan's in the output. >> The -ffast-math helped pin down the culprit by exaggerating >> the nan problem. Otherwise, it didn't show up in loglinterp() >> at all. And anyway, I wouldn't want to "solve" the problem by >> hiding it. I'd think a correct program should run correctly >> with or without -ffast-math. > > -ffast-math can easily provoke a NaN from a sequence of operations which > would produce finite results without that option. For example, x/y could > in effect become (1/y) * x; should 1/y overflow, a zero could be > produced "erroneously," then, further arithmetic involving those > results could produce NaN. Thanks, Tim. As mentioned to Eric, I first compiled without any special -switches, and noticed nan's in the output. So that probably reflects some actual code error on my part, rather than some compiler artifact from order of execution, or whatever. The -ffast-math did, in fact, produce a few more nan's than without it, helping me locate a common "bottleneck" at loglinterp() through which all the bad numbers seem to pass. Now I can try to trace back from there to the source (and then hopefully cause) of the bad numbers. And that can probably now be done with or without -ffast-math in the compile. > Also, -ffast-math allows parentheses to be > treated K&R fashion (ignored, according to usual algebraic rules), in > violation of standard C rules. > It's certainly possible that making your code more reliable will allow > it to work with and without -ffast-math. I'll be happy to get it working without. I had no particular interest in the switch until I noticed nan errors in the output and started trying to debug. -- John Forkosh ( mailto: j@f.com where j=john and f=forkosh ) |
Re: isnan or isntnan?
Alan Curry <pacman@kosh.dhis.org> wrote:
> JohnF <john@please.see.sig.for.email.com> wrote: >>I'm having trouble debugging some apparent nan problem. >>Checking with isnan() seems okay, but printf() just prints >>nan anyway. I'm running gcc 4.2.4, under linux (slackware 12.2 > > This is plausibly a compiler bug, so before digging too deep, you should > first try to reproduce the result with the newest version of the compiler you > can get your hands on. > > The first rule of compiler bugs is that if you think you found one, you > probably didn't. The second rule is if you did find one, it's probably > already been found and fixed by someone else. > > Besides, gcc-4.2 is no longer a maintained branch, which means that even if > you did find a previously unknown bug, nobody will care unless a newer > version is also affected. Thanks, Alan, but I'm not all that concerned about following up on a (rather benign in this case) putative compiler bug. It's not affecting (as far as I know) my program, just my debugging process. So the compiler bug, if that's what it is, won't affect me at all after the program is debugged. And James, from the other post, suggested a workaround -- sprintf the number and check the string for "nan". If printf is printing nan, then that ought to work regardless of isnan()'s inconsistent return value. And that'll solve my immediate problem, compiler bug or not. (Now all I have to do is actually debug the silly program.) -- John Forkosh ( mailto: j@f.com where j=john and f=forkosh ) |
Re: isnan or isntnan?
On Sat, 13 Nov 2010 16:48:42 +0000, JohnF wrote:
> It seems that isnan(y2) must be false since it prints 0 for the nanerror > variable, but then it prints nan for y2 anyway. What could be going on, > and how do I proceed to debug it? Thanks, Since I didn't see it posted elsewhere in this thread, it should be noted that GCC's -ffast-math option implies -ffinite-math-only, which tells the compiler that it may assume all floating point values are finite. This means that GCC can and will replace all calls to isnan or isinf with a constant 0. |
Re: isnan or isntnan?
Le 16/11/10 20:04, Nick Bowler a écrit :
> On Sat, 13 Nov 2010 16:48:42 +0000, JohnF wrote: >> It seems that isnan(y2) must be false since it prints 0 for the nanerror >> variable, but then it prints nan for y2 anyway. What could be going on, >> and how do I proceed to debug it? Thanks, > > Since I didn't see it posted elsewhere in this thread, it should be > noted that GCC's -ffast-math option implies -ffinite-math-only, which > tells the compiler that it may assume all floating point values are > finite. This means that GCC can and will replace all calls to isnan or > isinf with a constant 0. > !!!!!!!!!!!!!!!!!!!!!!!! This is one of the worst bugs of gcc I have ever seen. Buggy by design! How can the compiler possibly replace all isnan() by zero? And by an IMPLICIT RULE. Nowhere in the documentation is mentioned that calls to isnan() will be ignored. It just says: -ffinite-math-only Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or +-Infs. This option should never be turned on by any -O option since it can result in incorrect output for programs which depend on an exact implementation of IEEE or ISO rules/specifications. The default is -fno-finite-math-only. Reading this, I understand that the compiler "assumes that arguments and results are not NANs. Nowhere is said that a function call to isnan() will be IGNORED. Well... THERE IS NO WARRANTY FOR THE PROGRAM, THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
| All times are GMT. The time now is 04:34 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.