Exponentiation

Published

2023-07-31

Exponentiation

Exponentiation is a ubiquitous mathematical operation. However, the syntax for exponentiation varies between programming languages. In some languages, the caret (^) is the exponentiation operator. In other languages, including Python, it’s the double-asterisk (**). Some languages don’t have an exponentiation operator, and instead they provide a library function, pow().

The reasons for these differences are largely historical. In mathematics, we write an exponent as a superscript, for example, x^2. However, keyboards and character sets don’t know about superscripts,1 and so the designers of programming languages had to come up with different ways of writing exponentiation.

** was first used in Fortran, which first appeared in 1957. This is the operator which Python uses for exponentiation.

For the curious, here’s a table with some programming languages and the operators or functions they use for exponentiation.

** Algol, Basic, Fortran, JavaScript, OCaml, Pascal, Perl, Python, Ruby, Smalltalk
^ J, Julia, Lua, Mathematica
pow() C, C++, C#, Dart, Go, Java, Kotlin, Rust, Scala
expt Lisp, Clojure

Exponentiation in Python

Now we know that ** is the exponentiation operator in Python. This is an infix operator, meaning that the operator appears between its two operands. As you’d expect, the first operand is the base, and the second operand is the exponent or power. So,

b ** n

implements b^n.

Here are some examples,

Area of a circle of a given radius 3.14159 * radius ** 2
Kinetic energy, given mass and velocity (1 / 2) * m * v ** 2

Also, as you’d expect, ** has precedence over * so in the above examples, radius ** 2 and v ** 2 are calculated before multiplication with other terms.

But wait! There’s more!

You’re going to find out sooner or later, so you might as well know now that Python also has a built-in function pow(). For our purposes, ** and pow() are equivalent, so you may use either. Here’s a session at the Python shell:

>>> 3 ** 2
9
>>> 3.0 ** 2
9.0
>>>
>>> pow(3, 2)
9
>>> pow(3.0, 2)
9.0

With two operands or arguments, ** and pow() behave identically. If both operands are integers, and the exponent is positive, the result will be an integer. If one or more of the operands is a float, the result will be a float.

Negative or fractional exponents behave as you’d expect.

>>> 3 ** 0.5    # Calculates the square root of 3
1.7320508075688772
>>> 3 ** -1     # Calculates 1 / 3
0.3333333333333333

No surprises here.

x^0 = 1

Remember from algebra that any non-zero number raised to the zero power is one. If that weren’t the case, what would become of this rule?

b^{m + n} = b^m \times b^n

So x^0 = 1 for all non-zero x. Python knows about that, too.

>>> 1 ** 0
1
>>> 2 ** 0
1
>>> 0.1 ** 0
1.0

What about 0^0? Many mathematics texts state that this should be undefined or indeterminate. Others say 0^0 = 1. What do you think Python does?

>>> 0 ** 0
1

So, Python has an opinion on this.

Now, go forth and exponentiate!

A little puzzle

Consider the following Python shell session:

>>> pow(-1, 0)
1
>>> -1 ** 0
-1

What’s going on here? The answer we get using pow() is what we’d expect. Shouldn’t these both produce the same result? Can you guess why these yield different answers?

Original author: Clayton Cafiero < [given name] DOT [surname] AT uvm DOT edu >

No generative AI was used in producing this material. This was written the old-fashioned way.

This material is for free use under either the GNU Free Documentation License or the Creative Commons Attribution-ShareAlike 3.0 United States License (take your pick).

Footnotes

  1. Picking nits, that’s not entirely true, since nowadays there are some character sets that include superscript 2 and 3. But they’re not understood as numbers and aren’t useful in programming.↩︎