Velocity Reviews > exponentiation operator (lack of)

# exponentiation operator (lack of)

Keith Thompson
Guest
Posts: n/a

 12-23-2005
Jordan Abel <(E-Mail Removed)> writes:
> On 2005-12-23, jacob navia <(E-Mail Removed)> wrote:

[...]
>> The purported exponentiation operator would have to be dyadic:
>>
>> 10 ^^ 3 --> 1000

>
> it'd probably be **, but

If we were going to add an exponentiation operator to C, we couldn't
use "**" without breaking existing code. x**y already means x * *y.

It wouldn't have been entirely unreasonable to have a built-in
exponentiation operator in C. If it had been there from the
beginning, x**y wouldn't have been a problem; if you wanted x * *y,
you'd have to insert a space. It would provide some opportunities for
optimization that a function doesn't; for example, x**2 can be
translated to a simple multiplication, and x**16 can be implemented as
a sequence of 4 multiplications rather than 15. The right operand
could have been restricted to an integral value, leaving the pow()
function for a floating-point right operand. (A function whose second
argument has to be an integer could do most of the same optimizations.)

It wasn't done because it's not used all that much, because it's a
relatively higher-level operation than C's other built-in operators,
because C's original emphasis was systems programming rather than
mathematics, and because the designers of the language just
arbitrarily decided not to add it. I don't think the language has
particularly suffered from it. You can agree or disagree with the
decision, but we're stuck with it.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

jacob navia
Guest
Posts: n/a

 12-23-2005
Eric Sosman a écrit :
> jacob navia wrote:
>
>> [...]
>> The purported exponentiation operator would have to be dyadic:
>>
>> 10 ^^ 3 --> 1000
>>
>> This would be feasible but the problem is inserting it in
>> the precedence rules of C
>>
>> 10+4 ^^ 4+5 --> pow(14,9) ? or 10+pow(4,4)+5 ???
>>
>> There are enomous problems with this approach, and for exponentiation
>> I think it is just not worth the effort, unless we devise a general

>
>
> solved when I began programming thirty-nine years ago.

2**3**4
is an error in fortran. Should that be also the case in C?

2|3|4 is legal C... Should the operator ** be the same?
Besides, ** is not really good since it is easily mistaken with
multiply by the dereferenced pointre:

a**b is
(a)*(*b)
or
(a)**(b) ???

Etc etc. Once you start you will see it is NOT that easy.

