Professional Documents
Culture Documents
log in
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.
tour
help
Sign up
}
c++
performance
algorithm
mathematics
floating-point
Post rolled back. Please do not modify the original code based on answers. Jamal Sep 12 '14 at 8:15
4 Answers
Instead of using a recursive algorithm (which might overflow the stack for large exponents) and
calculating the power yourself, use the pow function which is likely pretty optimized.
#include <iostream>
#include <cmath>
using namespace std;
double func(double x, int n)
{
double x_n;
93
192
Now a few minor remarks about your original code: be sure to be more consistent with your
coding style. For example:
if(exponent == 0)
return 1;
if (exponent == 1)
return base;
vs.
if (x == 0) return 1;
if (x == 1) return n+1;
Personally, I'd always either write it on one line as in the second example or if there is a
newline, I'd always add braces. For reasons see Apple's goto fail; . But it's actually a
personal preference, you don't need to do it that way but I highly recommend that you chose
one style and stick to it.
(Same with whitespace: there should be a space after the
if
in
if(exponent == 0)
Either use
0x1
both times or
You reversed one of the most important points in the OP's code: Not iterating over the xi but using the finite
formula 1q . Nobody Sep 12 '14 at 9:36
1q n
Since OP's code uses one stack frame (function call) for each bit of exponent , it will not cause a stack
overflow. abuzittin gillifirca Sep 12 '14 at 10:06
@Nobody: Ouch! You're right, have fixed it. DarkDust Sep 12 '14 at 10:09
@abuzittingillifirca: It can still allocate up to 31 or 63 stack frames when the exponent is positive, depending
on sizeof(int) and the value. That's not good but usually not a problem (depending on stack size). But it
will cause a stack overflow for n < -1 since it'll recurse endlessly. Of course, n < 0 should not be
allowed in the first place. DarkDust Sep 12 '14 at 10:19
2
I agree with your last points. Now that I've seen your edit+last comment my answer's become somewhat
moot. I've got segfault for negative exponents, but it depends on whether the right shift sign-extends.
exponent/2 would be better than exponent>>1 anyways. abuzittin gillifirca Sep 12 '14 at 11:23
Style
func(x, n)
Performance
x == 0
geometricSeries(x, n)
special case.
Your question is based on a faulty premise. The FMUL (floating-point multiplication) and FADD
(floating-point addition) instructions take the same number of clock cycles on x87-compatible
processors, pretty much universally.
The only time performance would be a concern is when n is large. In such circumstances,
you would be better off using the pow() function, which probably works using logarithms. For
comparison, I ran the following benchmark:
#include
#include
#include
#include
#include
<cmath>
<iostream>
<random>
<sys/time.h>
<vector>
if(exponent == 0)
return 1;
if (exponent == 1)
return base;
On my machine, your powerWithIntExponent() runs about 20% slower. Of course, the results
will differ widely depending on what range you choose for n .
Note that for extremely large results, the two implementations can produce answers that differ
significantly. I don't know which one is more accurate.
answered Sep 12 '14 at 8:06
200_success
76.6k
88
283
As the implementation via logarithm uses approximations it is highly probable that the "explicit" integer power
via multiplication is more accurate for large n . Nobody Sep 12 '14 at 9:51
exponent
result *= result;
if (exponent & ...) {
result *= base;
}
unsigned
if (exponent < 0)
return 1 / powerWithIntExponent(base, -exponent);
22
I am confused by your question. In the text you seem to imply you actually want to sum the
powers of x as part of the program, but the program just uses the formula for a finite part of the
geometric series. I would assume the latter (i.e. using the formula) will almost always be faster.
If you did actually want to perform the addition the method I'm familiar with is using the identity
a0 + a1 x + a2 x2 + an xn = (( (an x + an1 )x + )x + a0 )
for evaluating general polynomials. The gain in this case is using only n multiplications and
n + 1 additions compared to the usual 2n multiplications and n additions.
edited Sep 12 '14 at 11:13
You are overgeneralizing the problem here. The OP talks about a geometric series where the usage of
1xn
Horner's method is not needed as there exists a constant time solution a 1x . Nobody Sep 12 '14 at
11:21
Thanks, the reason why I use the formula is that it is the best answer I can figure out. I look through the
Internet and find your solution may be the better answer to above. It's a coding interview question, and I
don't know the proper solution yet. Michael Sep 12 '14 at 11:23
@Nobody While I understand your point, if that is the question it seems particularly trivial. Especially if you
consider $x^n$ to be constant time. Asking someone to write a computer program to compute a formula
seems hardly worth the question. I suppose for C you actually have to use a function. Still the function
double geom(double x,int n){ user52971 Sep 12 '14 at 11:55