By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,838 Members | 1,675 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,838 IT Pros & Developers. It's quick & easy.

exponentiation operator (lack of)

P: n/a
Curious:
Why wasnt a primitive exponentiation operator not added to C99?
And, are there requests to do so in the next std revision?

Justification for doing so:
C and C++ are increasingly used in low-level
numerical computations, replacing Fortran in newer projects.
Check, for example, sourceforge.net or freshmeat.net

But neither language offers a primitive exp operator.
^ is exclusive OR, which is much less common in numerical
programs than exponentiation. However, ^^ is open.

Dec 22 '05 #1
Share this Question
Share on Google+
67 Replies


P: n/a
ca****@colorado.edu wrote:
Curious:
Why wasnt a primitive exponentiation operator not added to C99?


You should read the FAQ before posting, this is answered in question
14.7, see http://www.eskimo.com/~scs/C-faq/q14.7.html for the answer.

Robert Gamble

Dec 22 '05 #2

P: n/a
That is not an answer, just an excuse. It links language operators to
presence or absence of hardware. C is not assembly language.
Translation is the job of something called a compiler.

Dec 22 '05 #3

P: n/a
ca****@colorado.edu wrote:
That is not an answer, just an excuse. It links language operators to
presence or absence of hardware. C is not assembly language.
Translation is the job of something called a compiler.

1) You have failed to quote sufficient context -- for which Google's
broken Usenet interface is no excuse.
2) You were directed to an answer -- in the FAQ, which you should have
read *before* asking your original question.
3) This newsgroup is primarily concerned with the ISO C language as it
*is*. If you want it to be different, the proper place for such
discussions is news:comp.std.c.

Further, I recommend you do some reading on the history of the C
language, why it was created, what was its intended purpose, etc. That
may provide insight into the design decisions made.

HTH,
--ag

--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"
Dec 22 '05 #4

P: n/a
ca****@colorado.edu wrote:
C is not assembly language.


Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want).

Dec 22 '05 #5

P: n/a
sl*******@yahoo.com a écrit :
ca****@colorado.edu wrote:
C is not assembly language.

Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want).


This is the old story supported by many people around here.

C is dead and everybody should move to the "higher" level, C++.

This justifies trying to deny C any evolution possibilities, and
keeping the discussion in this group as "low level" as
possible.

The OP question is a good one. Personally I do not think we need a new
exponentiation operator, and in lcc-win32 there is operator overloading,
but those are not answers to the OP question.

May I remind you that the supposedly "higher" level C++ doesn't
have an exponentiation operator EITHER ???

I think the answer is that the enormous problem of introducing a
new operator, with all the complications of the 15 levels of
precedence of C makes the introduction of an ^^ operator an
herculean task, one that nobody has attempted, and probably never
will.

Let's stop the nonsense and tell the truth for one.

jacob

Dec 23 '05 #6

P: n/a
> Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want)


Absolutely correct, but C++ does not have an exponentiation operator
to overload. I might be off base here since I use C++ very little,
but I dont think pow(..) is in the "overloadable" list.

As regards gradual departure of C from assembly, let me note that
C99 offers a built-in complex type and associated operators.
Those are not part of any widely used assembly language
instruction set, although they can be microcoded in some
embedded systems.

Dec 23 '05 #7

P: n/a
"sl*******@yahoo.com" writes:
Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want).


This exposes one of the frailties of C++. The natural exponentiation
operator, ^, has the precedence of exclusive or, which is far too low for
the operation desired. Overloading it would be a disaster waiting to
happen. You would have parens all over the place and if you forgot one
there would probably be hell to pay in faulty results.
Dec 23 '05 #8

P: n/a
jacob navia wrote:
sl*******@yahoo.com a écrit :
ca****@colorado.edu wrote:
C is not assembly language.

Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want).

<snip>

May I remind you that the supposedly "higher" level C++ doesn't
have an exponentiation operator EITHER ???


The OP I was replying to did not mention anything about exponentiation
operator. He just said operators are linked to what is available in
assembly.

Dec 23 '05 #9

P: n/a
On 2005-12-23, ca****@colorado.edu <ca****@colorado.edu> wrote:
Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want)


Absolutely correct, but C++ does not have an exponentiation operator
to overload. I might be off base here since I use C++ very little,
but I dont think pow(..) is in the "overloadable" list.


I believe functions can also be overloaded.
Dec 23 '05 #10

