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;
}
Алгоритм выходит из цикла while, когда b становится 0. Число выполнений цикла составляет [log2 (b)] + 1 раз.
И сдвиг почти занимает постоянное время (1 ЦПцикл)
Имеет смысл звонить с меньшим значением как 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/