I assume that you want to round to nearest, and that .5
goes to the next bigger integer. And we restrict to a > 0
and b > 0
.
Consider that you already get the correct answer for half of the cases from simple integer arithmetics (because it is always rounding down). To get also the other half correct, you can shift the numerator by half the denominator:
#include <iostream>
int divide(int a, int b){
return (a+b/2) / b;
}
void test(int a, int b){
std::cout << a << " / " << b << " = " << (double)a/b << " == " << divide(a,b) << "\n";
}
int main(){
for (int i=0;i<20;++i){
test(i,3);
}
}
Output:
0 / 3 = 0 == 0
1 / 3 = 0.333333 == 0
2 / 3 = 0.666667 == 1
3 / 3 = 1 == 1
4 / 3 = 1.33333 == 1
5 / 3 = 1.66667 == 2
6 / 3 = 2 == 2
7 / 3 = 2.33333 == 2
8 / 3 = 2.66667 == 3
9 / 3 = 3 == 3
10 / 3 = 3.33333 == 3
11 / 3 = 3.66667 == 4
12 / 3 = 4 == 4
13 / 3 = 4.33333 == 4
14 / 3 = 4.66667 == 5
15 / 3 = 5 == 5
16 / 3 = 5.33333 == 5
17 / 3 = 5.66667 == 6
18 / 3 = 6 == 6
19 / 3 = 6.33333 == 6
I will try to visualize what happens here, actually it is rather simple:
For denomiator 3:
a 0 1 2 3 4 5 6
a/3 000000000 111111111 222222 <- integer arithmetics
round(a/3) 00000 111111111 2222222222 <- desired result
a/3==n.5 ^ ^
For denominator b
a 0 1 2 ... b/2 ... b-1 b b+1
a/b 000000000000000000000000000000 111111111111
round(a/3) 000000000000 111111111111111111111111111111
a/b==n.5 ^
With denominator b=3
we need to add an offset of 1
to a
to get correct results. In general we need to add an offset of b/2
. I hope the tables speak more than words.
Note that a+b/2
is suspectible to overflows. There are other mathematically equivalent epxressions that do not overflow that easily. As the final result for sure fits in an int
we can use unsigned
for the intermediate addition:
int div = (static_cast<unsigned>(a) + static_cast<unsigned>(b/2)) / b;
For typical implementations where unsigned
can store the sum of any two positive int
s this avoids the overflow.