This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 6 years ago.
I'm getting an unexpected behaviour when comparing a float value, I understand that floats could have rounding precission issues but here numbers are quite specific to present those issues.
#include <stdio.h>
int main()
{
float alpha = 0.0f;
int finish = 0;
while (finish == 0)
{
alpha += 0.05f;
if (alpha > 1.0f)
{
printf("%f", alpha); // Expected result: 1.05f, actual result: 1.0f
finish = 1;
}
}
return 0;
}
Actually, condition enters when alpha = 1.0f. Can't understand that behaviour...
I'm compiling with MinGW (GCC 5.3.0) on Windows 10 (tested on 32bit and 64bit), Intel i5 processors.
(Restricting the answer if I may to IEEE754 floating point).
There is no such float as 0.05. The nearest number representable to that is
0.0500000007450580596923828125
So what is happening, is that slightly larger values than what you think are added to alpha, which is enough to just push it over the 1.0f mark (which, out of interest, can be represented exactly.)
The default formatting in print is rounding that slightly greater than 1.0f number back to 1.0f.
In summary, all this is due to binary floating point not having, in general, an exact decimal representation.
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 6 years ago.
I have used this code to generate root, if output is not integer it should return -1.
#include <stdio.h>
#include <math.h>
int main(){
long int n=0;
long int num,p,reti;
double ret;
scanf("%ld",&n);
while(n!=0){
scanf("%ld %ld",&p,&num);
ret=pow(num,(double)1/p);
reti=(int)ret;
printf("%lf %lf\n",ret,(double)reti);
if(ret!=(double)reti){
reti=-1;
}
printf("%ld\n",reti);
n=n-1;
}
return 0;
}
but if I give input as
1
5 3125
it should give 5, but it is giving -1.
ret is not exactly 5.00000, you're just not printing enough digits after the decimal point to see the difference. Change your format to %.20lf and it will show 5.00000000000000088818, which is not equal to (double)5.
This is because pow() works with floating point numbers, and there are some inaccuracies introduced. (double)1/5 can't be represented exactly in binary floating point. See Is floating point math broken?
The reason why is this block of code:
if(ret!=(double)reti){
reti=-1;
}
reti is some integer value - converting it to double will convert it to a double representation, but odds are good that it will not be exactly equal to ret. This is a common issue with floating point numbers - generally speaking, you should never compare pure equality. Instead, you should compare the difference between the two numbers and confirm that it's within some acceptable error range (e.g. 0.00001).
This question already has answers here:
Why are floating point numbers inaccurate?
(5 answers)
Closed 6 years ago.
i started learning c. Today, while i am working on a program, i found an interesting thing and i made another small program (similar to my issue) to check it.
#include<stdio.h>
int main(void)
{
float num1=867.0;
float num2=.6921;
printf("sum = %.4f \n",num1+num2);
return 0;
}
if i run the above program, i am getting 867.6921 as the answer. but if i changed the .4%f to %f the answer is changing to sum = 867.692078. why's the change in the output? Also, is there any way that i can get the answer without using the .4%f?
but if i changed the .4%f to %f the answer is changing to sum = 867.692078
printf rounds the result to that many digits after the floating point you specified, the default is .6. While rounding, it uses the current floating point rounding mode, the default is round to the nearest.
The float type has about seven digits of precision (can be anywhere from 6-9 digits). One alternative is to use g instead of f. This fixes the number of precise digits in the number, not just those after the decimal.
printf("sum = %.7g \n",num1+num2);
This produces output
sum = 867.6921
and will always give seven digits of precision for any input. Number formats would be like :
0.000000E+07
0000000
000000.0
00000.00
0000.000
000.0000
...etc
This question already has answers here:
Floating point inaccuracy examples
(7 answers)
Closed 8 years ago.
int main()
{
float a = 0.7;
float b = 0.5;
if (a < 0.7)
{
if (b < 0.5) printf("2 are right");
else printf("1 is right");
}
else printf("0 are right");
}
I would have expected the output of this code to be 0 are right.
But to my dismay the output is 1 is right why?
int main()
{
float a = 0.7, b = 0.5; // These are FLOATS
if(a < .7) // This is a DOUBLE
{
if(b < .5) // This is a DOUBLE
printf("2 are right");
else
printf("1 is right");
}
else
printf("0 are right");
}
Floats get promoted to doubles during comparison, and since floats are less precise than doubles, 0.7 as float is not the same as 0.7 as double. In this case, 0.7 as float becomes inferior to 0.7 as double when it gets promoted. And as Christian said, 0.5 being a power of 2 is always represented exactly, so the test works as expected: 0.5 < 0.5 is false.
So either:
Change float to double, or:
Change .7 and .5 to .7f and .5f,
and you will get the expected behavior.
The issue is that the constants you are comparing to are double not float. Also, changing your constants to something that is representable easily such as a factor of 5 will make it say 0 is right. For example,
main()
{
float a=0.25,b=0.5;
if(a<.25)
{
if(b<.5)
printf("2 are right");
else
printf("1 is right");
}
else
printf("0 are right");
}
Output:
0 are right
This SO question on Most Effective Way for float and double comparison covers this topic.
Also, this article at cygnus on floating point number comparison gives us some tips:
The IEEE float and double formats were designed so that the numbers
are “lexicographically ordered”, which – in the words of IEEE
architect William Kahan means “if two floating-point numbers in the
same format are ordered ( say x < y ), then they are ordered the same
way when their bits are reinterpreted as Sign-Magnitude integers.”
This means that if we take two floats in memory, interpret their bit
pattern as integers, and compare them, we can tell which is larger,
without doing a floating point comparison. In the C/C++ language this
comparison looks like this:
if (*(int*)&f1 < *(int*)&f2)
This charming syntax means take the address of f1, treat it as an
integer pointer, and dereference it. All those pointer operations look
expensive, but they basically all cancel out and just mean ‘treat f1
as an integer’. Since we apply the same syntax to f2 the whole line
means ‘compare f1 and f2, using their in-memory representations
interpreted as integers instead of floats’.
It's due to rounding issues while converting from float to double
Generally comparing equality with floats is a dangerous business (which is effectively what you're doing as you're comparing right on the boundary of > ), remember that in decimal certain fractions (like 1/3) cannot be expressed exactly, the same can be said of binary,
0.5= 0.1, will be the same in float or double.
0.7=0.10110011001100 etc forever, 0.7 cannot be exactly represented in binary, you get rounding errors and may be (very very slightly) different between float and double
Note that going between floats and doubles you cut off a different number of decimal places, hence your inconsistant results.
Also, btw, you have an error in your logic of 0 are right. You don't check b when you output 0 are right. But the whole thing is a little mysterious in what you are really trying to accomplish. Floating point comparisons between floats and doubles will have variations, minute, so you should compare with a delta 'acceptable' variation for your situation. I've always done this via inline functions that just perform the work (did it once with a macro, but thats too messy). Anyhow, yah, rounding issues abound with this type of example. Read the floating point stuff, and know that .7 is different than .7f and assigning .7 to a float will cast a double into a float, thus changing the exact nature of the value. But, the programming assumption about b being wrong since you checked a blared out to me, and I had to note that :)
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.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Floating point comparison
When I run the code below I get the following output:
Output : if
Why does this happen?
#include <stdio.h>
void main()
{
float a = 0.7;
if(a<0.7)
{
printf("if");
}
else
{
printf("Else");
}
}
Your program compares the double representation of 0.7 (which is what the compiler produces when you write 0.7 in your program) with a float representation of 0.7 (which is what variable a contains). The two are not the same, and it just happens that the double one is slightly larger.
EDIT: (float)0.7 can be represented compactly in hexadecimal notation. It is 0x1.666666p-1. 0.7 as a double constant is 0x1.6666666666666p-1, so it is slightly larger.
Floating points are not stored in precise format. Most likely, your platform interprets
float a = 0.7;
as
float a = 0.69999....;
This is because of the internal representation of floating points on your platform. The link provided by Daniel should get you started.
That is due to accuracy issues in floating point representation on a computer. See this Wikipedia article.