> In
> FORTRAN the `**' operator means exponentiation, and binds more
> tightly than multiplication and division but less tightly than
> parentheses and function calls. Expressions in FORTRAN are
> structurally similar to those in C, and I'm confident a similar
> precedence rule could be worked out easily.
>

I am not.

> But perhaps I'm abusing you needlessly and owe an apology;
> you may be referring to the problems of adding user-defined
> operators on the fly and at the programmer's whim.

Well, not really by everyone but surely by the commitee.

> Those would
> indeed be "enomous" problems! But perhaps we need not generalize
> from a question about one obviously missing operator to the issue
> of accommodating every conceivable (and ill-conceived) operator
> a programmer's diseased mind can imagine. If you want APL, you
> know where to find it.
>

1)
We have operators that have hardware support but not operator
support in C:

char a = 200;
char b = 200;
char c = a |+| b; // c is 255 not 400%255. No 'wrap around'

There is now only the function call syntax to adapt that to
C:

2)
operator however). I use often APL concepts since it was a language
that I will never forget, like a jewel. Tiny but so perfect somehow.

jacob navia
Guest
Posts: n/a

 12-23-2005
Wow Chris, you know APL too!

How nice!

I will never forget that language. Small but powerful, with a
consistent and uniform way of expressing programs.

Yes, it had its drawbacks (like everything, there is nothing
perfect) but it was so advanced for its time!

jacob

Eric Sosman
Guest
Posts: n/a

 12-23-2005

jacob navia wrote On 12/23/05 14:34,:
> Eric Sosman a écrit :
>
>>jacob navia wrote:
>>
>>
>>>[...]
>>>The purported exponentiation operator would have to be dyadic:
>>>
>>>10 ^^ 3 --> 1000
>>>
>>>This would be feasible but the problem is inserting it in
>>>the precedence rules of C
>>>
>>>10+4 ^^ 4+5 --> pow(14,9) ? or 10+pow(4,4)+5 ???
>>>
>>>There are enomous problems with this approach, and for exponentiation
>>> I think it is just not worth the effort, unless we devise a general

>>
>>
>>solved when I began programming thirty-nine years ago.

>
>
> 2**3**4
> is an error in fortran. Should that be also the case in C?

It's been so long since I used FORTRAN that I don't
remember. If it were up to me, I'd say exponentiation
should be right-associative and let it go at that. It's
not up to me, though.

> 2|3|4 is legal C... Should the operator ** be the same?
> Besides, ** is not really good since it is easily mistaken with
> multiply by the dereferenced pointre:
>
> a**b is
> (a)*(*b)
> or
> (a)**(b) ???
>
> Etc etc. Once you start you will see it is NOT that easy.

This is just a question of spelling. Obviously you
can't grab ** or ^ or % to be C's exponentiation operator;
they're already taken for other purposes. # would almost
work, but there'd be niggling problems with line boundaries.
\$ would work, but there's a distaste for national characters.
Someone has already suggested ^^, and I think @ would also
be all right. The only question here is the choice of a
character combination that isn't already in use and has
some amount of mnemonic value. We could even do without
the mnemonic: nobody seems to complain about % even though
it's not very suggestive of "remainder."

> 1)
> We have operators that have hardware support but not operator
> support in C:
>
> char a = 200;
> char b = 200;
> char c = a |+| b; // c is 255 not 400%255. No 'wrap around'

The operator I miss even more than exponentiation is
"integer multiply producing double-width product." I've
only run into one non-assembly language that provided such
a thing; that language used * to get a 16-bit product from
two 16-bit integers and '*' (with the quotes) to get a 32-
bit product. Among other things, it gave a very easy way
to "pick a card, any card" with reasonable accuracy:

card = (rand() '*' 52) >> 16

(Please take this with a grain of salt; I remember the '*'
distinctly because it was both unusual and pleasant to have,
but I can't vouch for the spelling of the right-shift
operator or for the name of the pseudo-random source. Read
the idiom, not my idiocy.)

But this is the reverse of the O.P.'s question: he didn't
ask why there aren't operators for all the useful machine
instructions, but why there's no exponentiation operator.
When he says the FAQ offers an excuse rather than an answer
I'm inclined to agree with him. After all, C has no qualms
about requiring things like `long long' and `long double'
support even on 8-bit embedded toaster controllers; why be
just doesn't seem to hold a lot of water.

I think the "why not?" question can only be answered
by dmr himself. Anybody else is just speculating.

--
(E-Mail Removed)

Rouben Rostamian
Guest
Posts: n/a

 12-23-2005
In article <(E-Mail Removed)>,
Keith Thompson <(E-Mail Removed)> wrote:
>
>It wouldn't have been entirely unreasonable to have a built-in
>exponentiation operator in C. If it had been there from the
>beginning, x**y wouldn't have been a problem; if you wanted x * *y,
>you'd have to insert a space. It would provide some opportunities for
>optimization that a function doesn't; for example, x**2 can be
>translated to a simple multiplication, and x**16 can be implemented as
>a sequence of 4 multiplications rather than 15. The right operand
>could have been restricted to an integral value, leaving the pow()
>function for a floating-point right operand. (A function whose second
>argument has to be an integer could do most of the same optimizations.)

I completely agree with what you have written here.
Additionally, in my view the distinction between x**y and x * *y
would have been an ugly wart on the language but we would have
gotten used to it. Alas, it wasn't done that way.

>It wasn't done because it's not used all that much, because it's a
>relatively higher-level operation than C's other built-in operators,
>because C's original emphasis was systems programming rather than
>mathematics, and because the designers of the language just
>arbitrarily decided not to add it.

In the absence of a comment from DMR, these are probably as
plausible explanations as I can think of. I disagree, however,
with "It wasn't done because it's not used all that much".

Probably you meant to say "It wasn't done because it wasn't
used all that much in the early years of C". Otherwise that
statement sounds strange coming from someone from the San Diego
Supercomputer Center. I'll hazard a guess that the bulk of
the CPU time on your computers is spent on numerical analysis
and scientific computing where exponentiation operations
are pervasive.

--
Rouben Rostamian

Keith Thompson
Guest
Posts: n/a

 12-23-2005
