28

While there is such operator - ** in Python, I was wondering why Java and C++ don't have one too.

It is easy to make one for classes you define in C++ with operator overloading (and I believe such thing is possible also in Java), but when talking about primitive types such as int, double and so on, you'll have to use library function like Math.power (and usually have to cast both to double).

So - why not define such an operator for primitive types?

10
  • 8
    In C++, we cannot create our own operators. You can only overload the existing operators.
    – Mahesh
    Commented Mar 3, 2011 at 8:54
  • 1
    @Mahesh , so i can create my own Number class and overload ^ operator to be a power. That realy doesnt mather.
    – RanZilber
    Commented Mar 3, 2011 at 8:56
  • 22
    @RanZilber: It does matter because the precedence of the ^ operator do not match the precedence of exponentiation. Consider the expression a + b ^ c. In mathematics, the exponentiation is performed first (b ^ c), then the resulting power is added to a. In C++, the addition is performed first (a + b) then the ^ operator is performed with c. So even if you did implement the ^ operator to mean exponentiation, the precedence will surprise everyone.
    – In silico
    Commented Mar 3, 2011 at 8:58
  • 2
    @RamZilber - ^ is an XOR in C++. It is advised that overloaded operator should do no different what a primitive data type does using it.
    – Mahesh
    Commented Mar 3, 2011 at 9:01
  • 4
    @RanZilber: Because it's not at all intuitive to use any of those operators you mention to mean exponentiation. I would seriously question the competence of any C++ programmer that overloads the ++ operator or the ! operator et. al. to mean exponentation. But you can't anyway, because the operators you talk about accept only one argument; exponentiation requires two arguments.
    – In silico
    Commented Mar 3, 2011 at 9:03

9 Answers 9

34

Generally speaking, the primitive operators in C (and by extension C++) are designed to be implementable by simple hardware in roughly a single instruction. Something like exponentiation often requires software support; so it's not there by default.

Also, it's provided by the standard library of the language in the form of std::pow.

Finally, doing this for integer datatypes wouldn't make much sense, because most even small values for exponentiation blow out the range required for int, that is up to 65,535. Sure, you could do this for doubles and floats but not ints, but why make the language inconsistent for a rarely used feature?

18
  • 4
    While I agree with most of this, the fact that the modulus operator can not be used on floating point types is inconsistent for primitive data types, but that too probably would not be a single instruction on any hardware I imagine is any way prevalent now.
    – Sion Sheevok
    Commented Mar 3, 2011 at 9:05
  • @Sion: At least on x86, modulus is a single instruction. (DIV does both division and modulus) You've got me on the consistency point though. Commented Mar 3, 2011 at 9:09
  • @Billy ONeal: Floating point modulus in a single instruction? I haven't mucked around in assembly as of late to know for my self. If that's the case, then the modulus operator should be made applicable to floating point types.
    – Sion Sheevok
    Commented Mar 3, 2011 at 9:12
  • 3
    @DonalFellows: FORTRAN had the exponentiation operator long before it had anything resembling bignum support.
    – supercat
    Commented Feb 13, 2014 at 22:05
  • 1
    @DonalFellows: A power operator isn't as useful with integers as with floats, but for small powers (especially squaring) it could definitely have its uses. Personally I like the approach of making operators out of letters (as Pascal does with div or FORTRAN with .EQ.); depending upon the language whitespace rules, it may be possible to have arbitrary number of operators without requiring that they be reserved words.
    – supercat
    Commented Feb 14, 2014 at 20:53
45

This question is answerable for C++: Stroustrup, "Design and Evolution of C++" discusses this in section 11.6.1, pp. 247-250.

There were general objections to adding a new operator. It would add to the already overcomplicated precedence table. The members of the working group thought it would give only minor convenience over having a function, and they wanted to be able to substitute their own functions sometimes.

There was no good candidate for an operator. ^ is exclusive-or, and ^^ invited confusion because of the relationship between & and | and && and ||. ! was unsuitable since there would be the natural tendency to write != for exponentiation of an existing value, and that was already taken. The best available may have been *^, which apparently nobody really liked.

