Aba*_*han 5 c embedded bankers-rounding rounding integer-division
在 C 语言中,最简单的实现公式是什么int divround(int a, int b) {...},其中输出为 a/b,并采用银行家四舍五入(四舍五入为偶数)?
例如,divround(3,2)两者divround(5,2)的计算结果均为 2。
我正在编写嵌入式代码,所以我不能依赖库。我希望代码对于 ARM 和 RISC-V 是通用的,所以也不需要汇编。我试图模仿np.around(a/b)NumPy 中的行为(它执行大约一半到偶数),因此我可以准确比较来自 Python 和我的嵌入式应用程序的输出测试向量。
假设a和b是非负数,并且b小于INT_MAX / 2,以下是一个简单的实现:
int divround(int a, int b)
{
int q = a / b;
int r = a % b;
if (2*r > b) {
return q + 1;
} else if (2*r < b) {
return q;
} else if (q % 2 == 0) {
return q;
} else {
return q + 1;
}
}
Run Code Online (Sandbox Code Playgroud)
解释一下:
b向上舍入的一半,如果小于向下舍入的一半。b/2正好,则检查商是否为偶数,如果是则向下舍入,否则向上舍入。如果您还想处理负值,请首先确定结果的符号并将值标准化为非负,然后在将符号与结果相乘的同时执行上述操作。工作假设b在INT_MIN / 2和之间INT_MAX / 2。
int divround(int a, int b)
{
int s_a = 1, s_b = 1;
if (a < 0) {
a = -a;
s_a = -1;
}
if (b < 0) {
b = -b;
s_b = -1;
}
int q = a / b;
int r = a % b;
int sign = s_a * s_b;
if (2*r > b) {
return sign * (q + 1);
} else if (2*r < b) {
return sign * q;
} else if (q % 2 == 0) {
return sign * q;
} else {
return sign * (q + 1);
}
}
Run Code Online (Sandbox Code Playgroud)
当然,不要除以 0。