xxx*_*xxx 3 c algorithm optimization multiplication
这是我对俄罗斯农民增殖的简短实施.怎么改进?
限制:仅在> 0,b> 0时有效
for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);
Run Code Online (Sandbox Code Playgroud)
Sva*_*nte 55
它可以通过添加空格,适当的缩进和适当的函数体来改进:
int peasant_mult (int a, int b) {
for (p = 0;
p += (a & 1) * b, a != 1;
a /= 2, b *= 2);
return p;}
Run Code Online (Sandbox Code Playgroud)
看到?现在很清楚如何for使用声明的三个部分.请记住,程序主要是为人眼编写的.不可读的代码总是错误的代码.
现在,为了我个人的娱乐,一个尾递归版本:
(defun peasant-mult (a b &optional (sum 0))
"returns the product of a and b,
achieved by peasant multiplication."
(if (= a 1)
(+ b sum)
(peasant-mult (floor (/ a 2))
(* b 2)
(+ sum (* b (logand a 1))))))
Air*_*Ltd 20
我认为这很糟糕这与编译器的观点完全相同,并且(希望)更加清晰
int sum = 0;
while(1)
{
sum += (a & 1) * b;
if(a == 1)
break;
a = a / 2;
b = b * 2;
}
Run Code Online (Sandbox Code Playgroud)
现在我把它写出来了,我明白了.
flo*_*olo 14
有一种非常简单的方法可以改善这种情况:
p = a * b;
Run Code Online (Sandbox Code Playgroud)
它甚至具有a或b可以小于0的优点.
如果你看它是如何工作的,你会发现,它只是正常的手动乘法执行二进制.你的计算机以这种方式进行内核(1),因此使用俄罗斯农民方法的最简单方法是使用内置乘法.
(1)也许它有一个更复杂的算法,但原则上你可以说,它适用于这个算法
循环中仍然存在乘法.如果您想降低乘法的成本,可以改用:
for(p=0;p+=(-(a&1))&b,a!=1;a>>=1,b<<=1);
Run Code Online (Sandbox Code Playgroud)
我没有发现它特别可怕,混淆或不可读,正如其他人所说的那样,而且我不理解所有那些事.这就是说,这就是我如何"改进"它:
// Russian Peasant Multiplication ( p <- a*b, only works when a>0, b>0 )
// See http://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication
for( p=0; p+=(a&1)*b, a!=1; a>>=1,b<<=1 );
Run Code Online (Sandbox Code Playgroud)