开发者

Why does Perl's bignum module give me a strange result to a power calculation?

Context: ActiveState Perl: This is perl 5, version 12, subversion 4 (v5.12.4) built for MSWin32-x86-multi-thread

>perl -Mbignum=l -e "print 2 ** 32"
4294967296

>perl -Mbignum=l -e "print -2 ** 32"
-4294967296

Then I got to thinking, maybe I need to delimit the negative two.

>perl -Mbignum=l -e "print (-2) ** 32"
-2

Finally figured it out.

>perl -Mbignum=l -e "print 开发者_StackOverflow社区((-2) ** 32)"
4294967296

So how come all the parentheses?


This thread covers both of your questions (you have to go down a little to find the part corresponding to print (-2) ** 32).

Summarizing what is there:

  • For your first issue (perl -Mbignum=l -e "print -2 ** 32"): in Perl exponentiation has higher precedence than unary negation.

  • For the second issue (perl -Mbignum=l -e "print (-2) ** 32"): the key is the following warning in the documentation for print.

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


I don’t think this has to do with bignum.

$ perl -MO=Deparse -e "print 2 ** 32"
print 4294967296; # regular case
$ perl -MO=Deparse -e "print -2 ** 32"
print -4294967296; # ** has higher precedence than -
$ perl -MO=Deparse -e "print (-2) ** 32"
print(-2) ** 32; # parentheses parsed as function application
$ perl -MO=Deparse -e "print ((-2) ** 32)"
print 4294967296; # finally what you want

I guess the function application is what bit you (parsing print (-2) as the function print being called with -2 as an argument).


It's not a bignum related issue, if you try this:

perl -e "print (-2) + 32"

you get: -2

So the "problem" is with the arguments format of the print function


If you substitute your constants with variables, B::Deparse will show you how perl parses the code, so

$ perl -MO=Deparse,-p -e " print $fa ** $fb "
print(($fa ** $fb));
-e syntax OK

$ perl -MO=Deparse,-p -e " print -$fa ** $fb "
print((-($fa ** $fb)));
-e syntax OK

$ perl -MO=Deparse,-p -e " print (-$fa ) ** $fb "
(print((-$fa)) ** $fb);
-e syntax OK

$ perl -MO=Deparse,-p -e " print ( (-$fa ) ** $fb )"
print(((-$fa) ** $fb));
-e syntax OK
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