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. Advertising

  2. Test

    Eric Sosman Guest

    On 10/13/2013 4:31 AM, Test wrote:
    > 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()?


    i = (i5 + i2 - 1) / i2;

    --
    Eric Sosman
    d
    Eric Sosman, Oct 13, 2013
    #2
    1. Advertising

  3. On Sunday, October 13, 2013 10:24:14 AM UTC+1, wrote:
    > On Sun, 13 Oct 2013 11:31:57 +0300, Test <test@.nil.invalid.com>
    >


    > >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()?

    >

    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

    On 10/13/2013 05:24 AM, Robert Wessel wrote:
    > On Sun, 13 Oct 2013 11:31:57 +0300, Test <test@.nil.invalid.com>
    > wrote:
    >
    >> 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.

    >
    >
    > Baring a broken compiler, 3 is the only possible result. Casting i5
    > to a double will then force i2 to a matching promotion, so that the
    > (double) division can occur. So the result *must* be 2.5, and
    > ceil(2.5) must be 3.0. Nor should there be any question of how that
    > converts back to an int.


    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
    James Kuyper, Oct 13, 2013
    #4
  5. Test

    Seebs Guest

    On 2013-10-13, Test <test@> wrote:
    > 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.


    .... 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.

    > 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()?


    If they're always smallish positive integers:
    i = (i5 + 1) / i2;

    -s
    --
    Copyright 2013, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    Autism Speaks does not speak for me. http://autisticadvocacy.org/
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Oct 15, 2013
    #5
  6. Test

    Noob Guest

    Seebs wrote:

    > If they're always smallish positive integers:
    > i = (i5 + 1) / i2;


    Close, but no cigar. Eric got it right ;-)
    Noob, Oct 15, 2013
    #6
  7. On Tuesday, October 15, 2013 8:45:44 AM UTC+1, Noob wrote:
    > Seebs wrote:
    >
    >
    >
    > > If they're always smallish positive integers:

    >
    > > i = (i5 + 1) / i2;

    >
    >
    >
    > Close, but no cigar. Eric got it right ;-)
    >

    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

    "Malcolm McLean" <> wrote in message
    news:...
    > On Tuesday, October 15, 2013 8:45:44 AM UTC+1, Noob wrote:
    >> Seebs wrote:
    >>
    >> > If they're always smallish positive integers:

    >>
    >> > i = (i5 + 1) / i2;

    >>
    >> Close, but no cigar. Eric got it right ;-)
    >>

    > His fails on i5 + i2 -1 > INT_MAX, but it's faster solution than mine,
    > so the one to be preferred.


    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

    On 10/15/2013 07:23 AM, James Harris wrote:
    > "Malcolm McLean" <> wrote in message
    > news:...
    >> On Tuesday, October 15, 2013 8:45:44 AM UTC+1, Noob wrote:
    >>> Seebs wrote:
    >>>
    >>>> If they're always smallish positive integers:
    >>>
    >>>> i = (i5 + 1) / i2;
    >>>
    >>> Close, but no cigar. Eric got it right ;-)
    >>>

    >> His fails on i5 + i2 -1 > INT_MAX, but it's faster solution than mine,
    >> so the one to be preferred.

    >
    > 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.


    Malcolm's solution was not the one given above; it was:
    > int x = i5/i2;
    > if(x * i2 < i5)
    > x++;

    --
    James Kuyper
    James Kuyper, Oct 15, 2013
    #9
  10. Test

    James Kuyper Guest

    On 10/15/2013 03:34 AM, Seebs wrote:
    > On 2013-10-13, Test <test@> wrote:
    >> 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.

    >
    > ... 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.
    >
    >> 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()?

    >
    > If they're always smallish positive integers:
    > i = (i5 + 1) / i2;


    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
    James Kuyper, Oct 15, 2013
    #10
  11. Test

    James Kuyper Guest

    On 10/15/2013 03:34 AM, Seebs wrote:
    > On 2013-10-13, Test <test@> wrote:
    >> 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.

    >
    > ... 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.
    >
    >> 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()?

    >
    > If they're always smallish positive integers:
    > i = (i5 + 1) / i2;


    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
    James Kuyper, Oct 15, 2013
    #11
  12. Test

    Eric Sosman Guest

    On 10/15/2013 7:23 AM, James Harris wrote:
    >[...]
    >
    > 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.


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

    i = 0;

    --
    Eric Sosman
    d
    Eric Sosman, Oct 15, 2013
    #12
  13. On Tuesday, October 15, 2013 12:23:10 PM UTC+1, James Harris wrote:
    > "Malcolm McLean" <> wrote in message
    >
    > 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.
    >

    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. Malcolm McLean <> writes:

    > On Tuesday, October 15, 2013 12:23:10 PM UTC+1, James Harris wrote:
    >> "Malcolm McLean" <> wrote in message
    >>
    >> 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.
    >>

    > Mine has does a multiply then has an if statement. Branches tend to be quite
    > expensive, whilst addition is always an extremely cheap operation.


    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.
    Ben Bacarisse, Oct 15, 2013
    #14
  15. Test

    James Harris Guest

    "Malcolm McLean" <> wrote in message
    news:...
    > On Tuesday, October 15, 2013 12:23:10 PM UTC+1, James Harris wrote:
    >> "Malcolm McLean" <> wrote in message
    >>
    >> 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.
    >>

    > 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.


    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. James Kuyper <> wrote:
    > On 10/15/2013 03:34 AM, Seebs wrote:


    (snip)

    >>> i5=5;i2=2;
    >>> i=ceil((double)i5/i2);
    >>> I get 3 but from past experience I doubt some compilers will return 2.


    >> ... 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.


    That should be true, but for larger i5 you might get to the point
    where floating point rounds the wrong way.

    (snip)

    >> If they're always smallish positive integers:
    >> i = (i5 + 1) / i2;


    > 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.


    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

    On 10/15/2013 03:01 PM, glen herrmannsfeldt wrote:
    > James Kuyper <> wrote:
    >> On 10/15/2013 03:34 AM, Seebs wrote:

    >
    > (snip)
    >
    >>>> i5=5;i2=2;
    >>>> i=ceil((double)i5/i2);
    >>>> I get 3 but from past experience I doubt some compilers will return 2.

    >
    >>> ... 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.

    >
    > That should be true, but for larger i5 you might get to the point
    > where floating point rounds the wrong way.


    True - that would require that INT_MAX*DBL_EPSILON > 1; which is
    unlikely, but permitted. It could be an issue on 64bit machines.

    >>> If they're always smallish positive integers:
    >>> i = (i5 + 1) / i2;

    >
    >> 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.

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


    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

    On 2013-10-15, Malcolm McLean <> wrote:
    > On Tuesday, October 15, 2013 8:45:44 AM UTC+1, Noob wrote:
    >> Seebs wrote:
    >>
    >>
    >>
    >> > If they're always smallish positive integers:

    >>
    >> > i = (i5 + 1) / i2;

    >>
    >>
    >>
    >> Close, but no cigar. Eric got it right ;-)


    > His fails on i5 + i2 -1 > INT_MAX, but it's faster solution than mine,
    > so the one to be preferred.


    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
    --
    Copyright 2013, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    Autism Speaks does not speak for me. http://autisticadvocacy.org/
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Oct 16, 2013
    #18
  19. Test

    Seebs Guest

    On 2013-10-15, James Kuyper <> wrote:
    > 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.


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

    -s
    --
    Copyright 2013, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    Autism Speaks does not speak for me. http://autisticadvocacy.org/
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Oct 16, 2013
    #19
  20. Test

    Guest

    In article <l3e2vj$aa6$>,
    Eric Sosman <> wrote:
    > On 10/13/2013 4:31 AM, Test wrote:
    > > 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.



    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.


    > >
    > > 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()?

    >
    > i = (i5 + i2 - 1) / i2;
    >



    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!" ?

    --
    B. L. Massingill
    ObDisclaimer: I don't speak for my employers; they return the favor.
    , Oct 18, 2013
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Schnoffos
    Replies:
    2
    Views:
    1,195
    Martien Verbruggen
    Jun 27, 2003
  2. Hal Styli
    Replies:
    14
    Views:
    1,612
    Old Wolf
    Jan 20, 2004
  3. zlotawy

    ceil and floor

    zlotawy, Sep 15, 2007, in forum: VHDL
    Replies:
    4
    Views:
    666
  4. ptn

    ceil() and log10() - undefined?

    ptn, Oct 3, 2007, in forum: C Programming
    Replies:
    14
    Views:
    7,591
    Keith Thompson
    Oct 4, 2007
  5. ptn

    ceil() and log10() - undefined?

    ptn, Oct 3, 2007, in forum: C Programming
    Replies:
    1
    Views:
    314
Loading...

Share This Page