Why floating point value conditions failed in 'if' condition? [duplicate] - c

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
strange output in comparision of float with float literal
Here is the code
#include<stdio.h>
int main()
{
float a=0.3;
if(a==0.3)
printf("Hello World!");
else
printf("Stack Overflow");
return 0;
}
I expected output as "Hello World". But i got "Stack overflow". Why I didnt get "Hello World"?
Is there anything wrong in the if condition?

Comparing floating point numbers
Floating point math is not exact. Simple values like 0.2 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. Different compilers and CPU architectures store temporary results at different precisions, so results will differ depending on the details of your environment. If you do a calculation and then compare the results against some expected value it is highly unlikely that you will get exactly the result you intended.
Try this way:
#include<stdio.h>
int main()
{
float a=0.3;
float acceptedDiff = 0.0000001;
if(fabsf(a-0.3) < acceptedDiff)
printf("Hello World!");
else
printf("Stack Overflow");
return 0;
}

Try that :)
if (a == 0.3f)
or
if (a == (float)0.3)

Floating point values shall not be compared using either the == or != operators.
Most floating point values have no exact binary representation and have a limited precision. See what you can do.

It is because values like 0.3 cannot be precisely represented using binary floating point numbers. Temporary values are stored differently and thus cannot be compared liike this.
The value for a and 0.3 are thus stored differently and you cannot rely on such a direct comparison.

It is because of precision issue..This tutorial might interest you..

Yes as far as i know while the IF statement compare the variables and values it goes into the machine level information and storage of the value.
very first line you declared a = 0.3 as float type and so it will be stored in the binary format in the memory with the extra padding of the bits. and when you compare it with Exact "0.3" it will always fail.

Related

