Come for the quick hacks, stay for the epiphanies. PerlMonks

### Operator Precedence (unary negation and exponentiation)

by Elliott (Pilgrim)
 on Jan 14, 2003 at 10:21 UTC Need Help??

Elliott has asked for the wisdom of the Perl Monks concerning the following question:

Am I alone in finding Perl's precedence table counter-intuitive in having exponentiation bind more tightly than unary negation?

I (and the mathematicians I know) think that: -2**2 = 4, not -4 as Perl insists.

Does anyone know if this is a special feature of Perl or if other languages do the same?

Edited: ~Tue Jan 14 20:37:54 2003 (GMT) by footpad: Moved to SOPW, per Consideration

• Comment on Operator Precedence (unary negation and exponentiation)

Replies are listed 'Best First'.
Re: Operator Precedence (unary nagation and exponentiation)
by Callum (Chaplain) on Jan 14, 2003 at 10:42 UTC
Unfortunately the orders of precedence used in different subjects (computing, science, etc) and languages (Perl precedence is mostly based on C's precedence) vary too much, yet are similar enough that people can make (sometimes-wrong) assumptions about what the order will be.

My background is sciency rather than computery, so I've seen several such problems, which are essentially arising out of sharing part of a language -- the concept of operator precedence exists in both the 'maths-language' and the 'perl-language', and means almost the same thing in both but with subtle differences which will be missed if you're not fully fluent in both languages.

Re: Operator Precedence (unary nagation and exponentiation)
by Arien (Pilgrim) on Jan 14, 2003 at 10:54 UTC

Python (python -c 'print -2**2') and Ruby (ruby -e 'print -2**2') do it this way, both commands will print -4.

While we are on the subject, what is going on here??

```\$ perl -le 'print (-2)**2'
-2
\$

Update: B::Deparse helps sometimes:

```\$ perl -MO=Deparse -e 'print (-2)**2'
print(-2) ** 2;
-e syntax OK

The following does work as intended:

```\$ perl -le 'print((-2)**2)'
4

— Arien

It must be a parsing error, I guess: perl -e '\$v=-2; print \$v**2' correctly produces 4. So my guess is that the parsing in your example is simply throwing away the **2 component.

Why is another question...

--
Tommy
Too stupid to live.
Too stubborn to die.

Use -w!
```    \$ perl -wle 'print (-2)**2'
print (...) interpreted as function at -e line 1.
Useless use of exponentiation (**) in void context at -e line 1.
-2

Just like any other function, if the function name is followed by a left paren, it's taken as the start of the argument list. print (-2)**2 is parsed as (print (-2)) ** 2. This is even documented. From perldoc print:

```Also be careful not to follow the
print keyword with a left parenthesis unless you
want the corresponding right parenthesis to termi-
nate the arguments to the print--interpose a "+"
or put parentheses around all the arguments.

Abigail

Try perl -e '\$v = 2; print -\$v ** 2;'

This the use of unary negation that is the subject of the thread.

Examine what is said, not who speaks.

The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

Re: Operator Precedence (unary nagation and exponentiation)
by Hofmator (Curate) on Jan 14, 2003 at 10:44 UTC
Fortran *duck* does the same ...

-- Hofmator

Hmmm... well if it goes back to Fortran, then it's nearly as old as I am! I wonder if some compiler writer, tripping on 60s chemicals, got it wrong and his mistake has been passed from generation to generation or if, in fact, there is some very good reason for this order.

Anyone got any thoughts on why it might be better in some context to evaluate exponentiation before unary negation? Or (less likely but possible) does anyone know the actual history?

Because unary negation is actually a multiplication? And that everyone agrees that 4 * 3 ** 2 equals 36, and not 144? Of course, that's just guessing. Note that
```    echo '-2^2' | bc
gives you 4, and not -4.

Abigail

Re: Operator Precedence (unary negation and exponentiation)
by pdcawley (Hermit) on Jan 14, 2003 at 14:29 UTC
How can I put this?

Ah yes, you're wrong. -2**2 is -4, (-2)**2 is 4.

Assume that -2**2 = 4, now add zero to both sides and you have 0 - 2**2 = 0 + 4, reduce the exponent and you have 0 - 4 = 0 + 4 (exponentiation definitely binds tighter than subtraction), which reduces to -4 = 4 which is obviously not true.

So your argument is that subtraction and negation are the same thing. Perl does not agree with you. They are not next to each other in the precedence table.

Negation is ranked above multiplication while subtraction is ranked below. This means that
-2*3 is evaluated as (-2)*3
while
0-2*3 is evaluated as 0-(2*3)
I cannot think of any practical circumstance where this would lead to a different answer!

I have just been chatting to a mathematician about this and we agreed that the reason we would expect -2**3 to mean (-2)**3 is that we do not think of unary negation as a operation at all. Rather, we think of "-2" as a number.

Hold on just a moment. One minute you're arguing that Perl's operator precedence should be altered so that it agrees with your flawed understanding the normal order of operations, the next you're arguing that I'm wrong because that's not how Perl's operator table looks? You really can't have it both ways you know.

Go check any mathematical reference on this, here is pretty much the first explanation that fell off a google search for 'normal order of operation'.

Re: Operator Precedence (unary negation and exponentiation)
by Elliott (Pilgrim) on Jan 23, 2003 at 02:06 UTC
I'm hardly helping my case here - but I can report that Microsoft Excel does it the way I'd expect , with negation at the top of the precedence pile.

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://226785]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2024-08-03 08:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?
 • erzuuli ‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.