power - novice

R

Roman Töngi

I just want to raise a number to a power.
e.g.:
16^2
The pow()-function of cmath seems to be not enough. I've read
about valarray. Is it really so difficult?
Can you give me an example.

Thanks Roman
 
T

Tim Love

Roman Töngi said:
I just want to raise a number to a power.
e.g.:
16^2
The pow()-function of cmath seems to be not enough.
In what way "not enough"? What went wrong?
I've read about valarray. Is it really so difficult?
Is this question related to the pow() one?
 
R

Roman Töngi

Tim Love said:
In what way "not enough"? What went wrong?

Is this question related to the pow() one?

I only know pow() of math.h.
Just tell me please the easiest way (for a beginner) how to raise for
example 16 to the power of 2.
 
V

Victor Bazarov

Roman said:
[..]
I only know pow() of math.h.

Should be enough for your purposes.
Just tell me please the easiest way (for a beginner) how to raise for
example 16 to the power of 2.

pow(16,2)

Is this a trick question? Didn't you just say that you *knew* 'pow'?
 
R

Richard Cavell

I just want to raise a number to a power.
e.g.:
16^2
The pow()-function of cmath seems to be not enough.

Could you do it manually? eg. 16*16. Or write a recursive function
that will do it for any arbitrary exponent.

And for powers of 2, how about using a shift function? 16 << 1.
 
V

Victor Bazarov

Richard said:
Could you do it manually? eg. 16*16. Or write a recursive function
that will do it for any arbitrary exponent.

And for powers of 2, how about using a shift function? 16 << 1.

You're confusing it with multiplying by a power of 2. 16 << 1 is 32.
16 * 16 is the same as 16 << 4.

V
 
E

Evan

I've got two problems with those that are weirdly sorta opposite each
other.

exponent.

I would recommend against recursion. A recursive algorithm, though it's
easy to do and understand, will be grossly inefficient for the problem.
An iterative one is just as easy:

template<typename T>
T exponentiate(T base, int exp)
{
T ret = 1;
for( ; exp>0 ; --exp)
ret *= base;
return ret;
}

It's very possible that your compiler will be able to convert your
recursive solution to an iterative one, but this is a fairly
substantial optimization at little cost, and do you really want to
trust that your compiler will recognize that this is optimizable? (I
just tried it under gcc under Solaris and I don't know enough Sun
assembly to know if it did.)
And for powers of 2, how about using a shift function? 16 << 1.

On the other hand, this seems like the sort of optimization that you
DON'T want to do. 16 << 1 is not that much faster than 16 * 2. Unless
you're doing it a whole lot or running in a very very very tight
environment it won't make any difference. Second, as much as it will
help, I will almost gurantee that the compiler is much more likely to
optimize 16 << 1 than it is to find tail recursion. This is the sort of
optimization that can probably be implemented even in debug builds.
Third, you've reduced readability. Maybe not much for something like 'x
= 16 << 1', but quick, what is the value of '3 << 1 + 1'? Is it 7 ('(3
<< 1) + 1') or 12 ('3 << (1+1)')? I bet you had to think about that
much more than 3 * 1 + 1. Oh, and it's a different answer. So you can't
just substitute '<<1' everywhere you see '*2'. (MSVC warns about it:
"warning C4554: '<<' : check operator precedence for possible error;
use parentheses to clarify precedence".)
 
V

Victor Bazarov

Evan said:
I've got two problems with those that are weirdly sorta opposite each
other.



I would recommend against recursion. A recursive algorithm, though
it's easy to do and understand, will be grossly inefficient for the
problem. An iterative one is just as easy:

template<typename T>
T exponentiate(T base, int exp)
{
T ret = 1;
for( ; exp>0 ; --exp)
ret *= base;
return ret;
}

Have you thought of

template<unsigned power, class T> T exponentiate(T base)
{
return base * exponentiate<power-1>(base);
}

template<> double exponentiate<1,double>(double d)
{
return d;
}

template<> int exponentiate<1>(int i)
{
return i;
}

? It could be even faster than your loop... Check this out:
--------------
template<unsigned power, class T> T exponentiate(T base)
{
return base * exponentiate<power-1>(base);
}

template<> double exponentiate<1,double>(double d)
{
return d;
}

template<> int exponentiate<1>(int i)
{
return i;
}

template<class T> T exponenti8(T d, unsigned p) {
T ret = 1;
for (; p > 0; p--)
ret *= d;
return ret;
}

#include <iostream>
#include <ctime>

int main()
{
double *d = new double[1000000];
std::clock_t t1 = clock();
for (int i = 0; i < 1000000; ++i)
d = exponentiate<64>(2.0 + 0.000001 * i);
std::clock_t t2 = clock();
for (int i = 0; i < 1000000; ++i)
d = exponenti8(2.0 + 0.000001 * i, 64);
std::clock_t t3 = clock();
delete[] d;

std::cout << t2-t1 << std::endl;
std::cout << t3-t2 << std::endl;
}
--------------
On my system it prints
187
563
--------------
which means templates are three times faster! That's the power of
inlining. Recursion rules, but only in compile-time. :)
It's very possible that your compiler will be able to convert your
recursive solution to an iterative one, but this is a fairly
substantial optimization at little cost, and do you really want to
trust that your compiler will recognize that this is optimizable? (I
just tried it under gcc under Solaris and I don't know enough Sun
assembly to know if it did.)
[...]

V
 
C

Chris Croughton

Roman said:
[..]
I only know pow() of math.h.

Should be enough for your purposes.
Just tell me please the easiest way (for a beginner) how to raise for
example 16 to the power of 2.

pow(16,2)

Is this a trick question? Didn't you just say that you *knew* 'pow'?

I get an error about ambiguous overloading of pow(), it's defined for

float, float
float, int
double, double
double, int
long double, long double
long double, int

(and if I include header <complex> for complex types as well) but not
for int, int.

Chris C
 
V

Victor Bazarov

Chris said:
Roman said:
[..]
I only know pow() of math.h.

Should be enough for your purposes.

Just tell me please the easiest way (for a beginner) how to raise for
example 16 to the power of 2.

pow(16,2)

Is this a trick question? Didn't you just say that you *knew* 'pow'?


I get an error about ambiguous overloading of pow(),

If you put a dot after 16, does it help?
 
R

Richard Cavell

On the other hand, this seems like the sort of optimization that you
DON'T want to do. 16 << 1 is not that much faster than 16 * 2. Unless
you're doing it a whole lot or running in a very very very tight
environment it won't make any difference.

For my purposes, 16 << 1 more closely describes what it is that my
algorithm is doing than 16 * 2.
"warning C4554: '<<' : check operator precedence for possible error;
use parentheses to clarify precedence".)

Yeah, the operator precedence is a trap. ( When I ( write ( C++
expressions ) ) I ( ( use parantheses ) everywhere ) because of this ).
 
C

Chris Croughton

Chris said:
Roman Töngi wrote:

[..]
I only know pow() of math.h.

Should be enough for your purposes.

Just tell me please the easiest way (for a beginner) how to raise for
example 16 to the power of 2.

pow(16,2)

Is this a trick question? Didn't you just say that you *knew* 'pow'?

I get an error about ambiguous overloading of pow(),

If you put a dot after 16, does it help?

Yup. My point was that pow(16, 2) will give errors, it's a "trick
answer".

(Why they didn't have pow(int, int) as well, I don't know. It seems a
pretty obvious thing to have if you have all of the floating point
versions and the lack of it is going to cause errors...)

Chris C
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,663
Latest member
josh5959

Latest Threads

Top