I was trying to write a code where after decimal value if the fraction value is 0.005 then it will print the value as 0.01. I tried to use %0.02f but it this method didn't work. my full code is below and the input value.
#include<stdio.h>
int main()
{
float a,b,c=0,d=0,e=0;
while(1)
{
a=0;b=0;c=0,d=0,e=0;
scanf("%f%f",&a,&b);
c=b-a;
d=c*100.0;
e=d/a;
//printf("%0.2f\n%0.2f\n%0.2f\n",c,d,e);
printf("%0.2f%%\n",e);
}
return 0;
}
input 999.95 1000.00
expected output = 0.01%
My output = 0.00%
Your math, with 32 bit float
s, comes up with a final value for e
of 0.004999...
, not the "logical" 0.005
you expect (and expect to round to 0.01
). That's just how it is with floating point math. Rounding that to two decimal places accurately describes the result as 0.00
; it's less than 0.005
, so it rounds to 0.00
, not 0.01
.
Using a more precise type (double
) might help (it does on my machine [after changing the scanf
to use %lf
], but many compilers, especially with higher optimizations, and some architectures, violate IEEE-754 specs, and might disagree), but fundamentally, floating point math will introduce errors relative to precise logical arithmetic, so you should be using a different approach if you can't tolerate even small errors, e.g. fixed point int
-based math, or libmpdec
or the like for full decimal (base-10) floating point math.
Note that depending on what you choose to do, you may need to be careful about the rounding mode; C99 rounds half-way values away from zero, but there are other rounding modes (round half-even being a common one due to not introducing a bias in the rounding) that would produce 0.00
when rounding to two decimal places, even if you did produce 0.005
precisely.