how to specify power of number

Y

Yanb

Hi, I'm new to c, so please excuse, if this is silly ;-)

I made a C function, which takes IP adress from string and converts to unsigned long int. Everything
works, but I found that the "counting" part part works only with this:

numericip=atoi(textip[0])*256*256*256+atoi(textip[1])*256*256+atoi(textip[2])*256+atoi(textip[3]);

When I wrote *(256^3), I got fake results. I'd like to use something more sophisticated, instead of 256*256
*256, which does look silly ;-) (Just curious, what if I'd ever need to make 100th power of 256 ;-) )

Thank you in advance.
 
B

Ben Bacarisse

Yanb said:
Hi, I'm new to c, so please excuse, if this is silly ;-)

Well, not silly, but I am surprised that you start a new language
without consulting some sort of reference.
I made a C function, which takes IP adress from string and converts to unsigned long int. Everything
works, but I found that the "counting" part part works only with this:

numericip=atoi(textip[0])*256*256*256+atoi(textip[1])*256*256+atoi(textip[2])*256+atoi(textip[3]);

When I wrote *(256^3), I got fake results. I'd like to use something
more sophisticated, instead of 256*256

^ is exclusive or in C. C does not have an exponentiation operator.
Most C programmers would use a shift (<<) by 24, 16 or 8 bits to
compute the value you want.
 
B

Bartc

Yanb said:
Hi, I'm new to c, so please excuse, if this is silly ;-)

I made a C function, which takes IP adress from string and converts to
unsigned long int. Everything
works, but I found that the "counting" part part works only with this:

numericip=atoi(textip[0])*256*256*256+atoi(textip[1])*256*256+atoi(textip[2])*256+atoi(textip[3]);

When I wrote *(256^3), I got fake results. I'd like to use something more
sophisticated, instead of 256*256
*256, which does look silly ;-) (Just curious, what if I'd ever need to
make 100th power of 256 ;-) )

You would have to use pow(256,3) which uses floating point arithmetic -- not
recommended, even though the compiler is likely to optimise.

Your code is fine as it is, the compiler will optimise 256*256*256 to
*16777216 or <<24. Or just write those in yourself.
 
A

Antoninus Twink

You would have to use pow(256,3) which uses floating point arithmetic -- not
recommended, even though the compiler is likely to optimise.

Your code is fine as it is, the compiler will optimise 256*256*256 to
*16777216 or <<24. Or just write those in yourself.

For general integer powers, a simple square-and-multiply algorithm is a
good bet, e.g.

unsigned long long power(unsigned a, unsigned b)
{
unsigned long long r, bit, pow;
for(bit=r=1, pow=a; bit<=b; bit<<=1, pow *= pow)
if(b & bit)
r*=pow;
return r;
}

The hardest part is checking for overflow - left as an exercise for the
reader...
 
Y

Yanb

Well, not silly, but I am surprised that you start a new language
without consulting some sort of reference.

Hi, and thank you for reply. I have read some very basics, but usually I need a language for a specific
thing and as soon as I know enough to complete the task, I leave learning till later :-/

Do you have some tip for a newbie where to start? Of course I can google out load of pages about c,
but no search engine can compete with reference from a human ;-)
I made a C function, which takes IP adress from string and converts
to unsigned long int. Everything works, but I found that the
"counting" part part works only with this:

numericip=atoi(textip[0])*256*256*256+atoi(textip[1])*256*256+atoi(tex
tip[2])*256+atoi(textip[3]);

When I wrote *(256^3), I got fake results. I'd like to use something
more sophisticated, instead of 256*256

^ is exclusive or in C. C does not have an exponentiation operator.
Most C programmers would use a shift (<<) by 24, 16 or 8 bits to
compute the value you want.

Oh yes, that's it, thanks, shifting I know shifts from php ;-) This way will need less cpu cycles than
multiplication.

Ok, so there no way to write mathematic "power of" in c?
 
J

Jens Thoms Toerring

Oh yes, that's it, thanks, shifting I know shifts from php ;-) This way
will need less cpu cycles than multiplication.

I wouldn't bet on that, a good compiler probably will "see" if
a multiplication can be replaced by a shift operation and will
use that if it's faster on the machine you're compiling for.
Ok, so there no way to write mathematic "power of" in c?

