下面代码的输出应该给出一个非常强烈的线索 ;)
#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;
}
It looks to me like it's getting the answer by going the long way.
Edit: In response to the comment from Nawaz below, the first method works because of the vagaries of two's complement signed integer arithmetic. Like I said, it takes the long way around. It is enabled, as others have pointed out because of some compiler optimization or another. You can see this in the code below for the test input previously provided:
int mul2(int a, int b)
{
int rv = 0;
while (b--) rv += a;
return rv;
}
It in fact should work for any pair of integers but will take some time to run in some case (but I expect you weren't interested in efficiency in any event).
The second case does not work because your conditional b > 0 ? --b : ++b
essentially converts b
to abs(b)
. That is, you only add 7 times in your test case even though b = -7. If you wanted it to behave the way I think you wanted it to behave you would instead need to do something like:
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);
}
Edit 2: Try this instead:
short multiply(short a, short b)
{
if ( !b )
return 0;
else
return a + multiply(a, b ? --b : ++b );
}
and
short multiply(short a, short b)
{
if ( !b )
return 0;
else
return a + multiply(a, --b);
}
Both of these compile, run and return the same (correct) result with or without optimization. As others have pointed out, the cause of the execution time difference you are seeing can only be attributed to the way the compiler is optimizing your code. You will need to analyze the assembly code of the two methods to determine the root cause of the time discrepancies.
--b
/++b
。没有理由修改本地变量。只需执行b-1
和b+1
即可完成操作。 - Sven