从时间效率的角度来看,用Russian peasant multiplication算法将n乘以m还是将m乘以n无关紧要?
例如,当计算26 * 47时,时间效率是否类似于47 * 26计算?
答案 0 :(得分:1)
由于算法为floor(log2(k))
的乘数(第一个数字)运行k
个迭代,因此运行时间肯定取决于顺序。如果n
和m
位于两个相同的两个连续幂之间,则它们将花费相同的迭代次数来完成。否则,请始终将较小的数字放在第一位以最小化运行时间。
答案 1 :(得分:1)
unsigned int russianPeasant(unsigned int a, unsigned int b) {
int res = 0; // initialize result
// While second number doesn't become 1
while (b > 0)
{
// If second number becomes odd, add the first number to result
if (b & 1)
res = res + a;
// Double the first number and halve the second number
a = a << 1;
b = b >> 1;
}
return res;
}
当b变为0时,算法退出while循环。循环运行的次数为[log2(b)] + 1次。
换挡几乎需要固定的时间(1个CPU周期)
以较小的值b调用是有意义的。
奖金:速度比较
我编写了上面的代码,并以相同的数字47和26循环运行了10 ** 8次。
a = 26,b = 47时,平均花费1336852.2微秒。
a = 47,b = 26,平均花费1094454.4微秒。
有趣的旁注:
尽管就像@Dillon Davis提到的那样,如果日志相同,则迭代次数应该相同,但我发现以b表示的次数仍然较少。
(所有时间均以微秒为单位)
a = 46,b = 36-1204240.6
a = 36,b = 46-1295766.8
a = 44,b = 36-1204266.2
a = 36,b = 44-1253821.17。
TLDR: 以较小的第二个数字(while循环中的一个)运行
源代码:https://www.geeksforgeeks.org/russian-peasant-multiply-two-numbers-using-bitwise-operators/
答案 2 :(得分:0)
这取决于您如何实现俄罗斯农民算法。可以是:
a*b
更快b*a
更快我选择无差异,因为实数的数学乘法是可交换的:a*b=b*a
,并且由于最终用户在调用函数时不希望打扰顺序争论
要做到这一点,您需要调整代码,例如:
Let the two given numbers be 'a' and 'b'.
1) If 'b' is greater than 'a' - swap 'a' with 'b'
2) Initialize result 'res' as 0.
3) Do following while 'b' is greater than 0
a) If 'b' is odd, add 'a' to 'res'
b) Double 'a' and halve 'b'
4) Return 'res'.
此代码会很复杂
O(log 2(min(a,b)))