模运算符是否会减慢嵌入式系统的速度在很大程度上取决于您正在讨论的哪些嵌入式系统。
例如,MPS430 CPU 实际上有本机除法指令,因此,如果您使用它,则需要恢复为基于软件的计算。
但是,确实具有本机划分的 CPU 通常没问题,因此最好先测试您是否有问题,然后再尝试解决它。
如果没有本机除法指令,您的第一次尝试将类似于(C,仅用于无符号并忽略 div 目前为零的问题):
unsigned modulo (unsigned num, unsigned div) {
while (num >= div)
num -= div;
return num;
}
换句话说,使用重复减法,如果num 很大而div 很小,则不会很快。
但是,如果您意识到a % b 与a % 2b 完全相同,那么您可以大大提高该函数的速度,前提是2b <= a。
或者说和a % 4b一样,前提是4b <= a。 a % 8b 同上,前提是 8b <= a。
因此,通过一点递归魔法,我们可以调整 num,使其非常快速地减少到重复减法不会成为主要问题的程度。
unsigned modulo (unsigned num, unsigned div) {
if (num - div >= div)
num = modulo (num, div + div);
while (num >= div)
num -= div;
return num;
}
而天真的代码示例在我的系统上大约需要十秒钟来处理一百个模运算(使用随机数 num 和一到一百之间的随机数 div),改进的解决方案可以获得在大约三分之一秒内通过一百万,加速大约 300,000 倍。
如果您知道除数是 2 的幂,您还可以大大加快处理速度 - 使用按位运算有一种更快的方法。考虑一下你想锻炼:
974 % 16
您还可以使用二进制数和按位运算的属性来为您提供低四位:
num = num & 15;
那是因为15 是二进制的1111,如果你and 有任何数字,它只会清除最高位,得到与mod 16 相同的结果。这适用于 2 的所有幂,例如 2、4、8、...65536、...等等。
对于 974 % 16 的具体示例,974 与 15 的二进制位与运算得到:
1111001110
1111 &
----------
0000001110 (14)
而14确实是正确答案。