这是我Russian Peasant Multiplication的简短实现。如何改进?
限制:仅在> 0,b> 0
时有效for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);
答案 0 :(得分:55)
可以通过添加空格,适当的缩进和适当的函数体来改进它:
int peasant_mult (int a, int b) {
for (p = 0;
p += (a & 1) * b, a != 1;
a /= 2, b *= 2);
return p;}
请参阅?现在很清楚如何使用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))))))
答案 1 :(得分:20)
我认为这太可怕了 这与编译器的观点完全相同,并且(希望)更清晰
int sum = 0;
while(1)
{
sum += (a & 1) * b;
if(a == 1)
break;
a = a / 2;
b = b * 2;
}
现在我把它写出来了,我明白了。
答案 2 :(得分:14)
有一种非常简单的方法可以改善这种情况:
p = a * b;
它甚至具有a或b可能小于0的优点。
如果看看它是如何工作的,你会发现它只是正常的手动乘法执行二进制。你的计算机是通过这种方式实现的(1),因此使用俄罗斯农民方法的最简单方法是使用内置乘法。
(1)也许它有一个更复杂的算法,但原则上你可以说,它适用于这个算法
答案 3 :(得分:7)
循环中仍然存在乘法。如果您想降低乘法的成本,可以改为使用它:
for(p=0;p+=(-(a&1))&b,a!=1;a>>=1,b<<=1);
答案 4 :(得分:5)
我发现它并不像其他人所说的那样特别可怕,模糊不清或不可读,而且我不理解所有那些事。这就是说,这就是我如何“改进”它:
// 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 );
答案 5 :(得分:4)
p
未初始化。
如果a
为零会怎样?
如果a
为负数会怎样?
更新:我发现您已更新问题以解决上述问题。虽然您的代码现在似乎按照规定工作(溢出问题除外),但它的可读性仍然低于应有的程度。
答案 6 :(得分:4)
这是代码混淆比赛吗?我想你可以做得更好。对于初学者来说,使用误导性的变量名而不是无意义的变量名。
答案 7 :(得分:3)
我认为它不完整,而且很难阅读。你在寻找什么具体的反馈意见?
答案 8 :(得分:2)
int RussianPeasant(int a, int b)
{
// sum = a * b
int sum = 0;
while (a != 0)
{
if ((a & 1) != 0)
sum += b;
b <<= 1;
a >>= 1;
}
return sum;
}
答案 9 :(得分:0)
没有乘法或除法的答案:
function RPM(int a, int b){
int rtn;
for(rtn=0;rtn+=(a&1)*b,a!=1;a>>=1,b<<=1);
return rtn;
}