ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I should have mentioned I was trying this on a cygwin env. Never saw this before when I worked on any of the *nix env's myself.
Strange, but there must be a reason ...
A display of "0.000000" does not mean the item is zero. It means that to 7 places the value is zero.
Although this may not be the cause of the situation here, floating point comparisons should almost never be for equality because of round-off that occurs in calculation with the approximations we use.
Perhaps printing the values in hex or octal would be useful.
Also we don't know (I don't know) what instructions are generated for the comparison in the if ... cheers, makyo
Although in general your argument is correct...
... but an IEEE 754 "0.0" is binary identical to "0.000000000000000": http://en.wikipedia.org/wiki/IEEE_754
Quote:
Quote:
Although this may not be the cause of the situation here, floating point comparisons should almost never be for equality because of round-off that occurs in calculation with the approximations
<= I agree completely
Quote:
Quote:
Perhaps printing the values in hex or octal would be useful.
<= An excellent suggestion. I'm curious myself!
H/W -
Could you please:
1. Tell us your Cygin/GCC version ("gcc -v" should tell you)
2. Tell us what kind of PC you're running on (who knows - maybe you're using some kind of FPU that doesn't use IEEE floating point!)
3. Dump the data values in hex (if convenient: gdb is one way)
4. Post back the results (we're curious!)
Although in general your argument is correct...
... but an IEEE 754 "0.0" is binary identical to "0.000000000000000": http://en.wikipedia.org/wiki/IEEE_754
That was not the thrust of my comment, I should have been more precise. I was writing about the result of the printf statement.
Most of the tests that people performed were with calls that specified constants. The OP did not share how the argument values were obtained when the call was made ... cheers, makyo
Although this may not be the cause of the situation here, floating point comparisons should almost never be for equality because of round-off that occurs in calculation with the approximations we use.
exactly, observe:
Code:
#include <stdio.h>
#include <math.h>
int main(void)
{
float y;
float x;
for(;;) {
printf("\nEnter a number:");
scanf("%f", &x);
y = sqrtf(x);
printf("x=%f, y=%.33f\n", x, y);
y *= y;
printf("x=%f, y=%.33f\n", x, y);
}
}
Code:
Enter a number:99
x=99.000000, y=9.949873924255371093750000000000000
x=99.000000, y=98.999992370605468750000000000000000
Thanks for the replies, all.
I'm aware of not doing FP compares, but had assumed that zero would not have this same behaviour. I still am not convinced entirely as we don't see this on other systems, but hey ...
paulsm4: it's gcc 3.4.4 on a 64-bit Windows XP. Would using a %o format specifier do to get the octal? Wouldn't it be incorrect against "double's"?
a) checking for equality with floating point numbers (which are, by definition, imprecise) is dangerous...
... but ..
b) you *should* be able to compare a double variable with the value "0.0" with a floating point literal "0.0" and reliably get "equals".
For whatever it's worth, I tried your program on a *third* different PC: a 64-bit AMD running Suse 10.x/Gnu 4.x... and it worked OK. No problems with "0.0".
I guess I'd be suspicious of your copy of Cygwin. If you wanted to pursue it further, the next step would be to compile with "gcc -S" and look at the assembler output of the comparision.
Hi Paul,
It's not worth the effort to look into what makes it different on cygwin. It was just a short program I was writing, and it just so happens it was on an env I don't use otherwise (cygwin.)
Anyway, the topic and all your replies just iterated some good points to remember.
Thanks all.
The C standard defines macros like isgreaterequal, isgreater, and so on for comparing fp datatypes. Therefore,
Code:
if ( ! islessgreater(a,b))
is one sure way to do a == boolean compare for floating point values. The advantage of the macros aside from portability, is that it will not raise exceptions on non-normal fp numbers.
The C standard defines macros like isgreaterequal, isgreater, and so on for comparing fp datatypes. Therefore,
Code:
if ( ! islessgreater(a,b))
is one sure way to do a == boolean compare for floating point values. The advantage of the macros aside from portability, is that it will not raise exceptions on non-normal fp numbers.
See math.h for all of them.
Interesting, jim. Wasn't aware of those macros.
Thanks.
"islessgreater()" and friends are ISO C99 macros. Newer versions of GCC/Linux are pretty good about supporting them, but you're not going to find them elsewhere (for example, it's *not* in my copy of MSVC ... but I haven't seen the new "Orcas"/VS2008 yet ;-))
Even then, you probably have to add special flags to get it to compile/link, e.g.:
Quote:
gcc -std=c99 -o simple simple.c -lm
Again, the basic issue is that what H/W was trying *should* work. I would definitely characterize the problem as a compiler issue, *not* a programming error.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.