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.)
| [reply] [d/l] |
|
[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.
Cheers, R.
Pereant, qui ante nos nostra dixerunt!
| [reply] [d/l] [select] |
|
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.
| [reply] [d/l] [select] |
|
I was taught to use a plus to disambiguate:
print +( ... )
is that no longer accepted?
| [reply] [d/l] |
|
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.
| [reply] |
|
|
A reply falls below the community's threshold of quality. You may see it by logging in.
|
|
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. | [reply] |
Re: ** operator in perl
by ww (Archbishop) on Feb 03, 2009 at 10:49 UTC
|
| [reply] [d/l] |
Re: ** operator in perl
by lakshmananindia (Chaplain) on Feb 03, 2009 at 05:46 UTC
|
| [reply] |
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:\>
| [reply] [d/l] [select] |
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
| [reply] |
Re: ** operator in perl
by poolpi (Hermit) on Feb 03, 2009 at 09:20 UTC
|
#!/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
hth, PooLpi
| [reply] [d/l] |
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. | [reply] |