• C

# Floating and double values

my code is

float c=0.7;
if(c<0.7)
printf("value is less\n");
else
printf("value is more\n");
O/p is value is less

but when I declare it as
double c=0.7;
output is value is more

Can anyone tell me the reason why is the output so?
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
Hi Renisha,

A comment from previously asked question:::
floating point represenation is not exact

if you say x=0.7 ... system may actually be storing it as .6999999999999999999999999999999 or something else

floating point storage is at best approximate and not exact

Comment from sunnycoder
Date: 08/12/2003 05:47PM IST

exactly same questions - click the links below for viewing previous discussions on the topic

http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_20690437.html

http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_20548837.html

Date: 08/12/2003 06:39PM IST

You cannot compare floating point values like that. Floating point has an inexact representation in computers and so the correct test for equality is:

if (fabs(x - y) < EPSILON) {
/* x is close to y */
} else {
/* x is not close to y */
}

This introduces a tolerance value EPSILON which indicates how accurate you want the result to be. If you set EPSILON to 0.5 then it means that a value such as 0.7 compares "equal" to a value such as 1.1 since their difference is smaller than 0.5.

The exact tolerance to set partly depends on how many computations you do and partly on how much precision you use.

If you know you will work with two decimals it is often easier to work with scaled values. A scaled value is simply an integer which is the value multiplied by some factor so as to make it an integer. If you work with 2 decimals the factor is 100. In a sense you work in cents instead of dollars or you count centimeters instead of meters. This way you can keep the values as integers and avoid floating point.

Working with scaled values is often very useful. Currency is one such situation where a scaled integer is usually better than a floating point value. To be exact on currency exchange etc you might want work with a scale so that a value of 1 is stored as 10000. This gives 4 decimals accuracy.

Here is how you compute using such a scaled values. I use the type money_t to hold a scaled value while regular int are unscaled values:

The basic rules are these:

If you want to convert from an integer to a scaled value multiply by SCALE.
If you want to convert from a scaled value to an integer divide by SCALE.
If you want to convert from a scaled value to float convert the integer part of the scaled value to float and divide by SCALE.

If you want to add two scaled values just add them. The result is a scaled value.

If you want to add a scaled value with an int or with a value scaled with a different scale, change that other value to have the same scale by multiplying or dividing by a factor which changes the scale to same scale. If it is an int you simply change that int to the proper scaled value by multiplying by SCALE and then adding.

if you want to multiply a scaled value with an integer you just multiply. The result is a scaled value.
If you want to multiply two scaled values with each other, just multiply the values. The result has a scale equal to the multiplication of each scale. If you want to change that back to original scale you must divide the resulting product with a proper factor.

If you want to divide a scaled value with an integer you just divide. The result is a scaled value. The remainder should be handled properly depending on how you want to round the result.

If you want to divide two scaled values with each other you also divide the scales if they are the same the result is an unscaled value, otherwise the value is scaled with a suitable factor.

For example: You have 100.3547 dollars and you want to multiply that by 5, what do you get?

answer: Multiply 1003547 by 5 and you get the scaled result. The scale is untouched and is still 10000.

If you add 3 dollars to the amount 100.3547, what do you do?

multiply the 3 by the scale and add: 30000 + 1003547 = 1033547. With a scale of 10000 this is 103.3547 which is the correct result.

Using such scaled numbers instead of floating point your comparison is exact and is exactly what you expect:

If we have a scale of 0.1 then 0.7 is stored as the integer 7 and when we later compare we get exactly correct result.

also try this
#include<stdio.h>
int main()
{
float a= (float) 0.7;
if(a < (float) 0.7)
printf("a is less than 0.7");
else
printf(" a is equal to 0.7");
return 0;
}

http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_20690437.html
http://beta.experts-exchange.com/Programming/Programming_Languages/C/Q_20707050.html
http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_20548837.html

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Commented:
Hi Renisha,

You are not maintaining your questions ...

Questions Open: 5
Questions Deleted: 2

and the PAQed question is in CS ! take some time to close your question .. if you find some answer helpful, accept the answer and award points to the expert who helped you with your problem ... otherwise post in community support and get the questions deleted. For more help refer to
http://www.experts-exchange.com/help/closing.jsp
Commented:

if(c<0.7)

You are comparing a single-precision float with a double. c is now equal to 0.7F, but the float constant which you are comparing it with is 0.7, which is synonymous with 0.7L. c gets promoted to a double for the comparison, and is not exactly 0.7D.

--------8<--------
#include <stdio.h>

int main()
{
double d = 0.7L; /* Could write this simply as 0.7 - I used the L suffix to make a point */
float f;

printf("The value of d is %0.10lf\n",d);
f = d;
printf("The value of f is %0.10f\n",f);
d = f;
printf("The value of d is %0.10lf\n",d);
}
--------8<--------

Try comparing with with the single precision constant instead:

if(c<0.7F)
Commented:
> and is not exactly 0.7D