jacob navia <(E-Mail Removed)> writes:
> Eric Sosman a écrit :
>> jacob navia wrote:
>>
>>> [...]
>>> The purported exponentiation operator would have to be dyadic:
>>>
>>> 10 ^^ 3 --> 1000
>>>
>>> This would be feasible but the problem is inserting it in
>>> the precedence rules of C
>>>
>>> 10+4 ^^ 4+5 --> pow(14,9) ? or 10+pow(4,4)+5 ???
>>>
>>> There are enomous problems with this approach, and for exponentiation
>>> I think it is just not worth the effort, unless we devise a general

>> solved when I began programming thirty-nine years ago.

>
> 2**3**4
> is an error in fortran. Should that be also the case in C?
>
> 2|3|4 is legal C... Should the operator ** be the same?
> Besides, ** is not really good since it is easily mistaken with
> multiply by the dereferenced pointre:
>
> a**b is
> (a)*(*b)
> or
> (a)**(b) ???
>
> Etc etc. Once you start you will see it is NOT that easy.

Sure it is.

Let's assume, hypothetically, that we want to add an exponentiation
operator to C. We can't use "**" because x**y already means x * *y.
We can't use "^" because it already means bitwise xor. So let's use
"^^" (since nobody is going to want a short-circuit xor). Or bite the
bullet and use "**", breaking existing code; since the right operand
can't be a pointer, any code that's broken will get a diagnostic and
the programmer can insert the space that should have been there in the
first place. (The latter probably wouldn't get past the committee,
even assuming they'd accept the whole idea in the first place.)

Add a new precedence level, just above the multiplication operators,
so "x*y^^z" means "x*(y^^z)". Update the grammar to reflect this.

There are three choices for associativity: it associates
left-to-right, it associates right-to-left, or it doesn't associate at
all (x^^y^^z is illegal). Pick one.

Either the right operand has to be an integer, making it equivalent to
repeated multiplication, or the right operand can be floating-point,
making it equivalent to pow() (or powf() or powl()). Pick one.

There are some arbitrary choices to be made, but I don't see what's so

I'm not advocating this, but anyone who thinks it's a good idea could
implement it as an extension in some existing compiler, providing the
existing practice that would make it more likely for the committee to
accept the idea.

The only thing preventing the addition of an exponentiation operator
to C is lack of interest. Defining the syntax and semantics is the
easy part.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Keith Thompson
Guest
Posts: n/a

 12-23-2005
(E-Mail Removed) (Rouben Rostamian) writes:
> In article <(E-Mail Removed)>,
> Keith Thompson <(E-Mail Removed)> wrote:

[...]
>>It wasn't done because it's not used all that much, because it's a
>>relatively higher-level operation than C's other built-in operators,
>>because C's original emphasis was systems programming rather than
>>mathematics, and because the designers of the language just
>>arbitrarily decided not to add it.

>
> In the absence of a comment from DMR, these are probably as
> plausible explanations as I can think of. I disagree, however,
> with "It wasn't done because it's not used all that much".
>
> Probably you meant to say "It wasn't done because it wasn't
> used all that much in the early years of C". Otherwise that
> statement sounds strange coming from someone from the San Diego
> Supercomputer Center. I'll hazard a guess that the bulk of
> the CPU time on your computers is spent on numerical analysis
> and scientific computing where exponentiation operations
> are pervasive.

And I think most of that code is written in Fortran, though some of it
is written in C.

In any case, the software running on the computers where I work is
hardly typical of C software in general. I suspect (without proof)
that most C software is system-level stuff that doesn't need
exponentiation. It's questionable whether the use of C in scientific
computing is significant enought to justify changing the language.

On the other hand, C99 did add complex arithmetic and the infamous
type-generic math macros, which I suppose refutes what I just wrote.

On the other other hand, the existence of the pow() function means
that an exponentiation operator really isn't necessary. Using
function-call notation may be slightly less convenient, but it does
neatly avoid the issues of precedence and associativity. An
equivalent function whose second argument is an integer might be nice,
but I haven't seen much demand for it.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Guest
Posts: n/a

 12-23-2005
> The FAQ points out a perfectly valid reason for omitting any sort
> of exponentiation operator. C is not alone among languages in
> doing this. Exponentiation is not the most prevalent of operators,
> and is normally a subroutine in almost any language.

Historically that is not quite correct. My first language was
Fortran IV, used for my PhD thesis at UCB. In the 70s I briefly used
Burroughs Algol (a derivative of Algol 60-6 and Gnu Pascal in the
80s. The exponentiation operators were **, ^ and **, respectively.
Those 3 languages were widely used in their heyday although
of course were not useful for low-level system programming.

Algol 60 is supposed to have influenced C indirectly,
but the ^ operator was renamed. As I noted, the lack is presently
felt in low-level numerical applications of C. These are
growing rapidly, especially in parallel & multicore processing.

One reason: the ability of C to interact closely with the hardware
and do resource management. This is critical in supercomputers.

Second reason: the "feed" end of the Fortran pipeline is emptying.
Example: our College of Engineering has not taught Fortran to
undergraduates since 1997 (why? industry feedback). Numerical
methods are taught to freshmen in C for low-level components
and Matlab for high level scripts. One of our PhD students joined
Mathworks two yrs ago, and she works primarily in C.

Giving this ongoing enlargement in the scope of C applications,
I see no reason why a new operator (** or ^^) could not be
introduced to meet those needs either in a future standard, or
in a "successor to C" , as discussed in another thread.
It should have a high precedence, just under the dot.

Jordan Abel
Guest
Posts: n/a

 12-23-2005
On 2005-12-23, jacob navia <(E-Mail Removed)> wrote:
> Eric Sosman a écrit :
>> jacob navia wrote:
>>
>>> [...]
>>> The purported exponentiation operator would have to be dyadic:
>>>
>>> 10 ^^ 3 --> 1000
>>>
>>> This would be feasible but the problem is inserting it in
>>> the precedence rules of C
>>>
>>> 10+4 ^^ 4+5 --> pow(14,9) ? or 10+pow(4,4)+5 ???
>>>
>>> There are enomous problems with this approach, and for exponentiation
>>> I think it is just not worth the effort, unless we devise a general

>>
>>
>> solved when I began programming thirty-nine years ago.

>
> 2**3**4
> is an error in fortran. Should that be also the case in C?
>
> 2|3|4 is legal C... Should the operator ** be the same?
> Besides, ** is not really good since it is easily mistaken with
> multiply by the dereferenced pointre:
>
> a**b is
> (a)*(*b)
> or
> (a)**(b) ???
>
> Etc etc. Once you start you will see it is NOT that easy.

As opposed to a--b being a-- b [a syntax error] rather than the valid
a-(-b)? That's an argument against adding it (silent change) but NOT an
argument for why it shouldn't exist. ++ and -- are both tokens, and //
introduces a comment.

Guest
Posts: n/a

 12-23-2005

18.*Keith ThompsonDec 23, 12:08*pm * show options
Newsgroups: comp.lang.c
From: Keith Thompson <(E-Mail Removed)> - Find messages by this author
Date: Fri, 23 Dec 2005 19:08:11 GMT
Local: Fri, Dec 23 2005 12:08*pm
Subject: Re: exponentiation operator (lack of)
original| Report Abuse

Jordan Abel <(E-Mail Removed)> writes:
> On 2005-12-23, jacob navia <(E-Mail Removed)> wrote:

[...]
>> The purported exponentiation operator would have to be dyadic:

>> 10 ^^ 3 *--> 1000

> it'd probably be **, but

If we were going to add an exponentiation operator to C, we couldn't
use "**" without breaking existing code. *x**y already means x * *y.

> It wouldn't have been entirely unreasonable to have a built-in
> exponentiation operator in C. *If it had been there from the
> beginning, x**y wouldn't have been a problem; if you wanted x * *y,
> you'd have to insert a space. *It would provide some opportunities for
> optimization that a function doesn't; for example, x**2 can be
> translated to a simple multiplication, and x**16 can be implemented as
> a sequence of 4 multiplications rather than 15. *The right operand
> could have been restricted to an integral value, leaving the pow()
> function for a floating-point right operand. *(A function whose second
> argument has to be an integer could do most of the same optimizations.)

Agree. Suppose for example that a naive programmer evaluates a
4-polynomial by writing (assuming ^^ as exp operator)

c = a0 + a1*x + a2*x^^2 + a3*x^^3 + a4*x^^4;

A clever compiler could analyze this and convert it to the Horner
scheme, using less than a dozen fp core registers.
With pow() the analysis and optimization might be more
problematic if the compiler worries about side effects.
Also IMO the purpose of the foregoing expression is
easier to visualize to somebody who didnt write the code.