P: n/a
Jordan Abel a écrit :
On 2005-12-23, ca****@colorado.edu <ca****@colorado.edu> wrote:
Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want)


Absolutely correct, but C++ does not have an exponentiation operator
to overload. I might be off base here since I use C++ very little,
but I dont think pow(..) is in the "overloadable" list.

I believe functions can also be overloaded.


What's the use of overloading a function here?

I mean would you overload pow() ???

What's the point?

A function (overloaded or not) is not an operator!
Dec 23 '05 #11

P: n/a
sl*******@yahoo.com a écrit :

The OP I was replying to did not mention anything about exponentiation
operator. He just said operators are linked to what is available in
assembly.


God you are totally confused!!!

1) The OP (see the TITLE of this thread) asked why there isn't
an exponentiation operator in C.
2) He was redirected to the FAQ that says that there isn't since there
is no hardware support for that operator. It is the FAQ that says
it, not the OP.
3) The OP critized the FAQ, saying (rightly so in my opinion) that
C is not tied to hardware.

You mess completely!

jacob
Dec 23 '05 #12

P: n/a
osmium a écrit :
"sl*******@yahoo.com" writes:

Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want).

This exposes one of the frailties of C++. The natural exponentiation
operator, ^, has the precedence of exclusive or, which is far too low for
the operation desired. Overloading it would be a disaster waiting to
happen. You would have parens all over the place and if you forgot one
there would probably be hell to pay in faulty results.


And we come to the point that I mentioned elsethread:

The 15 levels of precedence of C are so messy that nobody
has had the time to devote a man year to find out how
an exponentiation operator could be implemented.

Dec 23 '05 #13

P: n/a
jacob navia said:

<snip>
A function (overloaded or not) is not an operator!


Actually, they're not all /that/ different, conceptually speaking. One can
think of qsort as the "sort" operator, strcmp as the "string comparison"
operator, foo as the "do the foo thing" operator, and so on. A function is
just God's way of letting us specify our own operators that can do whatever
we have the skill and imagination to write.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Dec 23 '05 #14

P: n/a
Richard Heathfield a écrit :
jacob navia said:

<snip>
A function (overloaded or not) is not an operator!

Actually, they're not all /that/ different, conceptually speaking. One can
think of qsort as the "sort" operator, strcmp as the "string comparison"
operator, foo as the "do the foo thing" operator, and so on. A function is
just God's way of letting us specify our own operators that can do whatever
we have the skill and imagination to write.


Granted, both operator overloading and function calls are the
same. The difference is syntax. In a function call even
if the function is overloaded you have a monadic (single
argument operator)

FUNCTION '(' arguments ... ')'

An operator can be monadic like above:
! arguments of the NOT operator
or DYADIC

arguments operator arguments

like

2 + 3

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
rule about adding new operators.

Dec 23 '05 #15

P: n/a
On 2005-12-23, jacob navia <ja***@jacob.remcomp.fr> wrote:
Richard Heathfield a écrit :
jacob navia said:

<snip>
A function (overloaded or not) is not an operator!

Actually, they're not all /that/ different, conceptually speaking. One can
think of qsort as the "sort" operator, strcmp as the "string comparison"
operator, foo as the "do the foo thing" operator, and so on. A function is
just God's way of letting us specify our own operators that can do whatever
we have the skill and imagination to write.


Granted, both operator overloading and function calls are the
same. The difference is syntax. In a function call even
if the function is overloaded you have a monadic (single
argument operator)


You don't seem to see the distinction between overloading a function and
overloading the function-call operator.
FUNCTION '(' arguments ... ')'

An operator can be monadic like above:
! arguments of the NOT operator
or DYADIC

arguments operator arguments

like

2 + 3

The purported exponentiation operator would have to be dyadic:

10 ^^ 3 --> 1000
it'd probably be **, but
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
rule about adding new operators.


Nobody suggested adding a new operator - only overloading pow().
Dec 23 '05 #16

P: n/a
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
rule about adding new operators.


The "enomous [sic] problems" you mention had already been
solved when I began programming thirty-nine years ago. 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.

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. 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. ;-)

--
Eric Sosman
es*****@acm-dot-org.invalid
Dec 23 '05 #17

P: n/a
jacob navia wrote:
sl*******@yahoo.com a écrit :

