Вывод кода ниже должен дать очень сильную подсказку;)
#include <iostream>
using namespace std;
int multiply(int a, int b)
{
cout << "a = " << a << "\tb = " << b << std::endl;
if ( !b )
return 0;
else
return a + multiply(a, b ? --b : ++b );
}
int main() {
cout << multiply(12, 7) << endl;
cout << multiply(12, -7) << endl;
cout << multiply(-12, -7) << endl;
cout << multiply(-12, 7) << endl;
return 0;
}
Мне кажется, что он получает ответ, пройдя долгий путь.
Редактировать: В ответ на комментарий Nawaz ниже, первый метод работает из-за капризов целой арифметики со знаком, дополненной двумя.Как я уже сказал, это займет много времени.Он включен, как указывали другие, из-за какой-то оптимизации компилятора или другой.Вы можете увидеть это в приведенном ниже коде для тестового ввода, ранее предоставленного:
int mul2(int a, int b)
{
int rv = 0;
while (b--) rv += a;
return rv;
}
На самом деле это должно работать для любой пары целых чисел, но в некоторых случаях потребуется некоторое время для запуска (но я ожидаю, что вы нене интересует эффективность в любом случае).
Второй случай не работает, потому что ваш условный b > 0 ? --b : ++b
по существу преобразует b
в abs(b)
.То есть вы добавляете только 7 раз в вашем тестовом примере, даже если b = -7.Если вы хотите, чтобы он вел себя так, как я думаю, вы хотите, чтобы он вел себя, вам вместо этого нужно сделать что-то вроде:
int multiply(int a, int b)
{
if ( !b )
return 0;
else if (b < 0)
return -a + multiply(-a, -b-1);
else
return a + multiply(a, --b);
}
Редактировать 2: Попробуйте вместо этого:
short multiply(short a, short b)
{
if ( !b )
return 0;
else
return a + multiply(a, b ? --b : ++b );
}
и
short multiply(short a, short b)
{
if ( !b )
return 0;
else
return a + multiply(a, --b);
}
Обе эти функции компилируются, запускаются и возвращают один и тот же (правильный) результат с оптимизацией или без нее.Как уже отмечали другие, причина разницы во времени выполнения, которую вы видите, может быть объяснена только тем, как компилятор оптимизирует ваш код.Вам нужно будет проанализировать ассемблерный код двух методов, чтобы определить основную причину расхождений во времени.