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} не является хорошей идеей, так как нет гарантии, что у объекта есть такой ключ hash, а также что он вообще содержит хэш.
ЗНАК
Знак может быть '+', '-', '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 версии 5.9.4 и выше.
- hex()/oct()
-
bigintпереопределяет эти функции версиями, которые также могут обрабатывать большие целые значения. Однако в Perl до версии 5.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
ЛИЦЕНЗИЯ
Эта программа является свободной программой; вы можете перераспределять и/или изменять ее на тех же условиях, что и Perl сам по себе.
См. также
Math::BigInt, Math::BigFloat, Math::BigRat и Math::Big, а также Math::BigInt::FastCalc, Math::BigInt::Pari и Math::BigInt::GMP.
АВТОРЫ
-
(с) Телс http://bloodgate.com/ в начале 2002-2007 гг.
-
Поддерживается Питером Джоном Аккламом <pjacklam@gmail.com<gt>, 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.30.3/bignum