Simple floating point multiplication not giving expected result [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
When given the input 150, I expect the output to be the mathematically correct answer 70685.7750, but I am getting the wrong output 70685.7812.
#include<stdio.h>
int main()
{
float A,n,R;
n=3.14159;
scanf("%f",&R);
A=n*(R*R);
printf("A=%.4f\n",A);
}
float and double numbers are not represented very accurately in the memory. The main reason is that the memory is limited, and most non-integers are not.
The best example is PI. You can specify as many digits as you want, but it will still be an approximation.
The limited precision of representing the numbers is the reason of the following rule:
when working with floats and double numbers, not not check for equality (m == n), but check that the difference between them is smaller than a certain error ((m-n) < e)
Please note, as mentioned in the comments too, that the above rule is not "the mother rule of all rules". There are other rules also.
Careful analysis must be done for each particular situation, in order to have a properly working application.
(Thanks #EricPostpischil for the reminder)
It is common for a variable of type float to be an IEEE-754 32-bit floating point number.
The number 3.14159 cannot be stored exactly in an IEEE-754 32-bit float - the closest value is approximately 3.14159012. 150 * 150 * 3.14159012 is 70685.7777, and the closest value to this that can be represented in a 32-bit float is 70685.78125, which you are then printing with %.4f so you see 70685.7812.
Another way of thinking about this is that your n value only ends up being accurate to the sixth significant figure, so - as you are just calculating a series of multiplications - your result is also only acccurate to the sixth significant figure (ie 70685.8). (In the general case this can be worse - for example subtraction of two close values can lead to a large increase in the relative error).
If you switch to using variables of type double (and change the scanf() to use %lf), then you will likely get the answer you are after. double is typically a 64-bit float, which means that the error in the representation of your n values and the result is small enough not to affect the fourth decimal place.
Have you heard that float and double values aren't always perfectly accurate, have limited precision? Have you heard that type float gives you the equivalent of only about 7 decimal digits' worth of precision? This is what that means. Your expected and actual answers, 70685.7750 and 70685.7812, differ in the seventh digit, just about as expected.
I expect the output to be the mathematically correct answer
I am sorry to disappoint you, but that's your mistake. As a general rule, when you're doing floating-point arithmetic, you will never get the mathematically correct answer, you will always get a limited-precision approximation of the mathematically correct answer.
The canonical SO answers to this sort of question are collected at Is floating point math broken?. You might want to read some of those answers for more enlightenment.

No Output Coming In Simple C Program

I have been asked a very simple question in the book to write the output of the following program -
#include<stdio.h>
int main()
{
float i=1.1;
while(i==1.1)
{
printf("%f\n",i);
i=i-0.1;
}
return 0;
}
Now I already read that I can use floating point numbers as loop counters but are not advisable which I learned. Now when I run this program inside the gcc, I get no output even though the logic is completely correct and according to which the value of I should be printed once. I tried printing the value of i and it gave me a result of 1.100000 . So I do not understand why the value is not being printed?
In most C implementations, using IEEE-754 binary floating-point, what happens in your program is:
The source text 1.1 is converted to a double. Since binary floating-point does not represent this value exactly, the result is the nearest representable value, 1.100000000000000088817841970012523233890533447265625.
The definition float i=1.1; converts the value to float. Since float has less precision than double, the result is 1.10000002384185791015625.
In the comparison i==1.1, the float 1.10000002384185791015625 is converted to double (which does not change its value) and compared to 1.100000000000000088817841970012523233890533447265625. Since they are unequal, the result is false.
The quantity 11/10 cannot be represented exactly in binary floating-point, and it has different approximations as double and as float.
The constant 1.1 in the source code is the double approximation of 11/10. Since i is of type float, it ends up containing the float approximation of 1.1.
Write while (i==1.1f) or declare i as double and your program will work.
Comparing floating point numbers:1
Floating point math is not exact. Simple values like 0.2 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. Different compilers and CPU architectures store temporary results at different precision, so results will differ depending on the details of your environment. If you do a calculation and then compare the results against some expected value it is highly unlikely that you will get exactly the result you intended.
In other words, if you do a calculation and then do this comparison:
if (result == expectedResult)
then it is unlikely that the comparison will be true. If the comparison is true then it is probably unstable – tiny changes in the input values, compiler, or CPU may change the result and make the comparison be false.
In short:
1.1 can't be represented exactly in binary floating pint number. This is like the decimal representation of 10/3 in decimal which is 3.333333333..........
I would suggest you to Read the article What Every Computer Scientist Should Know About Floating-Point Arithmetic.
1. For the experts who are encouraging beginner programmers to use == in floating point comparision
It is because i is not quite exactly 1.1.
If you are going to test a floating point, you should do something along the lines of while(i-1.1 < SOME_DELTA) where delta is the threshold where equality is good enough.
Read: https://softwareengineering.stackexchange.com/questions/101163/what-causes-floating-point-rounding-errors

Float and double output [duplicate]

This question already has answers here:
strange output in comparison of float with float literal
(8 answers)
Closed 9 years ago.
Please explain the output for different cases
#include<stdio.h>
int main()
{
float a=5.9; //a=0.9
if (a==5.9)
printf("Equal");
else if (a<5.9)
printf("Less than");
else
printf("Greater than");
return 0;
}
When a is 5.9 the output is "Greater than", when a is 0.9 the output is "Less than". Why?
In C, the literal “5.9” has type double and is converted by common compilers to 5.9000000000000003552713678800500929355621337890625, because they use binary IEEE-754 floating point, and that number is the value representable as a double that is closest to 5.9. Your code initializes a float with that value. That requires converting a double to a float, and the result is 5.900000095367431640625, because that is the float value that is closest to the double value. Obviously, the latter is greater than the former, which is why your output is “Greater than”.
With .9, the literal “.9” is converted to the double 0.90000000000000002220446049250313080847263336181640625. Then that double is converted to the float 0.89999997615814208984375, which is obviously less than the double.
Your variable is a float but the constant is a double. Since that value can't be stored precisely ti will be stored differently as a float and as a double. If you use the same data types you'll get the desired results
http://codepad.org/1q5mwFGd
http://codepad.org/Q4lOQnG8
Floating point numbers are inherently imprecise. For a quick introduction, you can read up a bit here. http://floating-point-gui.de/errors/comparison/
For some suggestions on effective comparison strategies, see this post. What is the most effective way for float and double comparison?
This is because internally, the floating point numbers are stored in binary form and 5.9 can't be represented exactly as 5.9. Have a look at the following similar question and answer: Why does a C floating-point type modify the actual input of 125.1 to 125.099998 on output?
When comparing floating-point numbers it is best to avoid '=='.
This because some values cannot be correctly stored without some loss of precision.
So it is better to say:
if( fabs(a-5.9) < .0001 ) {
// 'EQUAL' or at least near enough!
}
I know this takes more to compute, but it will behave the way you expect.
Due to decimal binary conversion, 0.9 represented as a summation of powers of 2^-1:
0.9 - (0.5 + 0.25 + 0.125) = 0.025
But 0.025 is not an exact power of 2^-1. So you need to represent both numbers in the comparison with the same precision. Since float and double have different precision they compare not equal.

C : Strange error when using float and double [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
strange output in comparision of float with float literal
Comparison of float and double variables
I have a test with double and float in C, but I cannot explain why.
float x = 3.4F;
if(x==3.4)
printf("true\n");
else printf("false\n");
double y = 3.4;
if (y==3.4)
printf("true\n");
else printf("false\n");
The result will be False and True. Please explain for me please.
3.4 cannot be exactly represented as a double for the same reason that one third cannot be exactly represented as a base-10 decimal number using a finite number of digits -- the representation recurs.
So, the double literal 3.4 is actually the double value closest to 3.4. 3.4F is the float value closest to 3.4, but that's different from the closest double value.
When you compare a float with a double, the float is converted to double, which doesn't change its value.
Hence, 3.4F != 3.4, just as 0.3333 != 0.33333333
x == 3.4 should be x == 3.4F, otherwise the 3.4 is a double (by default). Always compare like with like, not apples and oranges.
Edit:
Whether the result of the comparison between types of different precision is true or false depends on the floating point representation of the compiler.
Floating point numbers, whether single precision (float) or double, are an approximation.
No guarantee that the result will be false and true, but the basic idea is pretty simple: 3.4 has type double. When you assign it to a float, it'll get rounded. When you compare, that rounded number will be promoted back to a double, not necessarily the same double as 3.4.
In the second case, everything's double throughout.
Comparing for equality
Floating point math is not exact. Simple values like 0.2 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. Different compilers and CPU architectures store temporary results at different precisions, so results will differ depending on the details of your environment. If you do a calculation and then compare the results against some expected value it is highly unlikely that you will get exactly the result you intended.
In other words, if you do a calculation and then do this comparison:
if (result == expectedResult)
then it is unlikely that the comparison will be true. If the comparison is true then it is probably unstable – tiny changes in the input values, compiler, or CPU may change the result and make the comparison be false.
As a tip, comparing floating point numbers (float or double) with '==' is in most cases a bad programming practice, as you might never get the statement to be true. The two numbers might differ in their least significant bits.
It is better using something like:
abs(x - y) < EQUALITY_MARGIN
With EQUALITY_MARGIN being an adequately small number.

Floating point comparison `a != 0.7` [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
problems in floating point comparison
#include <stdio.h>
#include <conio.h>
main()
{
float a = 0.7;
if(a < 0.7)
printf("C");
else
printf("C++");
}
In the above code, the output is C. I tried this code in Code::Blocks and Pelles C but got the same answer. I would like know the reason for this in detail!
In binary, 0.7 is:
b0.1011001100110011001100110011001100110011001100110011001100110...
However, 0.7 is a double-precision literal, whose value is 0.7 rounded to the closest representable double-precision value, which is:
b0.10110011001100110011001100110011001100110011001100110
In decimal, that's exactly:
0.6999999999999999555910790149937383830547332763671875
When you write float a = 0.7, that double value is rounded again to single-precision, and a gets the binary value:
b0.101100110011001100110011
which is exactly
0.699999988079071044921875
in decimal.
When you do the comparison (a < 0.7), you are comparing this single-precision value (converted to double, which does not round, because all single-precision values are representable in double precision) to the original double-precision value. Because
0.699999988079071044921875 < 0.6999999999999999555910790149937383830547332763671875
the comparison correctly returns true, and your program prints "C".
Please note that none of this is any different in C++, appearances of the code in question to the contrary. There are certain (numerically unsafe) compiler optimizations that can change the behavior, but those are not unique to C or C++.
It's because 0.7 has type double, so a gets converted to double and comparison is made in this type. As 0.7 is not representable exactly in binary floating-point, you get some rounding error and the comparison becomes true.
You can:
if( a < 0.7f ) {
....
But actually this effect is true for C++ too, so your conditional is not exactly rightful.
Bart gave a very good reference in his comment, but I would also recommend this very simple rule:
Not all numbers can be represented exactly in the computer, so as soon as you use floating point numbers (such as float and double), you should expect that there can be a small, unpredictable error in each stored number. No, it isn't really random or unpredictable, but until you know more about it you can consider it unpredictable. Therefore, a copmparison such as your a<0.7 might turn out to be true, and it might not. Don't write code that depends on it being either.

Resources