472,118 Members | 1,554 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,118 software developers and data experts.

Floor and ceil function

I've learned that we can round up and down a float number by using Ceil and floor function. But, is this function still able to work if I the number I want to round up (or down) is zero?
I have wrote my codes, but somehow it didn't give the right answer if the number is zero. My simple code looks like this:

Expand|Select|Wrap|Line Numbers
  1. #include <math.h> 
  2. int main(){
  4. printf("The nearest integer from %f is %f\n", 0,ceil(0) );  
  5. }
The resut is like this:
"The nearest integer from 0.000 is 1.000"

And the same answer happen if I change Ceil to floor.
Did I miss something?

Thank you for your time.
May 26 '09 #1
7 25006
11,448 Expert 8TB
What compiler are you using? I get 0.000000 for an answer and I used a couple of compilers.

kind regards,

May 26 '09 #2
You can always write your own macro if your compiler is screwing up:

Expand|Select|Wrap|Line Numbers
  1. #define CEIL(VARIABLE) ( (VARIABLE - (int)VARIABLE)==0 ? (int)VARIABLE : (int)VARIABLE+1 )
Any questions?

Or if you hate macros as much as any CSc professor, you can do this:

Expand|Select|Wrap|Line Numbers
  1. int CEIL(double var)
  2. {
  3.      int integer = (int)var;
  4.      if(var - integer == 0) return integer;
  5.      else return integer + 1;
  6. }
May 26 '09 #3
I have tried another way. I declared an array (arr[5]) and use ceil and floor function. If the number is not zero, the result came out fine, but if the number is zero the result came out not fine. Because sometime it right but for another array,it results 1.000
My code looks like this;
Expand|Select|Wrap|Line Numbers
  1. # include <math.h> 
  2. int main(){
  3. float arr[5],c[5];
  4. int i;
  6. arr[0]=-2.828427; arr[1]=-0.707107; arr[2]=0.000000;arr[3]=-0.707107;
  7. arr[4]=0.000000;
  9. for (i=0;i<5;i++){
  10.   c[i]=ceil (arr[i]);
  11.   printf ("%f\n",c[i]);
  12. }
  14. }
And the result is like this:

Is it my compiler problem?If it is, what do you think that make it screw up?
Oh yeah, I use Dev C++ as my compiler.

Thank you
May 26 '09 #4
2,425 Expert 2GB
The C Standard says that ceil(x) "returns the smallest integral value not less than x, expressed as a double."

Neither of your examples returns a double.
Both of your examples depend on how the compiler behaves when you cast a double to an integer (round, truncate, other). That's implementation-defined behavior; not something you can count on. For example, C99 allows you to select between four different rounding modes.
May 26 '09 #5
2,425 Expert 2GB
I don't know why it would make a big difference, but the input and return value for ceil are both doubles. Try changing line 3 to declare arrays of double rather than arrays of float. No change needed on line 11 after you change line 3 because %f converts a double value (you, however, were passing a float value).
May 26 '09 #6
My examples were not meant to be 1 to 1 clone of the standard library. Heck, they weren't even very safe (cast double->int can cause an overflow). I don't see why you are making a point of this.

I admit that my examples were based on my previous experiences when casting. However, the C99 standard states:
When a finite value of real floating type is converted to an integer type other than _Bool,
the fractional part is discarded (i.e., the value is truncated toward zero). If the value of
the integral part cannot be represented by the integer type, the behavior is undefined.
Would you elaborate on the "4 different ways" you wrote of?

I tried compiling your code in the latest version of Dev-C++ and it works fine. My output was -2, 0, 0, 0, 0.
Perhaps you should download the latest version of your IDE? A clean installation would be great.
May 26 '09 #7
2,425 Expert 2GB
I was unaware of this. Thanks for bringing it to my attention. You're right -- this knocks out my objection regarding implementation-defined behavior.
C99 added fenv.h. That header makes functions fegetround and fesetround available. These functions get and set the rounding mode. Possible rounding modes are FE_DOWNWARD (similar to floor function), FE_TONEAREST, FE_TOWARDZERO (similar to casting floating type to integral type), and FE_UPWARD (similar to ceil function). I only brought this up because I thought implementation-defined behavior from casting a double to int might be in accordance with the current rounding mode. We now know that is not the case.
May 26 '09 #8

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

5 posts views Thread by SpaceCowboy | last post: by
6 posts views Thread by Jef Driesen | last post: by
29 posts views Thread by Vol | last post: by
8 posts views Thread by momotaro | last post: by
14 posts views Thread by yansong1990 | last post: by
5 posts views Thread by john.leidel | last post: by
7 posts views Thread by MrIncognito | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.