The OP I was replying to did not mention anything about
exponentiation operator. He just said operators are linked to
what is available in assembly.


God you are totally confused!!!

1) The OP (see the TITLE of this thread) asked why there isn't
an exponentiation operator in C. 2) He was redirected to the FAQ
that says that there isn't since there is no hardware support
for that operator. It is the FAQ that says it, not the OP. 3)
The OP critized the FAQ, saying (rightly so in my opinion) that
C is not tied to hardware.


No, you are. Based on the context included in the various
messages, only your point 1) is valid. The rest was not quoted,
and thus not necessarily available to Mr. Slebetman.

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.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html

Dec 23 '05 #18

P: n/a
In article <RY********************@comcast.com>
Eric Sosman <es*****@acm-dot-org.invalid> wrote:
... In FORTRAN the `**' operator means exponentiation, and binds more
tightly than multiplication and division but less tightly than
parentheses and function calls.
(And, if I recall correctly, is non-associative as well: A**B**C
is an error.)
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. Those would
indeed be "enomous" problems!
Although these, too, have been solved (for some definition of
"solved" anyway) in other languages.
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. ;-)


It, I think, is worth noting that APL -- a language designed by a
mathematician -- avoids the whole operator binding ("precedence
and associativity") problem by defining it away. Operators are
handled strictly in textual order, right to left. For instance,

* 3 + 4 (iota) 7

is handled as:

iota 7: produces the vector 1 2 3 4 5 6 7
+ 4 [vector]: produces the vector 5 6 7 8 9 10 11
* 3 [vector]: produces the vector 15 18 21 24 27 30 33

Also, as I think someone else mentioned in this thread, APL provides
sort operators (grade-up, which sorts into ascending order, and
grade-down, which sorts into descending order).

If you write pure functions (or ignore possible control flow and
"global variable" problems due to errors), the difference between
"function" and "operator" is mere syntax. A good programmer should
be comfortable with all three of these:

(* 2 (+ 3 4)) # functions, e.g., Lisp
2 3 4 + * # RPN, e.g., PostScript, FORTH
2 * 3 + 4 # "conventional" infix

This does not mean you cannot *prefer* one form over another (even
Lisp programmers write fancy macros), but there is no significant
difference. The spelling does not matter as much as the semantics.
Note that, on some machines (V7-and-earlier SPARC for instance):

int i, j, result;
...
result = i * j;

compiles to a subroutine call ("call .mul"), rather than a multiply
instruction, and:

size_t size;
size = sizeof(i);

compiles to a simple assignment, despite "sizeof(i)"'s resemblance
to a call to a function.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Dec 23 '05 #19

P: n/a
jacob navia wrote:
sl*******@yahoo.com a écrit :

The OP I was replying to did not mention anything about exponentiation
operator. He just said operators are linked to what is available in
assembly.

God you are totally confused!!!

1) The OP (see the TITLE of this thread) asked why there isn't
an exponentiation operator in C.
2) He was redirected to the FAQ that says that there isn't since there
is no hardware support for that operator. It is the FAQ that says
it, not the OP.
3) The OP critized the FAQ, saying (rightly so in my opinion) that
C is not tied to hardware.

You mess completely!


OK, here's the OP's complete post:
That is not an answer, just an excuse. It links language operators to
presence or absence of hardware. C is not assembly language.
Translation is the job of something called a compiler.


Apart from the title, where is the mention of the FAQ? Where is the
quote of the reply the OP was critisizing?

Dec 23 '05 #20

P: n/a
Jordan Abel <jm****@purdue.edu> writes:
On 2005-12-23, jacob navia <ja***@jacob.remcomp.fr> 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) ks***@mib.org <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.
Dec 23 '05 #21

P: n/a
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
rule about adding new operators.

The "enomous [sic] problems" you mention had already been
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:

char c = ClampedAdd(a,b,255);

2)
APL did NOT allow for operator overloading, (it had an exponentiation
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.
Dec 23 '05 #22

P: n/a
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
Dec 23 '05 #23

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> 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
Dec 23 '05 #24

P: n/a


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
rule about adding new operators.

The "enomous [sic] problems" you mention had already been
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
squeamish about requiring exponentiation? The FAQ's answer
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.

--
Er*********@sun.com

Dec 23 '05 #25

P: n/a
jacob navia <ja***@jacob.remcomp.fr> 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
rule about adding new operators.

The "enomous [sic] problems" you mention had already been
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
difficult about it.

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) ks***@mib.org <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.
Dec 23 '05 #26

P: n/a
ro****@pc18.math.umbc.edu (Rouben Rostamian) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> 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) ks***@mib.org <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.
Dec 23 '05 #27

P: n/a
> 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-68) 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.

Dec 23 '05 #28

P: n/a
On 2005-12-23, jacob navia <ja***@jacob.remcomp.fr> 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
rule about adding new operators.

The "enomous [sic] problems" you mention had already been
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.
Dec 23 '05 #29

P: n/a

18.*Keith ThompsonDec 23, 12:08*pm * show options
Newsgroups: comp.lang.c
From: Keith Thompson <k...@mib.org> - 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)
Reply |Reply to Author| Forward| Print| Individual Message| Show
original| Report Abuse
Jordan Abel <jma...@purdue.edu> writes:
On 2005-12-23, jacob navia <j...@jacob.remcomp.fr> 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.

Dec 23 '05 #30

P: n/a
In article <11**********************@g44g2000cwa.googlegroups .com>,
ca****@colorado.edu wrote:
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.


To be honest, anyone writing x**y would only get what they deserve if
their code is broken. Now if you can come up with an example where the
character sequence ** would change its meaning and still compile...

(I am assuming that number ** pointer would be an error that the
compiler has to catch).
Dec 23 '05 #31

P: n/a
Eric Sosman <er*********@sun.com> wrote:

The operator I miss even more than exponentiation is
"integer multiply producing double-width product."


The operator is "*". It's fairly simple for a compiler to recognize:

int i, j;
long l;
...
l = (long)i * j;

and avoid the needless widening of i and j.

-Larry Jones

Fortunately, that was our plan from the start. -- Calvin
Dec 23 '05 #32

P: n/a
Keith Thompson <ks***@mib.org> 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.


There's nothing preventing a compiler from optimizing calls to the pow()
function the same way.

-Larry Jones

I don't think math is a science, I think it's a religion. -- Calvin
Dec 23 '05 #33

P: n/a
ca****@colorado.edu writes:
18.Keith ThompsonDec 23, 12:08pm show options
Newsgroups: comp.lang.c
From: Keith Thompson <k...@mib.org> - Find messages by this author
Date: Fri, 23 Dec 2005 19:08:11 GMT
Local: Fri, Dec 23 2005 12:08pm
Subject: Re: exponentiation operator (lack of)
Reply |Reply to Author| Forward| Print| Individual Message| Show
original| Report Abuse

[snip]

Thank you for trying to quote using the broken Google interface, but
there's a much better way to do it.

See <http://cfaj.freeshell.org/google/>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Dec 23 '05 #34

P: n/a
la************@ugs.com writes:
Keith Thompson <ks***@mib.org> 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.


There's nothing preventing a compiler from optimizing calls to the pow()
function the same way.


It's slightly more difficult, since both arguments of pow() are
floating-point. The compiler would have to recognize that the second
argument is an integer; in that case, rather than converting it to
double, it would replace the call with code to do repeated
multiplication or whatever is most efficient, or perhaps just a call
to another function that takes an integer as its second argument.

It's certainly feasible, but I don't know whether any compilers do
this. If exponentiation were a built-in operator, I think compiler
writers would have been more strongly motivated to optimize it along
with expression evaluation in general.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Dec 23 '05 #35

P: n/a
On Fri, 23 Dec 2005 10:55:33 +0100, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.fr> wrote:
The 15 levels of precedence of C are so messy that nobody
has had the time to devote a man year to find out how
an exponentiation operator could be implemented.


Well, frankly this is nonsense. Why do you not post sensible things?
Is it some sort of fetish?

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Dec 24 '05 #36

P: n/a
On 22 Dec 2005 11:02:43 -0800, in comp.lang.c , ca****@colorado.edu
wrote:
That is not an answer, just an excuse.
So?There are lots of mathematical operators that C doesn't define, and
if you look closely, you'll notice that pretty much all of them are
ones you don't find hardware support for except in specialist math
chips. There are also missing operators for 'obvious' things like
addings two strings, adding two arrays, multiplying two matrices etc.
And why isn't there a dot-product operator and a cross-product
operator? I'm sure physicists would find them handy.
C is not assembly language.


Read a history book... :-)

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Dec 24 '05 #37

P: n/a
Mark McIntyre a écrit :
On 22 Dec 2005 11:02:43 -0800, in comp.lang.c , ca****@colorado.edu
wrote:
C is not assembly language.

Read a history book... :-)


Well, frankly this is nonsense. Why do you not post sensible things?
Is it some sort of fetish?
Dec 24 '05 #38

P: n/a
"jacob navia" <ja***@jacob.remcomp.fr> wrote in message
news:43***********************@news.wanadoo.fr...
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 ???


Obviously exponentiation has to have a higher priority than +,-,* or /,
because that's the case with algebra.

And perhaps evaluated right-to-left too, so 10**10**2 is 10**(10**2).

Ideally a superscript would be used, but I can see that has certain
difficulties. With ** ambiguous and ^ taken, ^^ is a good alternative,
although I don't see why an operator has to be a symbol, why not:

10 + 4 pow 4 + 5 ?

What about using ^ as exponentiation operator when either operand is float?

Bart

Dec 24 '05 #39

P: n/a
On 22 Dec 2005 10:39:06 -0800, ca****@colorado.edu wrote in
comp.lang.c:
Curious:
Why wasnt a primitive exponentiation operator not added to C99?
There is one. It's named pow(). How is pow(x, y) any more or less
primitive than x ** y?
And, are there requests to do so in the next std revision?
No, we already have pow(), and it does what we need.
Justification for doing so:
C and C++ are increasingly used in low-level
numerical computations, replacing Fortran in newer projects.
Check, for example, sourceforge.net or freshmeat.net
What C++ does or does not do is not relevant here.

What do you think happens when you use the exponentiation operator in
Fortran or Pascal? Perhaps on a very few hardware architectures a
short sequence of floating point unit instructions are added in line.
On most others, a run time support library routine is called.

Nothing at all prevents a C compiler for appropriate architectures to
make the function intrinsic and generate the same in line.
But neither language offers a primitive exp operator.
^ is exclusive OR, which is much less common in numerical
programs than exponentiation. However, ^^ is open.


So what?

By the way, the place to propose new features to the language or the
standard library is news:comp.std.c, not here.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Dec 24 '05 #40

P: n/a
On 22 Dec 2005 15:35:38 -0800, "sl*******@yahoo.com"
<sl*******@gmail.com> wrote in comp.lang.c:
ca****@colorado.edu wrote:
C is not assembly language.


Some people would beg to differ. C evolved from B which was merely a
very high level macro assembler. C itself was developed primarily as
replacement of assembly - a better way to write low level system
software. You want something higher level, try C++ (there you can
overload whatever operater you want).


People are entitled to their own opinions, no matter how wrong they
are, so they can differ all they want. And beg all they want, for
that matter.

As someone who has been fluent in many, many assembly languages over
the years, I am qualified to say that those who refer to C as "a high
level assembler" are generally trying to deprecate the language. And
they are wrong.

C is vastly superior to most assembly languages in many ways, and
certainly inferior to most of them in other ways.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Dec 24 '05 #41

P: n/a

"Keith Thompson" <ks***@mib.org> wrote
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.

I'd go for the first.
That way you can write x^^-1 and get a division for the cost of a single
multiplication.
Dec 24 '05 #42

P: n/a
On Sat, 24 Dec 2005 02:21:37 +0100, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.fr> wrote:
Mark McIntyre a écrit :
On 22 Dec 2005 11:02:43 -0800, in comp.lang.c , ca****@colorado.edu
wrote:
C is not assembly language.

Read a history book... :-)


Well, frankly this is nonsense. Why do you not post sensible things?
Is it some sort of fetish?


Echoing other peoples posts is pretty childish don't you think?

And do you deny that C was designed to be 'close to the metal' ?

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Dec 24 '05 #43

P: n/a
ca****@colorado.edu wrote:
Curious:
Why wasnt a primitive exponentiation operator not added to C99?
And, are there requests to do so in the next std revision?

Justification for doing so:
C and C++ are increasingly used in low-level
numerical computations, replacing Fortran in newer projects.
Check, for example, sourceforge.net or freshmeat.net

But neither language offers a primitive exp operator.
^ is exclusive OR, which is much less common in numerical
programs than exponentiation. However, ^^ is open.


I tend to use log() a lot and exp(). And they are extremely useful to
engineers. Should that be implemented too using some kind of a primitive
operator? Different people use different operators, actions, functions
or whatever. Even complex.h is too much...

One could easily write a new function that replaces pow() in his own
projects (either simple or aimed to super-computers and extreme
computations) that has the proper assembly calls for his system. And
that would be a more elegant solution.

If you want simplicity and ease of coding, use pow(). Else write our own
exponentiation function.

PS ...and although XOR is not usual in numerical computation, it's not
unusual in low-level programming and systems programming, for which C
was initially implemented.
Dec 24 '05 #44

P: n/a
Mark McIntyre a écrit :
And do you deny that C was designed to be 'close to the metal' ?

No, but it is surely NOT assembly language, and it is not determined
by hardware considerations.

The OP sentence:
C is not assembly language


is perfectly true.

You answer:

"Read a history book"

what implies that you would contest that affirmation, what is
surely nonsense. C is NOT assembly language, either from
the syntax (completely different) or the semantics (C handles
concepts like structures, local variables, etc etc).

Of course C is close to the basic hardware, closer than many
other languages maybe, but that surely doesn't make it
"assembly language" !

Of course *all* languages are assembly language in the
sense that eventually they must be translated into some
machine instructions to run, but then, you can say that
Smalltalk is assembly language too.

I stay with my critic: C is not assembly language.

jacob
Dec 24 '05 #45

P: n/a
Jack Klein a écrit :

[snip]
As someone who has been fluent in many, many assembly languages over
the years, I am qualified to say that those who refer to C as "a high
level assembler" are generally trying to deprecate the language. And
they are wrong.

C is vastly superior to most assembly languages in many ways, and
certainly inferior to most of them in other ways.


I would like to underline this. I think the idea of C as a
"High level assembler" was introduced by Betrand Meyer, with
his language Eiffel.

B.M. was too lazy to make a direct Eiffel-->assembler compiler,
and used C to implement Eiffel. (As many other languages do).

This allowed Eiffel to be written without much effort, but
produced other problems, since, for instance, they could not
detect integer overflow... Yes, C is certainly inferior to
many assemblers in some ways!!!

Dec 24 '05 #46

P: n/a
jacob navia wrote:
Eric Sosman a écrit :
jacob navia wrote:

The "enomous [sic] problems" you mention had already been
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?


Which is why, IMHO, I think the current pow() function is better:

pow(2,pow(3,4));

In fact, it even avoids confusion with:

pow(pow(2,3),4);

Dec 24 '05 #47

P: n/a
Keith Thompson wrote:
jacob navia <ja***@jacob.remcomp.fr> 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
rule about adding new operators.
The "enomous [sic] problems" you mention had already been
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.


<snip>

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.


Of course, in C++ you'd overload pow() with a pow(double, int) so that
if you supply an int as the right integer it will do the repeated
multiplication thing. I'd even overload it again with pow(int, int) for
cases where I want to avoid conversion problems. For C, powl() looks
like a good idea.

Dec 24 '05 #48

P: n/a
On Sat, 24 Dec 2005 13:19:34 +0100, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.fr> wrote:
Mark McIntyre a écrit :
And do you deny that C was designed to be 'close to the metal' ?

No, but it is surely NOT assembly language, and it is not determined
by hardware considerations.


But it is.
I stay with my critic: C is not assembly language.


I never said it was. I said "read a history book".

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Dec 24 '05 #49

P: n/a
Keith Thompson <ks***@mib.org> wrote [quoting me]:
There's nothing preventing a compiler from optimizing calls to the pow()
function the same way.
It's slightly more difficult, since both arguments of pow() are
floating-point.


If the compiler implements pow() as an intrinsic, it's free to provide
different implementations based on the actual (unconverted) argument
types rather than promoting everything to double.
It's certainly feasible, but I don't know whether any compilers do
this. If exponentiation were a built-in operator, I think compiler
writers would have been more strongly motivated to optimize it along
with expression evaluation in general.


I doubt it. Implementers targeting numerical applications are going to
be motivated in either case, implementers who don't care about numerical
applications aren't going to be motivated in either case. Certainly
having the str* and mem* functions as functions rather than operators
hasn't prevented many compilers from implementing them as optimized
intrinsics.

-Larry Jones

When you're SERIOUS about having fun, it's not much fun at all! -- Calvin
Dec 24 '05 #50

67 Replies

This discussion thread is closed

Replies have been disabled for this discussion.