Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   isnan or isntnan? (http://www.velocityreviews.com/forums/t737937-isnan-or-isntnan.html)

JohnF 11-13-2010 04:48 PM

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 )

Eric Sosman 11-13-2010 09:48 PM

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

James Waldby 11-14-2010 01:20 AM

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

JohnF 11-14-2010 10:06 PM

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 )

Alan Curry 11-14-2010 10:51 PM

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

Tim Prince 11-15-2010 01:45 AM

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

JohnF 11-15-2010 02:39 AM

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 )

JohnF 11-15-2010 02:48 AM

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 )

Nick Bowler 11-16-2010 07:04 PM

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.


jacob navia 11-16-2010 07:45 PM

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 09:28 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.