Click here to Skip to main content
14,172,909 members
Rate this:
 
Please Sign up or sign in to vote.
See more:
#include<stdio.h>
int main(){
    float x = 0.1;
    if (x == 0.1)
        printf("IF");
    else if (x == 0.1f)
        printf("ELSE IF");
    else
        printf("ELSE");
    return 0;
}

#include<stdio.h>
int main{
    float x = 0.5;
    if (x == 0.5)
        printf("IF");
    else if (x == 0.5f)
        printf("ELSE IF")
    else
        printf("ELSE");
    return 0;
}

First program Output: ELSE IF
Second program Output: IF

Both programs are similar.But outputs are different.Why?
Posted
Updated 3-Oct-15 2:13am
v2
Comments
0x01AA 3-Oct-15 8:27am
   
To understand this you have to dive deep into representation into representation of real numbers in a CPU.

1.) Comparing real numbers with "==" is problematic, you can find a lot of discussion about this in WWW
2.) In your case I think it is the mix between "double" (your right Hand side) and the "float" (left Hand side) for the Operator "==". To compare them an conversion is needed.
CPallini 3-Oct-15 8:45am
   
My (virtual) 5.
0x01AA 3-Oct-15 8:47am
   
Thank you, I Need it this Moment. It Looks like I'm Spammer #1 this Moment :)
CPallini 3-Oct-15 9:17am
   
Wow, luxury content for spamming :-)
0x01AA 3-Oct-15 10:33am
   
"Noblesse oblige" *lol*. It is solved now, I only wrote at the wrong place at a wrong time :-)
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

This is due to the internal representation of floating point numbers and rounding (see Wikipedia[^]).

Your if conditions compares the single precision (float) value with a double precision constant value. So the compiler converts the single precision value to double precision. The else if condition compares with a single precision constant (which should always be true).

The second value 0.5 can be represented exactly by floating point values. But this is not true for 0.1. When converting from single precision to double, the additional available bits will be cleared. But the double constant value 0.1 has some of these bits set. So the values are not binary identical.

You may use the converter at this page[^] to see the binary representation of single precision numbers and the corresponding double precision decimal.
   
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

In the expression x == 0.1 the 0.1 will be created as a double rather than a float, and will have more bits set. And since the value of 0.1 in floating point cannot be represented exactly the two values will differ slightly. See http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html[^] for a proper explanation.
   
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 3

Because floating point numbers don't always work well when you look at them as binary values.
0.5 is easy to convert to binary, 1/2 always will be given that binary is base 2!
But 0.1 is 1/10 which doesn't "map" nicely to base 2.

When you write 0.1f you are defining it as a single precision float, rather than the double precision you get for 0.1
So when you write
float x = 0.1;

What you actually get is
double d = 0.1;
float x = (float)d;
which isn't actually the same number (even though it looks like it!)
   
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 4

Read this: "What Every Computer Scientist Should Know About Floating-Point Arithmetic"[^].

Consider
float x = 0.5;
    if (x == 0.5)


In the first one a double literal (0.5) is casted to float before being assigned to the variable x.
In the second one the x variable is promoted to double before being compared to the double literal 0.5.
The first step might comport loss of precision making the successive comparison fail.
Might is fundamental in your example, because loss of precision happens with 0.1 but doesn't happen with (the syntaxical correct version of the program using) 0.5.

Floating point numbers are tricky in computing. Mixing float and double values is C even more tricky. If you don't have any particular reason for doing that, simply don't do that (usually choosing the double datatype is the best choice).
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Cookies | Terms of Service
Web05 | 2.8.190524.3 | Last Updated 3 Oct 2015
Copyright © CodeProject, 1999-2019
All Rights Reserved.
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100