bignum
СОДЕРЖАНИЕ
- НАЗВАНИЕ
- СИНТАКСИС
- ОПИСАНИЕ
- ОГРАНИЧЕНИЯ
- ИСПОЛЬЗУЕМЫЕ МОДУЛИ
- ПРИМЕРЫ
- ОШИБКИ
- ПОДДЕРЖКА
- ЛИЦЕНЗИЯ
- СМОТРИТЕ ТАКЖЕ
- АВТОРЫ
НАЗВАНИЕ
bignum - Поддержка чисел произвольной точности для Perl
СИНТАКСИС
use bignum;
$x = 2 + 4.5,"\n"; # BigFloat 6.5
print 2 ** 512 * 0.1,"\n"; # really is what you think it is
print inf * inf,"\n"; # prints inf
print NaN * 3,"\n"; # prints NaN
{
no bignum;
print 2 ** 256,"\n"; # a normal Perl scalar now
}
# for older Perls, import into current package:
use bignum qw/hex oct/;
print hex("0x1234567890123490"),"\n";
print oct("01234567890123490"),"\n"; ОПИСАНИЕ
Все операторы (включая основные математические операции) перегружены. Целые и вещественные константы создаются как соответствующие объекты BigInts или BigFloats.
Если вы выполните
use bignum; в начале вашего скрипта, Math::BigFloat и Math::BigInt будут загружены, и любое числовое значение будет преобразовано в соответствующий объект (Math::BigFloat для вещественных чисел, таких как 3.1415, и Math::BigInt для целых чисел, таких как 1234).
Таким образом, следующая строка:
$x = 1234; фактически создаёт объект Math::BigInt и сохраняет ссылку на него в переменной $x. Это происходит прозрачно и незаметно для пользователя.
Вы можете увидеть это, выполнив:
perl -Mbignum -le 'print ref(1234)' Не беспокойтесь, если вы видите Math::BigInt::Lite; bignum и родственные модули будут использовать Lite, если он установлен, так как он быстрее для некоторых операций. Он будет автоматически обновлён до BigInt, когда это необходимо:
perl -Mbignum -le 'print ref(2**255)' Это также означает, что проверка на наличие конкретного пакета не рекомендуется, так как фактическое содержимое $x может быть чем-то неожиданным. В связи с прозрачным способом работы bignum ref() не требуется.
Поскольку Math::BigInt и BigFloat также перегружают обычные математические операции, следующая строка по-прежнему будет работать:
perl -Mbignum -le 'print ref(1234+1234)' Поскольку числа представляют собой объекты, вы можете использовать все стандартные методы BigInt/BigFloat для них. Это в некоторой степени работает и с выражениями:
perl -Mbignum -le '$x = 1234; print $x->bdec()'
perl -Mbignum -le 'print 1234->copy()->binc();'
perl -Mbignum -le 'print 1234->copy()->binc->badd(6);'
perl -Mbignum -le 'print +(1234)->copy()->binc()' (Обратите внимание, что print не работает так, как ожидается, если выражение начинается с '('; поэтому используется +)
Вы даже можете объединять операции, как обычно:
perl -Mbignum -le 'print 1234->copy()->binc->badd(6);'
1241 В рамках bignum (или bigint или bigrat), Perl будет надлежащим образом «обновлять» числа. Это означает, что:
perl -Mbignum -le 'print 1234+4.5'
1238.5 будет работать правильно. Такие смешанные случаи не всегда работают при использовании только Math::BigInt или Math::BigFloat, или, по крайней мере, не так, как работают обычные скаляры Perl.
Если вам нужно работать с большими целыми числами, как в use integer;, попробуйте use bigint;:
perl -Mbigint -le 'print 1234.5+4.5'
1238 Также существует use bigrat;, которое позволяет вам работать с большими рациональными числами:
perl -Mbigrat -le 'print 1234+4.1'
12381/10 Весь процесс обновления/изменения формата по-прежнему находится на стадии эксперимента и может не работать так, как вы ожидаете, или может содержать ошибки. Вы можете получить такие ошибки:
Can't use an undefined value as an ARRAY reference at
/usr/local/lib/perl5/5.8.0/Math/BigInt/Calc.pm line 864 Это означает, что где-то процедура получила BigFloat/Lite, но ожидала BigInt (или наоборот), и путь обновления/изменения формата отсутствовал. Это ошибка, пожалуйста, сообщите об этом, чтобы мы могли её исправить.
Вы можете рассмотреть возможность использования только Math::BigInt или Math::BigFloat, так как они позволяют вам более тонко управлять тем, что происходит в данном модуле/пространстве. Например, простые счётчики циклов будут Math::BigInt в use bignum; и это медленнее, чем хранение их как скаляров Perl:
perl -Mbignum -le 'for ($i = 0; $i < 10; $i++) { print ref($i); }' Обратите внимание, что следующее не работает так, как ожидается (ничего не выводится), так как перегрузка оператора «..» пока невозможна в Perl (начиная с версии v5.8.0):
perl -Mbignum -le 'for (1..2) { print ref($_); }' Параметры
bignum распознаёт некоторые параметры, которые могут быть переданы во время загрузки через use. Эти параметры могут (в настоящее время) быть представлены в виде одной буквы или в длинной форме. Существуют следующие параметры:
- a или accuracy
-
Это устанавливает точность для всех математических операций. Аргумент должен быть больше или равен нулю. Подробнее см. функцию bround() в Math::BigInt.
perl -Mbignum=a,50 -le 'print sqrt(20)'Обратите внимание, что одновременная установка точности и числа значащих цифр невозможна.
- p или precision
-
Это устанавливает число значащих цифр для всех математических операций. Аргумент может быть любым целым числом. Отрицательные значения означают фиксированное число цифр после запятой, а положительные значения округляют до этого числа цифр слева от запятой. 0 или 1 означают округление до целого числа. Подробнее см. функцию bfround() в Math::BigInt.
perl -Mbignum=p,-50 -le 'print sqrt(20)'Обратите внимание, что одновременная установка точности и числа значащих цифр невозможна.
- t или trace
-
Это включает режим отслеживания и в основном предназначен для отладки bignum или Math::BigInt/Math::BigFloat.
- l или lib
-
Загрузить другую библиотеку математических функций, см. "Библиотека математических функций".
perl -Mbignum=l,GMP -e 'print 2 ** 512'В настоящее время нет способа указать более одной библиотеки в командной строке. Это означает, что следующее не работает:
perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'Надеемся, что это будет исправлено в ближайшее время ;)
- hex
-
Переопределить встроенный метод hex() версией, которая может обрабатывать большие числа. Это переопределяет его, экспортируя его в текущий пакет. В Perl v5.10.0 и выше это не так необходимо, так как hex() лексически переопределяется в текущем пространстве имён, когда активен pragma bignum.
- oct
-
Переопределить встроенный метод oct() версией, которая может обрабатывать большие числа. Это переопределяет его, экспортируя его в текущий пакет. В Perl v5.10.0 и выше это не так необходимо, так как oct() лексически переопределяется в текущем пространстве имён, когда активен pragma bigint.
- v или version
-
Это выводит имя и версию всех используемых модулей и затем завершает работу.
perl -Mbignum=v
Методы
Помимо import() и AUTOLOAD(), существует всего несколько других методов.
Поскольку все числа теперь являются объектами, вы можете использовать все функции, которые являются частью API BigInt или BigFloat. Тем не менее, рекомендуется использовать только обозначение bxxx(), а не fxxx(). Это позволяет тому, что лежащий в основе объект может измениться на другой класс, например, с BigFloat.
Ограничения
Однако необходимо предупреждение. При использовании следующего кода для создания копии числа будет создана только поверхностная копия.
$x = 9; $y = $x;
$x = $y = 7; Если вам нужна настоящая копия, используйте следующее:
$y = $x->copy(); Использование копии или оригинала с перегруженными математическими операциями допустимо, например, следующее работает:
$x = 9; $y = $x;
print $x + 1, " ", $y,"\n"; # prints 10 9 но вызов любого метода, который изменяет число напрямую, приведёт к уничтожению обоих оригинала и копии:
$x = 9; $y = $x;
print $x->badd(1), " ", $y,"\n"; # prints 10 10
$x = 9; $y = $x;
print $x->binc(1), " ", $y,"\n"; # prints 10 10
$x = 9; $y = $x;
print $x->bmul(2), " ", $y,"\n"; # prints 18 18 Использование методов, которые не изменяют, но проверяют содержимое, работает:
$x = 9; $y = $x;
$z = 9 if $x->is_zero(); # works fine Обратитесь к документации о конструкторе копирования и = в overload, а также к документации в BigInt для получения дополнительной информации.
- inf()
-
Сокращение для возвращения Math::BigInt->binf(). Полезно, потому что Perl не всегда правильно обрабатывает слова
inf. - NaN()
-
Сокращение для возвращения Math::BigInt->bnan(). Полезно, потому что Perl не всегда правильно обрабатывает слова
NaN. - e
-
# perl -Mbignum=e -wle 'print e'Возвращает число Эйлера
e, т.е. exp(1). - PI()
-
# perl -Mbignum=PI -wle 'print PI'Возвращает значение числа PI.
- bexp()
-
bexp($power,$accuracy);Возвращает число Эйлера
eв соответствующей степени с требуемой точностью.Пример:
# perl -Mbignum=bexp -wle 'print bexp(1,80)' - bpi()
-
bpi($accuracy);Возвращает значение числа PI с требуемой точностью.
Пример:
# perl -Mbignum=bpi -wle 'print bpi(80)' - upgrade()
-
Возвращает класс, к которому числа обновляются, фактически возвращает
$Math::BigInt::upgrade. - in_effect()
-
use bignum; print "in effect\n" if bignum::in_effect; # true { no bignum; print "in effect\n" if bignum::in_effect; # false }Возвращает true или false, если
bignumактивен в текущем пространстве имён.Этот метод работает только в Perl v5.9.4 и выше.
Библиотека математических функций
Математические операции с числами выполняются (по умолчанию) модулем Math::BigInt::Calc. Это эквивалентно следующему:
use bignum lib => 'Calc'; Вы можете изменить это, используя:
use bignum lib => 'GMP'; Следующее сначала попытается найти Math::BigInt::Foo, затем Math::BigInt::Bar, и если это не удастся, вернётся к Math::BigInt::Calc:
use bignum lib => 'Foo,Math::BigInt::Bar'; Для получения дополнительной информации, пожалуйста, обратитесь к документации соответствующего модуля.
Использование lib выводит предупреждение, если ни одна из указанных библиотек не найдена, и Math::BigInt вернулся к одной из стандартных библиотек. Чтобы подавить это предупреждение, используйте try вместо:
use bignum try => 'GMP'; Если вы хотите, чтобы код завершался ошибкой вместо возврата к стандартной библиотеке, используйте only вместо:
use bignum only => 'GMP'; ВНУТРЕННИЙ ФОРМАТ
Числа хранятся как объекты, и их внутреннее представление может меняться в любое время, особенно между математическими операциями. Объекты также могут принадлежать к различным классам, таким как Math::BigInt или Math::BigFloat. Смешение их с обычными скалярными переменными является нормальным и ожидаемым.
Вы не должны полагаться на внутренний формат; все обращения должны выполняться через методы доступа. Например, обращение к $x->{sign} — не лучшая идея, поскольку нет гарантии, что объект имеет такой ключ хэша, или вообще содержит хэш.
ЗНАК
Знак может быть '+', '-', 'NaN', '+inf' или '-inf' и хранится отдельно. Вы можете получить к нему доступ через метод sign().
Знак 'NaN' используется для представления результата, когда входные аргументы не являются числами или в результате деления 0/0. '+inf' и '-inf' представляют соответственно положительную и отрицательную бесконечность. Вы получите '+inf', когда разделите положительное число на 0, и '-inf', когда разделите любое отрицательное число на 0.
ОГРАНИЧЕНИЯ
- Перегрузка операторов и литералов
-
bignumработает, перегружая обработку целочисленных и дробных литералов, преобразуя их в объекты Math::BigInt или Math::BigFloat.Это означает, что арифметические операции, включающие только строковые значения или строковые литералы, будут выполняться с использованием встроенных операторов Perl.
Например:
use bignum; my $x = "900000000000000009"; my $y = "900000000000000007"; print $x - $y;выведет
0в 32-битных сборках по умолчанию, так какbigratникогда не видит строковые литералы. Чтобы убедиться, что выражение обрабатывается как объектыMath::BigIntилиBigFloat, используйте числовой литерал в выражении:print +(0+$x) - $y; - in_effect()
-
Этот метод работает только в Perl v5.9.4 и более поздних версиях.
- hex()/oct()
-
bigintпереопределяет эти функции версиями, которые также могут обрабатывать большие целые значения. Однако в Perl до версии v5.9.4 это не произойдёт, если вы не запросите это явно с помощью двух тегов импорта "hex" и "oct" - и тогда это будет глобально и не может быть отключено внутри области видимости с "no bigint":use bigint qw/hex oct/; print hex("0x1234567890123456"); { no bigint; print hex("0x1234567890123456"); }Второй вызов hex() выведет предупреждение о непереносимой константе.
Сравните с:
use bigint; # will warn only under older than v5.9.4 print hex("0x1234567890123456");
Используемые модули
bignum — это просто тонкий оболочек вокруг различных модулей семейства Math::BigInt. Представьте его как главу семьи, управляющую магазином и отдающую распоряжения другим, чтобы выполнить работу.
Следующие модули в настоящее время используются модулем bignum:
Math::BigInt::Lite (for speed, and only if it is loadable)
Math::BigInt
Math::BigFloat ПРИМЕРЫ
Несколько интересных командных примеров, чтобы произвести впечатление на пользователей Python ;)
perl -Mbignum -le 'print sqrt(33)'
perl -Mbignum -le 'print 2*255'
perl -Mbignum -le 'print 4.5+2*255'
perl -Mbignum -le 'print 3/7 + 5/7 + 8/3'
perl -Mbignum -le 'print 123->is_odd()'
perl -Mbignum -le 'print log(2)'
perl -Mbignum -le 'print exp(1)'
perl -Mbignum -le 'print 2 ** 0.5'
perl -Mbignum=a,65 -le 'print 2 ** 0.2'
perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777' ОШИБКИ
Пожалуйста, сообщите об ошибках или пожеланиях по улучшению модуля bug-math-bigint at rt.cpan.org, или через веб-интерфейс по адресу https://rt.cpan.org/Ticket/Create.html?Queue=bignum (требуется вход). Мы будем уведомлены, а затем вы будете автоматически уведомлены о ходе решения вашей проблемы по мере внесения изменений.
ПОДДЕРЖКА
Вы можете найти документацию по этому модулю с помощью команды perldoc.
perldoc bignum Также вы можете поискать информацию на:
-
RT: система отслеживания задач CPAN
-
AnnoCPAN: аннотированная документация CPAN
-
Рейтинги CPAN
-
Поиск CPAN
-
Матрица CPAN Testers
ЛИЦЕНЗИЯ
Эта программа является свободным программным обеспечением; вы можете перераспределять и/или изменять её на тех же условиях, что и Perl сам по себе.
См. также
Math::BigInt, Math::BigFloat, Math::BigRat и Math::Big, а также Math::BigInt::FastCalc, Math::BigInt::Pari и Math::BigInt::GMP.
АВТОРЫ
-
(с) Tels http://bloodgate.com/ в начале 2002—2007 годов.
-
Поддерживается Peter John Acklam <pjacklam@gmail.com>, 2014—.
© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.28.3/bignum