Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

** operator in perl

by irah (Pilgrim)
on Feb 03, 2009 at 05:02 UTC ( #740901=perlquestion: print w/replies, xml ) Need Help??
irah has asked for the wisdom of the Perl Monks concerning the following question:

I have executed a following program in Perl. print -2**4 + 1; Perl script prints, -15. But as per Mathematical rule (minus * minus = plus). So it will print, 17. Is Perl doesn't handle sign operation. Pleas clarify me.

Replies are listed 'Best First'.
Re: ** operator in perl
by chromatic (Archbishop) on Feb 03, 2009 at 05:21 UTC

    According to perlop, the exponentiation operator has a higher precedence than unary minus, so you need parentheses to disambiguate your expected precedence:

    print (((-2)**4)+1)

    (The extra parentheses denote the entire mathematical operation as the single argument to print.)

      I was puzzled by this one too ...

      [me@ptmr]/home/me$ perl -le 'print -2 ** 4 ' # ** binds before - -16 [me@ptmr]/home/me$ perl -le 'print (-2) ** 4 ' # this puzzled me -2 [me@ptmr]/home/me$ perl -le 'print ((-2) ** 4)' # parenthesis force wh +at I want 16

      but I guess print is handling the second case as a list followed by some irrelevance, do I have that about right ?

      Update: Thanks Fletch now I have been enlightened! I last read perlfunc a long time ago and had not really absorbed it all at the time. Now I see the explanation print (something) something_else gives the warning print (...) interpreted as function because it looks like a function.


      Pereant, qui ante nos nostra dixerunt!

        print is a list operator, so the second parses as (print(-2))**4 and will produce a warning if you run with -w/warnings (Useless use of exponentiation (**) in void context at -e line 1.).

        Update: I mean it's not like perlfunc uses print as the example of precedence issues that can come up with list operators right in the second paragraph or anything . . .

        The cake is a lie.
        The cake is a lie.
        The cake is a lie.

      I was taught to use a plus to disambiguate: print +( ... ) is that no longer accepted?

      Tilly is my hero.

        I was taught to use a plus to disambiguate: print +( ... ) is that no longer accepted?
        That's still fine in Perl 5, but Perl 6 disambiguates it on the basis of the whitespace alone, which is what most newcomers seem to expect. Also, unary + actually means something in Perl 6, and wouldn't work anymore for the purpose of doing nothing. So the Perl 5 usage is deprecated in that sense. But only if you believe in Perl 6... :-)

        Actually, what most people expect is for Perl to read their minds, but we've been having some trouble implementing that part, so we may put it off till Perl 7.

Re: ** operator in perl
by moritz (Cardinal) on Feb 03, 2009 at 08:26 UTC
    Even in mathematics the exponentiation binds tighter than a sign. I write thinks like -ei k x all the time, and it always means that I apply the exponentiation first.
Re: ** operator in perl
by ww (Bishop) on Feb 03, 2009 at 10:49 UTC
    To date, irah, all your questions could have been readily answered using the documentation (see $ perldoc perldoc at your local command prompt for a summary; the documentation referenced in perlman:perlfaq; or a decent book (say, for example, the Llama.

    You may want to try those.

Re: ** operator in perl
by lakshmananindia (Chaplain) on Feb 03, 2009 at 05:46 UTC
Re: ** operator in perl
by Anonymous Monk on Feb 03, 2009 at 08:21 UTC
    Hint, check with B::Deparse, even though constants get in the way
    D:\>perl -MO=Deparse,-p -e " print -2 ** 4 + 1; " print((-15)); -e syntax OK
    just substitute them variables, and you can see
    D:\>perl -MO=Deparse,-p -e " print -$two ** $four + $one; " print(((-($two ** $four)) + $one)); -e syntax OK D:\>
Re: ** operator in perl
by swampyankee (Parson) on Feb 03, 2009 at 12:59 UTC

    I'm going to be more verbose.

    You seem to be thinking that unary minus binds more tightly than exponentiation under normal arithmetic rules. It doesn't. You're expecting it to parse as

    (-2)4 - 1

    this is a misconception I've had to deal with often when tutoring community college students. By the normal precedence rules of arithmetic, it will actually be evaluated

    -(24) - 1.

    Perl (and most other programming languages) try to replicate the normal arithmetic precedence rules as closely as possible.

    Remember, under normal arithmetic rules, exponentiation (the ** operator in Perl) binds more closely than multiplication (there's an implied multiplication in -2; it's shorthand for (-1) * 2), which binds more tightly than addition.

    Information about American English usage here and here. Floating point issues? Please read this before posting. — emc

Re: ** operator in perl
by poolpi (Hermit) on Feb 03, 2009 at 09:20 UTC

    This core module may help you : Math::BigInt

    #!/usr/bin/perl use strict; use warnings; use Math::BigInt lib => 'GMP'; # (((-2)**4)+1) my $x = Math::BigInt->new('-2'); print $x->bpow(4)->badd(1)->bstr(); __END__ Output: 17


    'Ebry haffa hoe hab im tik a bush'. Jamaican proverb
Re: ** operator in perl
by repellent (Priest) on Feb 05, 2009 at 00:42 UTC
    Dominus's Precedence Problems provides a great explanation about the importance of operator precedence in Perl 5, and why it's laid out as-is.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://740901]
Approved by moritz
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2016-12-11 14:16 GMT
Find Nodes?
    Voting Booth?
    On a regular basis, I'm most likely to spy upon:

    Results (169 votes). Check out past polls.