Stroustrup considered ** again, but it already has a meaning in C: a**p is a times whatever p points to, and char ** c; declares c as a pointer to pointer to char. Introducing ** as a token meaning "declaration of a pointer to pointer to", "times what the next thing points to" (if it's a pointer) or "exponentiation" (if followed by a number) caused precedence problems. a/b**p would have to parse as a/(b**p) if p were a number, but (a/b) * *p if p were a pointer, so this would have to be resolved in the parser.

In other words, it would have been possible, but it would have complicated the precedence table and the parser, and both are already too complicated.

I don't know the story about Java; all I could do would be speculate. As for C, where it started, all C operators are easily translated into assembly code, partly to simplify the compiler and partly to avoid hiding time-consuming functionality in simple operators (the fact that operator+() and others could hide great complexity and performance hits was one of the early complaints about C++).

6
  • 2
    Nice answer. I guess Java tried to be simplified C in this respect, so nobody wanted to add a new operator. That's a pity that nobody asked me, I surely would have liked *^. :D
    – maaartinus
    Commented Aug 12, 2011 at 7:09
  • 1
    C was built to do text formatting. Fortran was built to do maths and had complex, power and matrix maths 20 years earlier. Commented May 29, 2012 at 15:39
  • 1
    @Martin Beckett: Can you find evidence that C was built for text formatting? It seems to me a very clumsy language for that, and what I've read about the origin of C says it was designed for system programming for Unix primarily. Commented May 29, 2012 at 18:09
  • 1
    @DavidThornley - It was designed to write Unix in, but all the early Unix uses seem to have been text formatting, and for it's time it has an extensive string and i/o library. Commented May 29, 2012 at 18:10
  • 7
    +1: The existing meaning for a**p is the killer. (The hacks to work around that problem… Brr!) Commented Oct 29, 2013 at 9:32
14

I suspect it's because every operator you introduce increases the complexity of the language. The barrier for entry is therefore very high. I find myself using exponentiation very, very rarely - and I'm more than happy to use a method call to do so.

8
  • 6
    Every feature starts out with -100 points.
    – In silico
    Commented Mar 3, 2011 at 9:12
  • 3
    I'd use x**2 and x**3 not that rarely. And a magic pow implementation that the compiler knows about and optimizes for the simple cases would be nice. Commented Mar 3, 2011 at 10:43
  • 2
    @CodeInChaos: However x * x and x * x * x aren't bad substitutes for the square and cube. Commented Mar 4, 2011 at 16:40
  • 5
    @David you can't simply write x*x if x is an expression. In the best case the code becomes unwieldy, and in the worst slower or even wrong. So you'd need to define your own Square and Cube functions. And even then the code would be uglier than using ** as power operator. Commented Mar 4, 2011 at 21:58
  • 1
    @David I need to put parentheses yes, but don't need to repeat the expression several times and bloats the source-code. Which reduces readability a lot. And common subexpression elimination is only possible if the compiler can guarantee the expression being free of side effects. And at least .net jitter isn't too smart in that regard. Commented Mar 4, 2011 at 22:36
11

The Java language and core library designers decided to relegate most math operations to the Math class. See Math.pow().

Why? Flexibility to prioritize performance over bit-for-bit precision. It would go against the rest of the language spec to say that the behavior of built-in math operators could vary from platform to platform, whereas the Math class specifically states that the behavior potentially sacrifices precision for performance, so buyer beware:

Unlike some of the numeric methods of class StrictMath, all implementations of the equivalent functions of class Math are not defined to return the bit-for-bit same results. This relaxation permits better-performing implementations where strict reproducibility is not required.

0
6

Exponentiation was part of Fortran from the beginning because it was aimed squarely at scientific programming. Engineers and physicists use it often in simulations, because power law relationships are common in physics.

Python has a strong presence in scientific computing, too (e.g. NumPy and SciPy). That, along with its exponentiation operator, suggest that it was aimed at scientific programming, too.

C, Java, and C# have roots in system programming. Perhaps that's an influence that kept exponentiation out of the group of supported operators.

Just a theory.

0
4

C defined operators only for common arithmetic operations accessible with the ALU. Its main aim was creating a human-readable interface to Assembly code.

C++ did not change any operator behaviour because it wanted all the code base written in C to be compliant.

Java did the same because it didn't want to intimidate existing C++ programmers.

2
  • When C was created, multiplication and division were not infrequently lacking in hardware and had to be implemented in software. Yet C has multiplication and division operators.
    – siride
    Commented Mar 5, 2011 at 4:17
  • @siride: To my knowledge, the PDP-7 the first computer to run Unix, had hardware multiplication and division through its EAE. Please see: bitsavers.org/pdf/dec/pdp7/F-75_PDP-7userHbk_Jun65.pdf Commented Mar 11, 2011 at 13:08
1

Well because every operator that would make sense for a power is already in use. ^ is XOR and ** defines a pointer to a pointer. So instead they just have a function that does the same thing. (like pow())

6
  • @RTS - Does a langauge developer is realy looking for sense more than efficieny ?
    – RanZilber
    Commented Mar 3, 2011 at 9:05
  • A good developer of a programming language looks at both. I can't say anything about java. But in c++ the pow() function is computed at compile time. And is just as efficient as the regular operators.
    – RTS
    Commented Mar 3, 2011 at 9:10
  • @RTS: The pow() function performs its computation at runtime, unless you got a compiler that can do constant folding for pow(), which I highly doubt. (Some compilers give you the option of using processor intrinsics to perform the calculation, however.)
    – In silico
    Commented Mar 3, 2011 at 9:13
  • @In silico I didn't mean that it computes the final value, I meant that the compilers will optimize away the function call, so you just have the raw equation.
    – RTS
    Commented Mar 3, 2011 at 9:19
  • 2
    @josefx: Sure it's a good reason. A single * is a lexical token, whether it's used for indirection or multiplication. A ** meaning exponentiation would be either one or two lexical tokens, and you really don't want your lexer to have to hit the symbol table to tokenize. Commented Mar 4, 2011 at 22:37
0

Fact is, arithmetic operators are only shortcuts of functions. (Nearly) Everything you do with them can be done with a function. Example:

c = a + b;
// equals
c.set(a.add(b));
// or as free functions
set(c, add(a,b));

It's just more verbose, so I see nothing wrong with using functions to perform 'power of'.

-1

Addition/subtraction/negation and multiplication/division are basic mathematical operators. If you were to make power an operator, where would you stop? Square root operator? N-root operator? Logarithm operator?

I can't speak for their creators, but I can say that I think it'd become unwieldy and not orthogonal to have such operators in the language. The number of non alpha-numeric/white-space characters remaining on the keyboard are rather limited. As it is, it's strange that there's a modulus operator in C++.

2
  • +1 - I don't see why having mod as an operator is strange. It's usually a single instruction. It's a primative operation on integers. It's used most everywhere in computer science. (Implementing things like bounded buffers without mod would stink) Commented Mar 3, 2011 at 9:14
  • @Billy ONeal: Strange because of the inconsistency between being able to use with integer types and floating point types. Absolutely useful though and I wouldn't dream of removing it. Just quirky is all.
    – Sion Sheevok
    Commented Mar 3, 2011 at 9:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.