# 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

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

Eric Sosman, Oct 13, 2013

3. ### Malcolm McLeanGuest

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

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

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

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

Noob, Oct 15, 2013
7. ### Malcolm McLeanGuest

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

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

Malcolm's solution was not the one given above; it was:

James Kuyper, Oct 15, 2013
10. ### James KuyperGuest

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

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

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

i = 0;

Eric Sosman, Oct 15, 2013
13. ### Malcolm McLeanGuest

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

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

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

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

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

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

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

-s

Seebs, Oct 16, 2013
20. ### blmblmGuest

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