ceil() and int values

Discussion in 'C Programming' started by Test, Oct 13, 2013.

  1. Test

    Test Guest

    I need to get a ceil value from two integers

    When I use as follows:
    int i5,i2;
    i5=5;i2=2;
    i=ceil(i5/i2);
    I get 2 for obvious reasons.

    However when I use as follows:
    int i5,i2;
    i5=5;i2=2;
    i=ceil((double)i5/i2);
    I get 3 but from past experience I doubt some compilers will return 2.

    Safest way to get 3 appears to be lengthy
    int i5,i2;
    i5=5;i2=2;
    i=ceil((double)((double)i5/(double)i2));

    What is the "cleanest" but most compatible way? My program in this instance
    always uses integers greater than zero and less than 128. Is there another
    (speedier?) way other than using ceil()?
     
    Test, Oct 13, 2013
    #1
    1. Advertisements

  2. Test

    Eric Sosman Guest

    i = (i5 + i2 - 1) / i2;
     
    Eric Sosman, Oct 13, 2013
    #2
    1. Advertisements

  3. int x = i5/i2;
    if(x * i2 < i5)
    x++;

    it may or may not be faster, often floating point is pipelined separately
    to integer calculations, so it's very difficult to say whether removing a
    floating point operation will speed up code or not.
     
    Malcolm McLean, Oct 13, 2013
    #3
  4. Test

    James Kuyper Guest

    While I would agree with you that any compiler which produces any value
    other than 3 is broken, such a compiler could still be fully conforming:

    "The accuracy of the floating-point operations (+, -, *, /) and of the
    library functions in <math.h> and <complex.h> that return floating-point
    results is implementation defined, as is the accuracy of the conversion
    between floating-point internal representations and string
    representations performed by the library functions in <stdio.h>,
    <stdlib.h>, and <wchar.h>. The implementation may state that the
    accuracy is unknown." (5.2.2.4.2p6).

    Division is one of those operations, and ceil() is one of those
    functions, so there are two different opportunities for arbitrarily bad
    accuracy to be fully conforming, so long as the implementation documents
    the fact that it is that bad.

    If the implementation chooses to pre-#define __STDC_IEC_559__, the
    requirements are much stricter, and a conforming implementation must
    produce 3.
     
    James Kuyper, Oct 13, 2013
    #4
  5. Test

    Seebs Guest

    .... I doubt very much that any compiler will yield 2, because I don't
    think C's ever worked in a way where this could produce anything but 3.
    If they're always smallish positive integers:
    i = (i5 + 1) / i2;

    -s
     
    Seebs, Oct 15, 2013
    #5
  6. Test

    Noob Guest

    Close, but no cigar. Eric got it right ;-)
     
    Noob, Oct 15, 2013
    #6
  7. His fails on i5 + i2 -1 > INT_MAX, but it's faster solution than mine,
    so the one to be preferred.
     
    Malcolm McLean, Oct 15, 2013
    #7
  8. Test

    James Harris Guest

    I don't understand. Eric's was i = (i5 + i2 - 1) / i2. How can it be faster?
    Unless the divisor is a constant both will be dominated by the cost of the
    division.

    James
     
    James Harris, Oct 15, 2013
    #8
  9. Test

    James Kuyper Guest

    Malcolm's solution was not the one given above; it was:
     
    James Kuyper, Oct 15, 2013
    #9
  10. Test

    James Kuyper Guest

    I suppose that's correct, for a suitable definition of "smallish". The
    smallest pair of positive values for which it gives the wrong result is
    i5==1, i2==3, for which the correct result is 1, and your formula gives
    0. That's a pretty restrictive definition of "smallish".
     
    James Kuyper, Oct 15, 2013
    #10
  11. Test

    James Kuyper Guest

    Restricting consideration to the positive integers, that gives the wrong
    result whenever i2==1 || i5%i2 < i2-1. Example: i5 == 1, i2 == 3; the
    correct result should be 1, your expression gives 0.
     
    James Kuyper, Oct 15, 2013
    #11
  12. Test

    Eric Sosman Guest

    If speed is what most concerns you, it's hard to beat

    i = 0;
     
    Eric Sosman, Oct 15, 2013
    #12
  13. Mine has does a multiply then has an if statement. Branches tend to be quite
    expensive, whilst addition is always an extremely cheap operation.
    However Eric's won't give correct results in i5 + i2 overflows, whilst
    mine will. However that's unlikely, so for most purposes Eric's solution
    is the better one.
     
    Malcolm McLean, Oct 15, 2013
    #13
  14. Your if:

    if (x*i2 < i5) x++;

    can be written:

    x += x*i2 < i5;

    which may well compile without a branch. Indeed, the original might do
    as well. In fact it does in gcc -- only with -O0 do you get a branch.

    <snip>
     
    Ben Bacarisse, Oct 15, 2013
    #14
  15. Test

    James Harris Guest

    Ah, sorry. I read Peter's solution as yours. Yes, branches can be slow if
    they are unpredictable but will be very fast on many CPUs if the data allow
    them to be predicted well.

    James
     
    James Harris, Oct 15, 2013
    #15
  16. That should be true, but for larger i5 you might get to the point
    where floating point rounds the wrong way.

    (snip)
    But note that to the OP, i2=2. The OP didn't ask for a
    generalization, but only for this one specific case.

    -- glen
     
    glen herrmannsfeldt, Oct 15, 2013
    #16
  17. Test

    James Kuyper Guest

    True - that would require that INT_MAX*DBL_EPSILON > 1; which is
    unlikely, but permitted. It could be an issue on 64bit machines.
    If he didn't want generalization, he could have replaced i5 with 5, and
    i2 with 2, or he could have gone even farther and simply written

    i = 3;

    I think he was looking for a generalization.
     
    James Kuyper, Oct 15, 2013
    #17
  18. Test

    Seebs Guest

    I explicitly stated the necessary qualifier, because the OP had stated that
    things were in a range of 0-128 or so, as I recall. But for that case it's
    fine, so far as I know.

    -s
     
    Seebs, Oct 16, 2013
    #18
  19. Test

    Seebs Guest

    D'oh. I think I somehow formed the theory that we only cared about i2 == 2.

    -s
     
    Seebs, Oct 16, 2013
    #19
  20. Test

    blmblm Guest

    Tying this in, sort of, with the other thread in which usage of "doubt"
    is (was?) being debated once again ....

    Here's an instance of "doubt" being used in a way that -- IMO anyway --
    is potentially ambiguous.

    To a US-English speaker (or to this one anyway), it -- well, I'd
    say that it means "my guess is that there are no compilers that
    will return 2" except that I'd be more likely to write "I doubt
    any compilers would return 2".

    In context it appears to mean that maybe some compilers *do* return 2.

    "Just sayin'", maybe.


    Now there's a trick .... I learned it in a long-ago PPOE and think
    it's kind of a clever hack. But I don't know that I've observed
    anyone other than the long-ago colleague (and myself) using it.
    But apparently some others in this thread know about it, and also
    know that it *can* run up against problems with overflow. "Hm!" ?
     
    blmblm, Oct 18, 2013
    #20
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.