Power of Operators
Written by Harry Fairhead   
Thursday, 28 January 2021
Article Index
Power of Operators
Reverse Polish
Priority and assignment

Reverse Polish

A better, but less familiar, notation is reverse Polish where the operator is written after its operands.

For example, AB+ is reverse Polish for A+B. The advantage of reverse Polish is that it does generalize to n-adic operators.

For example, ABC@ is a reverse Polish expression using the triadic operator that finds the maximum of A,B and C.

Reverse Polish has another advantage in that operator priorities can be represented by the order that they occur.

For example, AB+C* is clearly (A+B)*C because the multiplication cannot be evaluated until the addition is evaluated to provide the second operand for the multiplication.

Because an operator can look like a function it is possible to confuse the two.

For example, in Ada abs, i.e. taking the absolute value of a quantity, is an operator but in Pascal and most other languages it is a function. If you don't notice this subtle difference you could end up writing expressions in Ada or Pascal that don't work as you expect.

As well as not agreeing about whether something is an operator or a function languages don't always agree about the assignment of priorities and if you switch languages this can be a cause of serious and difficult to find bugs.

For example, Fortran and BASIC give the exponentiation operator ^ the highest precedence but most spreadsheets give it second place to the unitary minus -.

It isn't even always reasonable to stick to a simple precedence rule in all cases.

For example, in many languages the exponentiation operation has the highest precedence of all operators and in general this is reasonable but consider

4^-2

using the strict precedence this should be

-4^2

i.e. -16 but this clearly isn't what the programmer intended. To put things right many languages alter the priority of exponentiation when it is immediately followed by negation. That is 4^-2 is evaluated as 4 raised to the power of -2 (i.e. 1/16).

Operators and expressions are powerful and compact ways of writing programs and many languages cannot resist the temptation to use them for nearly everything.

The most often quoted example of an operator based language is APL but surprisingly it doesn't use an operator precedence at all and simply evaluates everything left to right!

 

operators

Operators in C

In my opinion the operator king of modern languages is C and its approach has been inherited by many of the languages that are based on it.

C has a range of operators that needs 16 levels of precedence to control!

This bewildering array of operators is one of the reasons why C is intimating to the beginner and can look cryptic if written using lots of operators.

Once you start to extend the range of operators that a language has then you have to worry about associativity as well as precedence.

Associativity is simply the order that operators of the same priority will be evaluated. If you restrict your attention to simple arithmetic operators then the associativity isn't a problem because (A+B)+C is the same as A+(B+C).

However when you move on to consider more general operators it does matter.

For example, in C and many other languages (C# for example) the right shift operator A>>B shifts A right by B bits and

(A>>B)>>C

which means shift A right by B+C isn't the same as

A>>(B>>C)

shift A right by the result of the right shift of B by C bits.

To make the result of such operations unambiguous C defines each operator as associating left to right or right to left i.e. right or left associative.

The >> operator associates left to right because this means that A>>B>>C is (A>>B)>>C and this is the same as A>>(B+C).

 

Banner



Last Updated ( Thursday, 28 January 2021 )