# ceil() and int values

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

1. ### TestGuest

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

2. ### Eric SosmanGuest

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

3. ### Malcolm McLeanGuest

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
4. ### James KuyperGuest

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
5. ### SeebsGuest

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
6. ### NoobGuest

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
7. ### Malcolm McLeanGuest

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
8. ### James HarrisGuest

"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
9. ### James KuyperGuest

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
10. ### James KuyperGuest

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
11. ### James KuyperGuest

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
12. ### Eric SosmanGuest

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
13. ### Malcolm McLeanGuest

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
14. ### Ben BacarisseGuest

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.

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
15. ### James HarrisGuest

"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
16. ### glen herrmannsfeldtGuest

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,

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
17. ### James KuyperGuest

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,

>
> 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
18. ### SeebsGuest

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
19. ### SeebsGuest

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