我正在尝试实现带有舍入的整数除法。显然,默认情况下整数除法会取整,我想我可以使用余数来确定是否应该在结果中加 1。
在此解决方案中,处理器周期非常宝贵(以 10 kHz 运行),因此我正在寻找以最小开销实现此目的的方法,或者理想情况下“免费”获得结果作为现有除法计算的一部分
我的问题是,有谁知道在实际上没有除法指令的 G0 上实现这一点的好方法吗?我需要进行反汇编并看看它在做什么吗?我需要编写自己的汇编代码吗?有公认的解决方案吗?
注意:商和除数都是任意的,而不是常整数。
我的问题是,有谁知道在实际上没有除法指令的 G0 上实现此目的的好方法吗?
我不知道有什么通用方法比编译器已经做的更快。
有一些方法可以比通用代码更快,如果:
分子(被除数)的范围是非负数。
分母(除数)的范围为正。
我们可以忽略
INT_MIN/-1
舍入模式关系远离 0(如下所示),而不是关系到偶数。
让
q = rounded_division(a, b)
使用
div()
在一次操作中计算 a/b
和 a%b
。
#include <stdlib.h>
div_t qr = div(a, b);
if (qr.quot >= 0) {
if (a >= 0) {
if (b/2 > r.rem) qr.quot++;
} else {
if (b/2 < r.rem) qr.quot--;
}
} else {
if (a >= 0) {
if (b/2 < r.rem) qr.quot--;
} else {
if (b/2 > r.rem) qr.quot++;
}
}
a >= 0
和b > 0
和a + b/2
不溢出时:除法前先加上除数的一半。
q = (a + b/2)/b;
a + b/2
(a - b/2
)不溢出时:除法之前将一半(带有选择符号)加到除数上。
// If a and b have the same sign ...
if ((a < 0) == (b < 0)) {
q = (a + b/2)/b;
} else {
q = (a - b/2)/b;
}
此处进行的舍入是“舍入到最接近的,远离 0”。
通过符号比较可以实现一些潜在的优化,但通常更难理解。通常,即使没有这样精心设计的代码,编译也会生成良好的代码。 示例:
// if ((a < 0) == (b < 0)) {
if (!((a ^ b) & INT_MIN)) {
除以 0 和
INT_MIN/-1
仍然是 未定义行为 (UB)。
(我希望我对所有案例的编码都是正确的。)