Solved

Floating and double values

Posted on 2003-11-20
6
354 Views
Last Modified: 2010-04-15
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?
0
Comment
Question by:renisha
  • 2
  • 2
6 Comments
 
LVL 45

Accepted Solution

by:
sunnycoder earned 250 total points
ID: 9786667
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
 Your Comment  

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

 
Accepted Answer from Salte
Date: 08/12/2003 06:39PM IST
 Accepted Answer  

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
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 9786697
Hi Renisha,

You are not maintaining your questions ...

Questions Asked: 8
Questions Open: 5
Questions Graded: 1
Questions Deleted: 2
Last 10 Grades Given: A

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
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9786758
The problem is your comparison

    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)
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9786772
> and is not exactly 0.7D

Oops Java. Read:

and is not exactly 0.7L
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now