Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

math.h ceil not working as expected in C

How come ceil() rounds up an even floating with no fractional parts?
When I try to do this:

double x = 2.22;  
x *= 100; //which becomes 222.00...  
printf("%lf", ceil(x)); //prints 223.00... (?)  

But when I change the value of 2.22 to 2.21

x *= 100; //which becomes 221.00...  
printf("%lf", ceil(x)); //prints 221.00... as expected  

I tried to do it another way like this using modf() and encountered another strange thing:

double x = 2.22 * 100;  
double num, fraction;  
fraction = modf(x, &num);  
if(fraction > 0)  
    num += 1; //goes inside here even when fraction is 0.00...  

So what happens is 0.000... is greater than 0?
Can anyone explain why both of these situations are happening? Also I'm compiling using cc version 4.1.2 in RedHat.

like image 887
bojaboja Avatar asked Feb 22 '10 13:02

bojaboja


2 Answers

This is normal as numbers are stored using binary. While your numbers can be written in finite numbers of digits using decimal, this does not hold for binary.

You should read Goldberg's report called What Every Computer Scientist Should Know About Floating-Point Arithmetic.

like image 51
Goran Rakic Avatar answered Sep 30 '22 16:09

Goran Rakic


The basic answer is that the floating point number you get with:

double x = 2.22;

is actually a tiny bit larger than the value 2.22, and the value you get with

double x = 2.21;

is a tiny bit smaller than 2.21.

like image 23
Daniel Martin Avatar answered Sep 30 '22 17:09

Daniel Martin