Почему модуль Perl Bignum дает мне странный результат для расчета мощности?
Контекст: ActiveState Perl: это perl 5, версия 12, subversion 4 (v5.12.4), созданная для многопоточности MSWin32-x86
>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 ответа
Эта тема охватывает оба ваших вопроса (вам нужно немного спуститься, чтобы найти часть, соответствующую print (-2) ** 32
).
Подводя итог, что там:
- Для вашего первого номера (
perl -Mbignum=l -e "print -2 ** 32"
): в Perl возведение в степень имеет более высокий приоритет, чем унарное отрицание. Для второго номера (
perl -Mbignum=l -e "print (-2) ** 32"
): ключом является следующее предупреждение в документации для печати.Также будьте осторожны, чтобы не следовать за ключевым словом print с левой круглой скобкой, если только вы не хотите, чтобы соответствующая правая скобка завершила аргументы для печати - вставьте + или поставьте круглые скобки вокруг всех аргументов.
Я не думаю, что это связано с 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
в качестве аргумента).
Это не проблема, связанная с bignum, если вы попробуете это:
perl -e "print (-2) + 32"
Вы получаете: -2
Таким образом, "проблема" связана с форматом аргументов функции печати
Если вы замените свои константы переменными, 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