Почему модуль Perl Bignum дает мне странный результат для расчета мощности? - PullRequest
2 голосов
/ 14 октября 2011

Контекст: ActiveState Perl: Это Perl 5, версия 12, Subversion 4 (v5.12.4), созданная для MSWin32-x86-multi-thread

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

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

Тогда я подумал, может быть, мне нужноразграничить два отрицательных.

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

Наконец-то разобрался.

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

Так как же все скобки?

Ответы [ 4 ]

9 голосов
/ 14 октября 2011

Эта тема охватывает оба ваших вопроса (вам нужно немного спуститься, чтобы найти часть, соответствующую print (-2) ** 32).

Обобщая, что там:

  • Для вашей первой проблемы (perl -Mbignum=l -e "print -2 ** 32"): в Perl возведение в степень имеет более высокий приоритет, чем унарное отрицание.
  • Для второй проблемы (perl -Mbignum=l -e "print (-2) ** 32"): ключом является следующее предупреждениев документации для print .

    Также будьте осторожны, чтобы не использовать ключевое слово print с левой круглой скобкой, если только вы не хотите, чтобы соответствующая правая скобка завершила аргументы для print--вставьте + или поставьте круглые скобки вокруг всех аргументов.

4 голосов
/ 14 октября 2011

Я не думаю, что это связано с 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

Я полагаю, что применение функции - это то, что вам нужно (парсинг print (-2) как функция print вызывается с -2в качестве аргумента).

3 голосов
/ 14 октября 2011

Это не проблема, связанная с bignum, если вы попробуете это:

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

вы получите: -2

Таким образом, "проблема" связана с форматом аргументов функции печати

2 голосов
/ 15 октября 2011

Если вы замените свои константы переменными, B :: Deparse покажет вам, как perl анализирует код, поэтому

$ 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
...