[comp.lang.c] Exponentiation in C

karl@haddock.ISC.COM (Karl Heuer) (06/28/88)

In article <808@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
>In article <12784@apple.Apple.COM>, bgibbons@Apple.COM (Bill Gibbons) writes:
>>... raising a floating-point value to an integer (typed as integer) power is
>>always done with repeated multiplies (in about log2(exponent) time),

That's a strange comment to be posting to a C newsgroup.

>Apparently Bill missed the discussion a few months ago about exponentiation
>in C.  There was considerable disagreement about what should be done about
>the problem, and a rather large number of correspondents seemed unable to
>consider computing powers except by the pow(x,y) function, which does not
>use the reasonably quick and exact method.

Actually that's an implementation issue; as has been noted, a smart compiler
could generate a single integer multiply instruction for an expression like
"(int)pow((double)n, 2.0)".

However, until a substantial fraction of available compilers actually do such
an optimization, I'd rather write "n*n" (or, if the expression n is complex
enough, "temp=n" and "temp*temp").  Using pow() is a small win if the compiler
is smart, but a big lose if it isn't.

I've managed to convince myself that C should have a real power operator.  It
won't get into ANSI C-88.  (Unless it was added in the second public review,
which I doubt.  Was it even formally proposed?  I didn't have time to write a
formal comment on this issue.)  The next best thing is to try it out as a
non-standard extension.

Perhaps the FSF would be interested in adding this to gcc.  If someone mails
me the appropriate address, I'll send them my analysis and suggestions.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

bgibbons@Apple.COM (Bill Gibbons) (06/29/88)

In article <4778@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>In article <808@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
>>In article <12784@apple.Apple.COM>, bgibbons@Apple.COM (Bill Gibbons) writes:
>>>... raising a floating-point value to an integer (typed as integer) power is
>>>always done with repeated multiplies (in about log2(exponent) time),
>That's a strange comment to be posting to a C newsgroup.

Actually, I meant this from an algorithmic point of view: if the implementor
knows that the exponent is an integer (without checking, e.g. it was typed
that way) the library code should use repeated multiplies.  This is trivial to
do in C++ by overloading pow().  In C, you have to name the library routine
something else, of course.  Or, as has been noted, change the language.

Bill Gibbons
bgibbons@apple.apple.com (contractor)

gregory@ritcsh.UUCP (Gregory Conway) (07/01/88)

In article <4778@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) writes:
] In article <808@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
] >In article <12784@apple.Apple.COM>, bgibbons@Apple.COM (Bill Gibbons) writes:
] >>... raising a floating-point value to an integer (typed as integer) power is
] >>always done with repeated multiplies (in about log2(exponent) time),
] 
] That's a strange comment to be posting to a C newsgroup.
] 
] >Apparently Bill missed the discussion a few months ago about exponentiation
] >in C.  There was considerable disagreement about what should be done about
] >the problem, and a rather large number of correspondents seemed unable to
] >consider computing powers except by the pow(x,y) function, which does not
] >use the reasonably quick and exact method.


I'm still a little wet behind the ears where C is concerned, so (politely)
correct me if I'm wrong, but what's wrong with this:


		y = 3.0^2
		log (y) = log (3.0^2)
		log (y) = 2 * log(3.0)

		So......

		y = exp ((double)2 * log(3.0));

Mathematically, it should work.  I'm just not so sure that it will compile.
How about it??

 
-- 
   ==>  Gregory Conway @ Computer Science House, RIT, Rochester, New York  <==
"I never did write that love song, the words just never seemed to flow.
 Now sad in reflection, did I gaze through perfection, 
 and examine the shadows on the other side of morning."  - Marillion

cik@l.cc.purdue.edu.UUCP (07/01/88)

In article <3167@ritcsh.UUCP>, gregory@ritcsh.UUCP (Gregory Conway) writes:
> In article <4778@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) writes:
> ] In article <808@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
> ] >In article <12784@apple.Apple.COM>, bgibbons@Apple.COM (Bill Gibbons) writes:
> ] >>... raising a floating-point value to an integer (typed as integer) power is
> ] >>always done with repeated multiplies (in about log2(exponent) time),
> 
> I'm still a little wet behind the ears where C is concerned, so (politely)
> correct me if I'm wrong, but what's wrong with this:

 
> 		y = 3.0^2
> 		log (y) = log (3.0^2)
> 		log (y) = 2 * log(3.0)

> 		So......
> 
> 		y = exp ((double)2 * log(3.0));
> 
> Mathematically, it should work.  I'm just not so sure that it will compile.
> How about it??
> 
It will compile, and it will execute, and except for roundoff, it will give 
the right answer.  So why do I complain?

	y = 3.0^2

if properly compiled, takes 1 multiplication time.

 		y = exp ((double)2 * log(3.0));

takes 1 convert time, 2 function calls, two executions of transcendental
functions.  We are talking about 20-100 times as much execution time.
In addition, if instead we wanted

	n = 3^2

we would need two more convert times, and would the answer be 9 or 8?  I
do not know, and I cannot even guess.  If we want 3.0^2 to be an integer
in its floating point representation, we had better not use log and exp.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet

msf@prandtl.nas.nasa.gov.UUCP (07/01/88)

In article <3167@ritcsh.UUCP> gregory@ritcsh.UUCP (Gregory Conway) writes:
>I'm still a little wet behind the ears where C is concerned, so (politely)
>correct me if I'm wrong, but what's wrong with this:
>
>		y = 3.0^2
>		log (y) = log (3.0^2)
>		log (y) = 2 * log(3.0)
>
>		So......
>
>		y = exp ((double)2 * log(3.0));
>
>Mathematically, it should work.  I'm just not so sure that it will compile.
>How about it??

Well, it didn't compile.  After adding semicolons and a few other dew dads,
just to see what would come out, I got this:
main()
{
        union   {
                int     a;
                float   b;
        } y;

        y.b = 3.0;

        printf("%f\n", (float) (y.a ^ 2));
}

and the answer was 1077936130.000000.  I had to throw in the union 'cause
otherwise the compiler barfed on doing exclusive-or on a float.  :-)
		mike


Michael Fischbein                 msf@ames-nas.nas.nasa.gov
                                  ...!seismo!decuac!csmunix!icase!msf
These are my opinions and not necessarily official views of any
organization.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/02/88)

In article <820@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
>	n = 3^2

You guys must be talking about some other language than C.
That already has a meaning in C; it sets the contents of `n' to 1.