0

I just started learning how to program in C++ and I'm already desperate because of one task. I'm only allowed to use the following operations: + - * / % and brackets and int variables and declaration, e.g. a = b;

The task is to divide int numbers a and b. The output should be the mathematically / arithmetically correct rounding to the next int. How do I do that? I can't use if/else, define new functions etc. I really don't know and I've tried a couple of things but they don't work for every case (a and b can be all positive integers).

Thanks a lot for your help!!!!

EDIT: As we didn't learn what bool etc. is, I can't use it. It should output, for example 5/2 = 3 (rounded up) 7/3 = 2 (rounded down)

kp00
  • 11
  • 1
  • 4

1 Answers1

2

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 ints this avoids the overflow.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185