views:

83

answers:

4

Possible Duplicates:
Difference between float and double
strange output in comparision of float with float literal

I am using visual C++ 6.0 and in a program I am comparing float and double variables For example for this program

#include<stdio.h>
int main()  
{    
    float a = 0.7f;
    double b = 0.7; 
    printf("%d %d %d",a<b,a>b,a==b);
    return 0;
 }  

I am getting 1 0 0 as output

and for

#include<stdio.h>
int main()  
{    
    float a = 1.7f;
    double b = 1.7; 
    printf("%d %d %d",a<b,a>b,a==b);
    return 0;
 }  

I am getting 0 1 0 as output.

Please tell me why I am getting these weird output and is there any way to predict these outputs on the same processor. Also how comparison is done of two variables in C ?

+1  A: 

1.7d and 1.7f are very likely to be different values: one is the closest you can get to the absolute value 1.7 in a double representation, and one is the closest you can get to the absolute value 1.7 in a float representation.

To put it into simpler-to-understand terms, imagine that you had two types, shortDecimal and longDecimal. shortDecimal is a decimal value with 3 significant digits. longDecimal is a decimal value with 5 significant digits. Now imagine you had some way of representing pi in a program, and assigning the value to shortDecimal and longDecimal variables. The short value would be 3.14, and the long value would be 3.1416. The two values aren't the same, even though they're both the closest representable value to pi in their respective types.

Jon Skeet
He *is* passing integers.
Hans Passant
@Hans: The question changed after posting. It was *originally* printing `a` and `b` (nearly; actually `ab` which I assumed was a typo for `a,b`; it turns out it was just unformatted code, which made everything unclear). Will edit.
Jon Skeet
@Shynthriir: Look at the question pre-edit...
Jon Skeet
@Jon Skeet: Apologies, I knew there had to be a reason.
Shynthriir
A: 

You can't compare floating point variables for equality. The reason is that decimal fractions are represented as binary ones, that means loss of precision.

Andrey
A: 

1.7 is decimal. In binary, it has non-finite representation.

Therefore, 1.7 and 1.7f differ.

Heuristic proof: when you shift bits to the left (ie multiply by 2) it will in the end be an integer if ever the binary representation is “finite”.

But in decimal, multiply 1.7 by 2, and again: you will only obtain non-integers (decimal part will cycle between .4, .8, .6 and .2). Therefore 1.7 is not a sum of powers of 2.

Benoit
+2  A: 

It has to do with the way the internal representation of floats and doubles are in the computer. Computers store numbers in binary which is base 2. Base 10 numbers when stored in binary may have repeating digits and the "exact" value stored in the computer is not the same.

When you compare floats, it's common to use an epsilon to denote a small change in values. For example:

float epsilon = 0.000000001;
float a = 0.7;
double b = 0.7;

if (abs(a - b) < epsilon)
  // they are close enough to be equal.
Starkey
Wrong. You should use fabs instead.