我假设你想四舍五入到最接近的,.5然后到下一个更大的整数。我们限制为a > 0和b > 0。
考虑到您已经从简单的整数算术中得到了一半情况的正确答案(因为它总是向下舍入)。为了使另一半也正确,您可以将分子移动分母的一半:
#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);
}
}
输出:
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
我将尝试想象这里发生了什么,实际上它很简单:
对于分母 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 ^ ^
对于分母 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 ^
对于分母b=3,我们需要添加一个偏移量1来a获得正确的结果。一般来说,我们需要添加一个偏移量b/2。我希望桌子能说的胜过千言万语。
请注意,这a+b/2可能会溢出。还有其他数学上等价的表达式不会那么容易溢出。作为最终结果肯定适合int我们可以unsigned用于中间添加:
int div = (static_cast<unsigned>(a) + static_cast<unsigned>(b/2)) / b;
对于unsigned可以存储任何两个正数之和的典型实现,int这可以避免溢出。