Thread: Problem With ceil() and floor() functions

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    18

    Problem With ceil() and floor() functions

    Hi all,
    Please go through the following very basic code.

    Code:
    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
            float i = 2.5;
    
            printf ("%d %f\n", floor(i), ceil(i));
    
            return 0;
    }
    When I compiled and executed this code, It produced the following output.

    Code:
    0 0.000000
    But according to the definition of floor and ceil function, it must have returned 2 3.000000 as result.

    Compiler: gcc 4.4.1
    OS: Mandriva 2010

    Thanks and Best Regards,
    Aakash Johari

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    floor() returns a double, not an int; so use %f. Otherwise, to use %d, you'll have to cast the return value of floor() to an int. printf() does not know the types of the arguments you're passing, so it's up to you to get them right.

  3. #3
    Registered User
    Join Date
    Jan 2011
    Posts
    18
    I know well. That I must you %d instead of %f for this. But the question is that why it is affecting the second correctly specified ceil() function value

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    When you have sequential data to be printed in the same printf() call, it's important to get the first data item correct, FIRST. That may correct the second data item, right there.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Possibly because printf() detected an error on the first format specifier and returned at that point. What is your printf() returning?

    Jim

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by jimblumberg View Post
    Possibly because printf() detected an error on the first format specifier and returned at that point. What is your printf() returning?
    If that's the case, it wouldn't have printed two values.

    The more likely explanation is that the executable being run does not correspond to the code shown.

    For example, an older version of the code was printing the two zero values. The code as shown did not correctly compile and link (eg due to a missing -lm option).

    In other words, a version control error by the programmer.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Jan 2011
    Posts
    18
    It is not the case that the program is not compiled correctly.

    printf() is returning 11.

    and I have compiled it with -lm switch. So no chance of not being compiled correctly.

    Hoping for the correct reply!!

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by aakashjohari View Post
    It is not the case that the program is not compiled correctly.

    printf() is returning 11.

    and I have compiled it with -lm switch. So no chance of not being compiled correctly.

    Hoping for the correct reply!!
    You've already had the correct reply. %d means "print an int", which means "take four bytes off the stack and go with it". Therefore printf takes half of your double off the stack, specifically the half that's all zeroes (2.0, as a double, has only two or three bits set, all in the exponent, which in a little endian machine will not be in the front half of memory). %f means "print a double", which means "take eight bytes off the stack and go with it", which will be the other half of your first double and half of your second double. Same deal -- you've only got two or three bit sets, but now they're not in the exponent, and you have a subnormal float, which printed as 0.

  9. #9
    Registered User
    Join Date
    Jan 2011
    Posts
    18
    Yes, You all are right.

    I have experimented this.

    C maintains a stack for arguments.

    Code:
    printf ("%c %c", 'A', 'B');
    In this case, 'A' is first pop-out and then 'B'. (A character is 8-bit sequence hence first that 8-bits and then for next character 'B', next 8-bits)

    Now try to print the following:

    Code:
    printf ("%c %c", 283467841601LL);
    this will give you the same answer.

    First find the Hex Equivalent of it.

    It comes out to be: 0x4200000041

    0x41 = 65 (ASCII code of 'A')
    0x42 = 66 (ASCII code of 'B')

    It adds 6 Hex Zeros (6 * 4 = 24 bits) in between. This is because when we print any character by printf it is first converted to an Integer ( 32-bit long).

    So you can prove it as follows:
    00000041 = 8 Hex digits = 8 * 4 bits = 32 bits = 4 bytes

    So first from the stack, 0x00000041 comes out and gives us 'A' and then 0x00000042 which gives us 'B'.

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Do be careful to not make real use of the information about how your compiler passes arguments. There's no guarantee that a stack is used, or if one is used, that arguments are pushed in the order you expect. And, of course, a long long need not be 64-bit, nor does a char need to be 8 bits.

    It's interesting (and probably useful) to know how various systems work at a lower level, but you should not assume that because one implementation operates in a particular way that all do.

  11. #11
    Registered User
    Join Date
    Jan 2011
    Posts
    18
    Yes, you are right cas. It is machine dependent.

Popular pages Recent additions subscribe to a feed