快速模3或除法算法?

时间:2009-11-08 17:59:17

标签: performance algorithm binary

是否存在类似于2的幂的快速算法,其可以与3一起使用,即n%3。 也许是使用这样一个事实:如果数字的总和可以被3整除,那么这个数字也是可以整除的。

这导致了下一个问题。在数字中添加数字的快捷方式是什么?即37 - > 3 +7 - > 10 我正在寻找没有条件的东西,因为那些往往会抑制矢量化

感谢

3 个答案:

答案 0 :(得分:13)

4 % 3 == 1,所以(4^k * a + b) % 3 == (a + b) % 3。您可以使用此事实来评估32位x的x%3:

x = (x >> 16) + (x & 0xffff);
x = (x >> 10) + (x & 0x3ff);
x = (x >> 6) + (x & 0x3f);
x = (x >> 4) + (x & 0xf);
x = (x >> 2) + (x & 0x3);
x = (x >> 2) + (x & 0x3);
x = (x >> 2) + (x & 0x3);
if (x == 3) x = 0;

(未经测试 - 您可能需要多一些缩减。)这比您的硬件可以做x%3快吗?如果是的话,可能不是很多。

答案 1 :(得分:4)

comp.compilers item具有计算模3的特定建议。

另一种选择,特别是如果被除数的最大值是适度的,则乘以3的倒数作为定点值,用足够的精度来处理最大尺寸的被除数来计算商,然后从被除数中减去3 *商以得到余数。所有这些乘法都可以通过固定的移位和加法序列来实现。指令的数量取决于倒数的位模式。当股息最大值适中时,这非常有效。

关于在数字中添加数字...如果你想要添加十进制数字,你最终会做一些相当于数字转换为十进制的数字,这涉及到某处除以10。如果你愿意在base2中添加数字,你可以通过一个简单的shift-right和add循环来实现。可以使用各种巧妙的技巧在N位块中执行此操作,以进一步加快速度。

答案 2 :(得分:0)

不确定第一个问题,但对于第二个问题,您可以利用%运算符和整数除法:

int num = 12345;
int sum = 0;
while (num) {
    sum += num % 10;
    num /= 10;
}

这可行,因为12345 % 10 = 512345 / 10 = 1234并一直持续到num == 0