While there's no "power of" operator like for example in FORTRAN
there's the pow() function from the math part of the standard
C library, but which takes double arguments and returns a double.

Regards, Jens
 
Y

Yanb

For general integer powers, a simple square-and-multiply algorithm is
a good bet, e.g.

unsigned long long power(unsigned a, unsigned b)
{
unsigned long long r, bit, pow;
for(bit=r=1, pow=a; bit<=b; bit<<=1, pow *= pow)
if(b & bit)
r*=pow;
return r;
}

The hardest part is checking for overflow - left as an exercise for
the reader...

Thank you both. I must admit, that the code Is almost a mystery for me :)
 
Y

Yanb

(e-mail address removed) (Jens Thoms Toerring) wrote in
[snip]

Thank you for a good advices, Jens. Good to know it.
 
A

Antoninus Twink

Thank you both. I must admit, that the code Is almost a mystery for me :)

Well, it's overkill for exponents small enough not to overflow a
unit64_t, but the idea is this: naively, to raise a to the power b takes
b integer multiplies (a*a*...*a, b times). But actually, you can do this
using more like log(b) multiplies by repeatedly squaring to compute a^2,
a^4, a^8, ... and then multiplying those terms corresponding to
exponents of 2 that occur in the binary expansion of b. For example, if
b=7, then a^7 = a^(1+2+4) = a * a^2 * a^4.
 
U

user923005

Well, it's overkill for exponents small enough not to overflow a
unit64_t, but the idea is this: naively, to raise a to the power b takes
b integer multiplies (a*a*...*a, b times). But actually, you can do this
using more like log(b) multiplies by repeatedly squaring to compute a^2,
a^4, a^8, ...  and then multiplying those terms corresponding to
exponents of 2 that occur in the binary expansion of b. For example, if
b=7, then a^7 = a^(1+2+4) = a * a^2 * a^4.

If we look at his original post (and knowing he is just turning these
TCP/IP addresses into 4 byte integers):
"
numericip=atoi(textip[0])*256*256*256+atoi(textip[1])*256*256+atoi(textip[2­])*256+atoi(textip[3]);"

It could clearly be done as {assuming textip[] is an array of unsigned
char} as:
numericip = (unsigned long)textip[0] << 24 +
(unsigned long)textip[1] << 16 +
(unsigned long)textip[2] << 8 +
(unsigned long)textip[3] ;

Or {better yet} simply use inet_aton() {which is also fine for
Winsock, though WSAStringToAddress() is an alternative}. That is what
would be normally done to retrieve a TCP/IP address from a dotted
address string.

HOWEVER!

The OP should keep in mind that inet_aton() does NOT support IPv6 and
that getnameinfo() should be used instead for IPv4/v6 dual stack
support.

IMO-YMMV.

To the O.P.:
You can't go wrong with "Unix Network Programming" By W. Richard
Stevens (the same ideas work everywhere so don't be concerned if you
are doing Windows TCP/IP.

I don't know of any good reference works for IPv6 (I just use RFCs for
that).
 
A

Antoninus Twink

If we look at his original post (and knowing he is just turning these
TCP/IP addresses into 4 byte integers):
"
numericip=atoi(textip[0])*256*256*256+atoi(textip[1])*256*256+atoi(textip[2­])*256+atoi(textip[3]);"

It could clearly be done as {assuming textip[] is an array of unsigned
char} as:
numericip = (unsigned long)textip[0] << 24 +
(unsigned long)textip[1] << 16 +
(unsigned long)textip[2] << 8 +
(unsigned long)textip[3] ;

True, and someone had already suggested this. But the discussion
broadened, and someone claimed that using pow() was the best way to
raise integers to (positive) integer powers: it was this assertion that
I was responding to.
Or {better yet} simply use inet_aton() {which is also fine for
Winsock, though WSAStringToAddress() is an alternative}. That is what
would be normally done to retrieve a TCP/IP address from a dotted
address string.

HOWEVER!

The OP should keep in mind that inet_aton() does NOT support IPv6 and
that getnameinfo() should be used instead for IPv4/v6 dual stack
support.

Good advice.
To the O.P.:
You can't go wrong with "Unix Network Programming" By W. Richard
Stevens

Agreed.
 
T

Tim Prince

