Today is...
Saturday, July 20, 2019
Welcome to Control.com, the global online
community of automation professionals.
Featured Video...
Featured Video
A tutorial introduction to programming using the QuickBuilder Programming Environment.
Our Advertisers
Help keep our servers running...
Patronize our advertisers!
Visit our Post Archive
Problem with C - A Simple Code
Caught between double and float variables...!!
By Rahul P Sharma on 11 July, 2006 - 8:59 pm

Please help with the following code

void main(void)
(
float a = 1.1;
double b = 1.1;
if(i == d)
printf("\nHi\n");
else
printf("\nBye\n");
)

The above program outputs "Bye"... Why so??
I've printed both the values in all possible formats... and they are always 1.10000 in each case.... why then the result??

au revoir
Rahul

By Rokicki, Andrew \(Andrew\) on 12 July, 2006 - 5:32 pm

The way float and doubles are stored in memory is different a and b are approximations. So your if statement will evaluate to false.

Try this as an exercise:

void main(void)
{
float a = 1.1;
double b = 1.1;
while (a<1000.0)
{
a=a*a;
b=b*b;
}
printf(" a value %f\n",a);
printf(" a value %f\n",a);
)

At least on my machine I got (Linux gcc v4.0.0):
a value 198730.765625
b value 198730.122503

Hope this helps.
Andrew R.
Somewhere at 41.50, -72.90

By Robert Scott on 14 July, 2006 - 10:10 am

I agree with Curt. But Michael and Herman are wrong about the example having syntax errors or not compiling. Automatic promotion to (double) in the comparison is completely valid. You are welcome to mix data types as long as you realize that things this this will happen. If, instead of 1.1, you used 2.0, then the comparison (a==b) would have been true. And Herman

Robert Scott
Real-Time Specialties
Embedded Systems Consulting

By Michael Griffin on 17 July, 2006 - 1:42 pm

In reply to Robert Scott - You said I was "wrong about the example having syntax errors or not compiling". Did you try compiling it yourself? The sample provided was:


void main(void)
(
float a = 1.1;
double b = 1.1;
if(i == d)
printf("\nHi\n");
else
printf("\nBye\n");
)

Even if we add in "#include <stdio.h>" at the beginning, we still get:

$ cc simple-c.c
simple-c.c:4: error: syntax error before '=' token
simple-c.c:7: error: conflicting types for 'printf'
simple-c.c:7: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
simple-c.c:7: warning: data definition has no type or storage class

It doesn't look like it compiled. It also looks like it had syntax errors.
Lots of them.

Secondly, I didn't say you *can't* mix data types, I said you *shouldn't* mix
data types in this manner. Not everything than *can* be done, *should* be
done. As to why you *shouldn't* mix data types, it is because then you end up
writing messages to the Automation List asking why you can't figure out why
your program won't work.

Counting on automatic promotion of variables in 'C' is a good way of
introducing bugs and creating a software maintenance headache. You may end up
doing conversions you haven't given proper consideration to. If you need to
convert types, then you should do explicit type casts. This tells someone who
is reading the program that a type conversion is taking place, and that you
intended it to take place. Even type casting won't magically fix problems
like this one, but it does make the program more readable and the fact that a
type conversion is taking place more obvious.

If someone is submitting their homework questions to the A-List and mistakes
"shouldn't" for "can't" and gets marked down on it, I don't feel too sorry
for them.

Thirdly, you would have seen in the third part of my reply where I explained
what happens to numbers like "1.1" in floating point representation. I showed
what the actual values of "a" and "b" were when printed out to enough
precision. This should have been your clue that I actually compiled and ran
the program (after first fixing it) before commenting on it.

Whatever else it was you had intended to say to Mr. Herman Hoffeldt does not
appear to have made it through the aether. If you intended to tell him it was
not caused by the different type sizes, you were correct. The code sample
showed bad programming practice in the comparison, but this was not the root
of the problem.

By Michael Griffin on 13 July, 2006 - 1:38 pm

In reply to Rahul P Sharma - Your problems are:

1) Your example won't even compile because it has syntax errors.

2) "a" and "b" are different data types. You shouldn't mix data types in a statement in this manner.

3) "a" and "b" are not the same value. Decimal values will not necessarily convert exactly to binary floating point. Just as "pi" is only approximately "3.1417", "1.1" will not convert exactly to binary. If you print out "a" and "b" with enough precision you will find that "a = 1.10000002384185791016" and "b = 1.10000000000000008882". Note that these are not the same value.

By Curt Wuollet on 13 July, 2006 - 2:49 pm

Why? Because they are not equal!

The lesser type is promoted to the greater type before the comparison is made and there was a tiny rounding error or some such in the process. Floats are not exact, but are held to a given degree of precision. This will often occur even if you promote an integer. Greater than and less than are far better when dealing with floats. Even worse, the equality can work occasionally depending on history. These bugs can be extremely hard to find. One way around this is to convert to integer by multiplying say 13.011 by 1,000, the integer 13011 is exact and will compare with an integer derived the same way without error.

Regards

cww

By Friedrich Haase on 13 July, 2006 - 5:50 pm

Moin Rahul,
moin all,

Remember, you cannot write all real numbers with unlimited precision, e.g. 1/3 != 0.333. Pretty much the same holds for the binary real values in in floats and doubles. Your float a value is very near to 1.1 but not exactly. Your double b value is even more closer to 1.0 but neither exactly 1.1. So both a and b are never the same.

To have a look at the binary representations of floating point values and check the differences you could use my floating point to/from hex/binary
conversion utility at http://www.61131.com

Regards
Friedrich Haase

Ing.-Büro Dr. Friedrich Haase
Consulting - Automatisierungstechnik
email Friedrich@61131.com
WEB http://www.61131.com

By Hoffeldt, Herman \(JH\) on 13 July, 2006 - 7:41 pm

It should not even compile at all. You are probably running an old executable for this code. Some of the variables is not declared. I suppose your code looks like this:


void main(void)
{
float a = 1.1;
double b = 1.1;
if(a == b)
printf("\nHi\n");
else
printf("\nBye\n");
}

You can correct the code by casting as follows:


void main(void)
{
float a = 1.1;
double b = 1.1;
if(a == (float)b )
printf("\nHi\n");
else
printf("\nBye\n");
}

Cheers<br>
Herman

The float values or double values in C/C++ are stored something different from u assign.
As in case of ur program,when u have given a=1.1 then actually the value of a is not exactly 1.1 it is something different say 1.100000123 (e.g).
the value of b is also stored something different from 1.1. This is the reason when u r comparing these values these are not equal.

By Mark Bayern on 1 August, 2006 - 8:30 am

An old comp-sci adage, attributed to Kernigan and Plauger:

"Floating point numbers are like piles of sand; every time you move
one you lose a little sand and pick up a little dirt."

Mark

By prakash shrivastava on 18 August, 2006 - 1:15 pm

In c language the comparison between two no. is done by binary form. Who is convert by compiler and store this value in given byte area. in float compiler give 4 byte = 32 bit and the double 8 byte = 64 byte.

after conversion compiler compare both. the value of 32 byte is equal after 32 bit we get some other value. For this reson the 1.1 in float and 1.1 in double is not equal.

if u use


void main(void)
(
float a = 1.5
double b = 1.5
if(i == d)
printf("\nHi\n");
else
printf("\nBye\n");
)
always print Hi
but any value can not be equal.