[comp.lang.c] Power proposal for ANSI C -- we already have what we need

gnu@hoptoad.uucp (John Gilmore) (01/10/88)

I guess most people who are talking about problems with pow()
can't think like a (draft proposed) ANSI C compiler.

Suppose you have a dumb math library.  In <math.h> you put a declaration like:

	double pow(double, double);

and write the library routine, and you are done.  Now users can call
this routine with integers, floats, doubles, whatever, and it works,
because the function includes a prototype.  E.g.

	zap = pow(x, 2);

works, as does

	zap = pow(x, 2.0);
	oot = pow(x, 0.5);  etc...

Now suppose that you have a smart compiler and math library.  In
<math.h> you do:

	#define	pow	_compiler_pow

where _compiler_pow is recognized as a keyword by the compiler.  This
is a two-argument function built into the compiler -- it *knows* the
types of the operands, etc, just like any other built in primitive function,
like addition or multiplication or sizeof.  So if the user codes:

	zap = pow(x, 2);

it can easily see to multiply x by itself.  If you code

	zap = pow(x, 2.0);

it can *also* see to multiply x by itself (if your float representation
can't hold exact values of small integers, you are already in trouble).
If you code:

	oot = pow(x, .5);

then it can generate a square root instruction (ditto representation of .5).

And if you code

	whoknows = pow(x, y)

then it generates a subroutine call to the dumb library routine.

Does *anybody* have a problem with this???  I think it would be crazy
to change the standard for something like this.  Adding new multi-character
arithmetic operators to the language at the final stage of review?
Be serious.  We laughed at ( ), we roared at noalias, who would believe 
us if we overloaded ** to mean a crippled float/int-only exponentiation?
we already have one crippled math op (% doesn't work on floats, for no reason),
why add another?
-- 
{pyramid,ptsfa,amdahl,sun,ihnp4}!hoptoad!gnu			  gnu@toad.com
  I forsee a day when there are two kinds of C compilers: standard ones and 
  useful ones ... just like Pascal and Fortran.  Are we making progress yet?
	-- ASC:GUTHERY%slb-test.csnet

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/11/88)

In article <3812@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
>	double pow(double, double);
>...  Now users can call
>this routine with integers, floats, doubles, whatever, and it works,

No, it doesn't!  First, it evaluates to a double, which is not what
is wanted in many cases, but more importantly, it doesn't work at all
for some well-defined sets of integer operands.

However, the point about using a mapping onto a compiler intrinsic
to obtain optimization is important; this can be done for many
functions, including strcpy() etc. and many math-like functions,
depending on what the run-time code (as opposed to library)
environment will support.

blm@cxsea.UUCP (Brian Matthews) (01/12/88)

John Gilmore (gnu@hoptoad.uucp) writes:
|[Good reasons why function prototypes and a smart compiler make the
| pow function just fine...]
|Does *anybody* have a problem with this???  I think it would be crazy
|to change the standard for something like this.  Adding new multi-character
|arithmetic operators to the language at the final stage of review?
|Be serious.  We laughed at ( ), we roared at noalias, who would believe 
|us if we overloaded ** to mean a crippled float/int-only exponentiation?
|we already have one crippled math op (% doesn't work on floats, for no reason),
|why add another?

I'm sure somebody has a problem with this, but not me.  I would be in favor of
adding a power operator iff:

    1.  It works with both integral and floating point types, just
	like all of the other arithmetic operators (yes, expect %),

    2.  It followed the same rules in regards to type promotion as
	the other arithmetic operators, and

    3.  A syntax is proposed which doesn't break existing code or
	require the compiler to choose between two different meanings
	to a statement based upon the types of the operands.  This
	means ** and -> are both unacceptable.  I would also say ^^
	is unacceptable in the hopes of getting a boolean
	exclusive-or.

    4.  A corresponding op= operator was added (i.e. like +=, -=,
	etc.)

In other words, make the exponentiation operator look like part of
the language, instead of something hurriedly tacked on.  This is
especially true when there is already a good way of doing
exponentiation, as outlined by John in the article I quoted.

-- 
Brian L. Matthews                               "A power tool is not a toy.
...{mnetor,uw-beaver!ssc-vax}!cxsea!blm          Unix is a power tool."
+1 206 251 6811
Computer X Inc. - a division of Motorola New Enterprises

jk@hpfelg.HP.COM (John Kessenich) (01/12/88)

I agree that an exponentiation operator makes sense in 'C' for small
integer exponents for the many good reasons given elsewhere, and
support its addition (but not if it means more delay).

Also, its precedence obviously belongs somewhere between that of 
(not inclusive) unary operators and punctuation operators.

But, since exponentiation is not associative, order of evaluation is also 
important (what is (x ** 2 ** 3) ?).

I propose the more mathematically correct interpretation of right to
left (as in assignment), not the normal left to right (used for most
operators).  That is,

                                      3
                                    2                       8            6
     x ** 2 ** 3       means      x        which equals   x      not   x


thus x ** 2 ** 3 is interpreted as x ** (2 ** 3).


By the way, if *^ is adopted for exponents, why not /^ for roots?
(don't take this too seriously :-) ).

---------------

John Kessenich

ericb@athertn.Atherton.COM (Eric Black) (01/12/88)

In article <3812@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
>I guess most people who are talking about problems with pow()
>can't think like a (draft proposed) ANSI C compiler.
>
>Suppose you have a dumb math library.  In <math.h> you put a declaration like:
>
>	double pow(double, double);
>[...]
>Now suppose that you have a smart compiler and math library.  In
><math.h> you do:
>
>	#define	pow	_compiler_pow
>
>where _compiler_pow is recognized as a keyword by the compiler.
>[...]
>Does *anybody* have a problem with this???

Seems to work as far as it goes...
Your solution still requires the arguments to first be promoted to double,
and the return result converted from double to whatever.  I have done
graphics and number crunching where that conversion both ways is
not desired (float precision is adequate) and it takes an unacceptable
performance hit.

In fact, on some systems (e.g. PR1ME/PRIMOS) a common practice is to
use a kludgey compiler "private keyword" to tell the compiler it's
making an inter-language call (in PRIMOS C it's the modifier "fortran",
of all things!) to avoid this promotion to double, and write the called
routine in FORTRAN *just so it doesn't expect its incoming arguments to
be double*, even though they are declared as float (because C requires
them to be promoted to double on the way in, you see...).

Now, in the first instance above, it is clear that the arguments MUST
be converted to double.  In the second (the builtin), I suppose the
compiler could somehow be told (a #pragma?) not to do that, but
that's really wierd and unexpected behavior.

I suppose that means I really don't have a problem with your proposed
solution, John, because this is a built-in (!) problem with C as it is,
and your solution really doesn't address my problem any less than C
does now.

Is there a provision I haven't seen that solves my problem?  If so, then
"Never mind!".  If not, I'd much prefer that it be added than any
built-in power operator.
-- 
Eric Black	"Garbage in, Gospel out"
   UUCP:	{sun!sunncal,hpda}!athertn!ericb
   Domainist:	ericb@Atherton.COM

decot@hpisod2.HP.COM (Dave Decot) (01/19/88)

Nobody has addressed the idea of using %% as the power operator.

It would not conflict with any other possible extension that anyone has
mentioned, and is not riskier syntax than any other.

Dave Decot
hpda!decot

jk@hpfelg.HP.COM (John Kessenich) (02/02/88)

    I have thought about using macros for squaring expressions, and problem
    is that they *do* require a temp.  This makes it impossible to do the
    following:

        #define SQR(exp) ????

        x = y + z * SQR(a+b);

    Either a temp must be available so one can write

        #define SQR(exp) (t=(exp), t*t)

    Or one must write

	#define SQR(x,exp) {int t; t=(exp); x = t*t;}

    which cannot be used in expressions.

    Conclusion? there is not a good substitute for a real power operator.
    (This does not mean there should be a power operator. :-)

---------------
John Kessenich