Because math coprocessors are awfully fast now, I guess that pow(2.0,k) is
nearly as fast as bit shifts and additions, but there is a bigger problem
with using pow(2,x) to find exact powers of 2. It should not be unexpected
for pow(2.0,24) to return 16777215.999999999 and if you assign that to an
integer, it probably won't be what is wanted unless you are clever enough to
round it -- ceil() won't help either because we might also have seen
16777215.0000001 or something like that. The Cephes collection of math
functions {for instance} uses a ratio of a cubic polynomial divided by a
quartic polynomial to form the approximation.

Likely, many implementations will actually recognize integral inputs (my C++
compiler definitely does this -- even sometimes complaining about ambiguity
over argument type) but there is no reason to expect that to happen.

It's almost obligatory for an implementation of pow() to special case
integral exponents, so as to handle negative operands, as well as provide
accuracy. I thought Cephes did this.
In case this doesn't happen, it doesn't seem too far fetched to specify
functions such as lrint(), supplying your own code if your position is
that C99 isn't portable enough.
 
U

user923005

It's almost obligatory for an implementation of pow() to special case
integral exponents, so as to handle negative operands, as well as provide
accuracy.  I thought Cephes did this.

I looked, it does.
In case this doesn't happen, it doesn't seem too far fetched to specify
functions such as lrint(), supplying your own code if your position is
that C99 isn't portable enough.

Of course if you just need a small power of 2, a shift will do
nicely. Even though most implementations will probably notice integer
values for both base and exponent, there is no requirement for them to
do that and not even a requirement to produce an answer within 1/2 ULP
of what is correct {though some compilers will try hard to do it}.
 
N

Nick Keighley

It could clearly be done as {assuming textip[] is an array of unsigned
char} as:
numericip = (unsigned long)textip[0] << 24 +
            (unsigned long)textip[1] << 16 +
            (unsigned long)textip[2] << 8 +
            (unsigned long)textip[3] ;

congratulations you have just hit C pitfall number 57.

<spoiler>

















just what is the precedence of +? and of <<?

write out 10,000,000 times.
"I must not mix logical and arithmetic operators"

And it was nice to see my compiler (Microsoft) issued a warning
for the code.
 
B

Bartc

Nick said:
It could clearly be done as {assuming textip[] is an array of
unsigned char} as:
numericip = (unsigned long)textip[0] << 24 +
(unsigned long)textip[1] << 16 +
(unsigned long)textip[2] << 8 +
(unsigned long)textip[3] ;

just what is the precedence of +? and of <<?

Given that << and >> are on a par with multiply and divide, what was the
reason for the silly choice of precendence?
 
N

Noob

[ Cross-posting to comp.unix.programmer and setting Followup-To ]
The OP should keep in mind that inet_aton() does NOT support IPv6
OK.

and that getnameinfo() should be used instead for IPv4/v6 dual
stack support.

inet_pton() seems more appropriate.

http://www.kernel.org/doc/man-pages/online/pages/man3/inet_pton.3.html

<quote>
This function converts the character string src into a network address
structure in the af address family, then copies the network address
structure to dst.
</quote>
 
U

user923005

It could clearly be done as {assuming textip[] is an array of unsigned
char} as:
numericip = (unsigned long)textip[0] << 24 +
            (unsigned long)textip[1] << 16 +
            (unsigned long)textip[2] << 8 +
            (unsigned long)textip[3] ;

congratulations you have just hit C pitfall number 57.

<spoiler>

just what is the precedence of +? and of <<?

write out 10,000,000 times.
"I must not mix logical and arithmetic operators"

And it was nice to see my compiler (Microsoft) issued a warning
for the code.

Should have been:
numericip = (unsigned long)textip[0] << 24 |
(unsigned long)textip[1] << 16 |
(unsigned long)textip[2] << 8 |
(unsigned long)textip[3] ;

which is how I would normally code it, but I thought the other
expression would be more clear. That's what I get for not checking.
 
L

lawrence.jones

Eric Sosman said:
The reference explains the peculiar precedence of &&,
but I see nothing about << and >> there. Have I missed
something? (Again?)

I don't think so. But I believe the precedence of << and >> is the same
as it was back in BCPL.

-Larry Jones

I've never seen a sled catch fire before. -- Hobbes
 

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,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top