bignum
СОДЕРЖАНИЕ
ИМЯ
bignum - поддержка больших чисел в Perl
СИНОПСИС
use bignum;
$x = 2 + 4.5; # Math::BigFloat 6.5
print 2 ** 512 * 0.1; # Math::BigFloat 134...09.6
print 2 ** 512; # Math::BigInt 134...096
print inf + 42; # Math::BigInt inf
print NaN * 7; # Math::BigInt NaN
print hex("0x1234567890123490"); # Perl v5.10.0 or later
{
no bignum;
print 2 ** 256; # a normal Perl scalar now
}
# for older Perls, import into current package:
use bignum qw/hex oct/;
print hex("0x1234567890123490");
print oct("01234567890123490"); ОПИСАНИЕ
Литеральные числовые константы
По умолчанию, каждое целочисленное литеральное значение становится объектом Math::BigInt, а дробное – объектом Math::BigFloat. Тип (целое или дробное) определяется только значением константы, а не ее представлением. Например, константы 3.14e2 и 0x1.3ap8 становятся объектами Math::BigInt, так как они оба представляют целое значение в десятичной записи 314.
По умолчанию use bignum; эквивалентно
use bignum downgrade => "Math::BigInt", upgrade => "Math::BigFloat"; Классы, используемые для целых и дробных чисел, могут быть установлены во время компиляции с помощью опций downgrade и upgrade, например
# use Math::BigInt for integers and Math::BigRat for non-integers
use bignum upgrade => "Math::BigRat"; Обратите внимание, что отключение модификации и понижения типов не влияет на то, как числовые литералы преобразуются в объекты
# disable both downgrading and upgrading
use bignum downgrade => undef, upgrade => undef;
$x = 2.4; # becomes 2.4 as a Math::BigFloat
$y = 2; # becomes 2 as a Math::BigInt Модификация и понижение типов
По умолчанию, когда результат вычисления является целым числом, Inf или NaN, результат понижается до целого числа, даже если все операнды являются экземплярами класса, предназначенного для преобразования в тип с большей точностью.
use bignum;
$x = 2.4; # becomes 2.4 as a Math::BigFloat
$y = 1.2; # becomes 1.2 as a Math::BigFloat
$z = $x / $y; # becomes 2 as a Math::BigInt due to downgrading Аналогично, по умолчанию, когда результат вычисления является конечным нецелым числом, результат повышается до числа с плавающей точкой, даже если все операнды являются экземплярами класса, предназначенного для преобразования в тип с меньшей точностью.
use bignum;
$x = 7; # becomes 7 as a Math::BigInt
$y = 2; # becomes 2 as a Math::BigInt
$z = $x / $y; # becomes 3.5 as a Math::BigFloat due to upgrading Классы, используемые для повышения и понижения типов, могут быть установлены во время выполнения с помощью методов "downgrade()" и "upgrade()", но см. "ОГРАНИЧЕНИЯ" ниже.
Классы для повышения и понижения типов не обязательно должны быть Math::BigInt и Math::BigFloat. Например, для использования Math::BigRat в качестве класса для повышения типа используйте
use bignum upgrade => "Math::BigRat";
$x = 2; # becomes 2 as a Math::BigInt
$y = 3.6; # becomes 18/5 as a Math::BigRat Классы для повышения и понижения типов можно изменять во время выполнения
use bignum;
$x = 3; # becomes 3 as a Math::BigInt
$y = 2; # becomes 2 as a Math::BigInt
$z = $x / $y; # becomes 1.5 as a Math::BigFlaot
bignum -> upgrade("Math::BigRat");
$w = $x / $y; # becomes 3/2 as a Math::BigRat Отключение понижения типов не изменяет тот факт, что целочисленные литеральные константы преобразуются в класс для понижения типов; оно только предотвращает понижение типов в результате вычисления. Например,
use bignum downgrade => undef;
$x = 2; # becomes 2 as a Math::BigInt
$y = 2.4; # becomes 2.4 as a Math::BigFloat
$z = 1.2; # becomes 1.2 as a Math::BigFloat
$w = $x / $y; # becomes 2 as a Math::BigFloat due to no downgrading Если вы хотите, чтобы все числовые литералы, как целые, так и дробные, становились объектами Math::BigFloat, используйте прагму bigfloat.
Аналогично, отключение повышения типов не изменяет тот факт, что дробные литеральные константы преобразуются в класс для повышения типов; оно только предотвращает повышение типов в результате вычисления. Например,
use bignum upgrade => undef;
$x = 2.5; # becomes 2.5 as a Math::BigFloat
$y = 7; # becomes 7 as a Math::BigInt
$z = 2; # becomes 2 as a Math::BigInt
$w = $x / $y; # becomes 3 as a Math::BigInt due to no upgrading Если вы хотите, чтобы все числовые литералы, как целые, так и дробные, становились объектами Math::BigInt, используйте прагму bigint.
Вы даже можете сделать
use bignum upgrade => "Math::BigRat", upgrade => undef; что преобразует все целочисленные литералы в объекты Math::BigInt, а все нецелочисленные – в объекты Math::BigRat. Однако, когда результат вычисления, включающего два объекта Math::BigInt, приводит к нецелому числу (например, 7/2), результат будет усечён до Math::BigInt, а не повышен до Math::BigRat, так как повышение типов отключено.
Перегрузка
Так как все числовые литералы становятся объектами, вы можете вызывать все обычные методы из Math::BigInt и Math::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);' Параметры
bignum распознаёт некоторые параметры, которые можно передать при загрузке с помощью use. Существуют следующие параметры:
- a или точность
-
Это устанавливает точность для всех математических операций. Аргумент должен быть больше или равен нулю. Подробности см. в методе bround() модуля Math::BigInt.
perl -Mbignum=a,50 -le 'print sqrt(20)'Обратите внимание, что одновременная установка точности и точности невозможна.
- p или разрядность
-
Это устанавливает разрядность для всех математических операций. Аргумент может быть любым целым числом. Отрицательные значения означают фиксированное количество цифр после точки, а положительное значение округляет до этой цифры слева от точки. 0 означает округление до целого числа. Подробности см. в методе bfround() модуля Math::BigInt.
perl -Mbignum=p,-50 -le 'print sqrt(20)'Обратите внимание, что одновременная установка точности и разрядности невозможна.
- l, lib, try или только
-
Загрузить другую библиотеку математических функций, см. "Библиотека математических функций".
perl -Mbignum=l,GMP -e 'print 2 ** 512' perl -Mbignum=lib,GMP -e 'print 2 ** 512' perl -Mbignum=try,GMP -e 'print 2 ** 512' perl -Mbignum=only,GMP -e 'print 2 ** 512' - hex
-
Переопределить встроенный метод hex() версией, которая может обрабатывать большие числа. Это переопределяет его, экспортируя его в текущий пакет. В Perl версии 5.10.0 и выше это не так необходимо, так как hex() лексически переопределяется в текущем контексте, когда активна прагма
bignum. - oct
-
Переопределить встроенный метод oct() версией, которая может обрабатывать большие числа. Это переопределяет его, экспортируя его в текущий пакет. В Perl версии 5.10.0 и выше это не так необходимо, так как oct() лексически переопределяется в текущем контексте, когда активна прагма
bignum. - v или версия
-
выводит имя и версию модулей и затем завершается.
perl -Mbignum=v
Библиотека математических функций
Математические операции с числами выполняются (по умолчанию) с помощью библиотечного модуля 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'; Использование c<lib> выводит предупреждение, если ни одна из указанных библиотек не найдена, и Math::BigInt и Math::BigFloat вернулись к одной из стандартных библиотек. Чтобы подавить это предупреждение, используйте try вместо:
use bignum try => 'GMP'; Если вы хотите, чтобы код завершился ошибкой вместо возвращения к стандартной библиотеке, используйте only вместо:
use bignum only => 'GMP'; Дополнительные сведения см. в документации соответствующего модуля.
Вызовы методов
Так как все числа теперь являются объектами, вы можете использовать методы, которые являются частью API Math::BigInt и Math::BigFloat.
Но следует обратить внимание. При использовании следующего для создания копии числа, будет создана только поверхностная копия.
$x = 9; $y = $x;
$x = $y = 7; Использование копии или оригинала с перегруженными математическими операциями допустимо, например, следующее работает:
$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, а также документацию в Math::BigFloat для получения дополнительной информации.
Методы
- inf()
-
Сокращение для возврата
infв качестве объекта. Полезно, потому что Perl не всегда корректно обрабатывает неявные значенияinf. - NaN()
-
Сокращение для возврата
NaNв качестве объекта. Полезно, потому что Perl не всегда корректно обрабатывает неявные значенияNaN. - e
-
# perl -Mbignum=e -wle 'print e'Возвращает число Эйлера
e, также exp(1) (= 2.7182818284...). - PI
-
# perl -Mbignum=PI -wle 'print PI'Возвращает число PI (= 3.1415926532..).
- bexp()
-
bexp($power, $accuracy);Возвращает число Эйлера
eв заданной степени с заданной точностью.Пример:
# perl -Mbignum=bexp -wle 'print bexp(1,80)' - bpi()
-
bpi($accuracy);Возвращает число PI с заданной точностью.
Пример:
# perl -Mbignum=bpi -wle 'print bpi(80)' - accuracy()
-
Установить или получить точность.
- precision()
-
Установить или получить разрядность.
- round_mode()
-
Установить или получить режим округления.
- div_scale()
-
Установить или получить масштаб деления.
- upgrade()
-
Установить или получить класс, к которому класс понижения типа преобразуется, если таковой имеется. Установите класс повышения типа в
undefдля отключения повышения типа. См./CAVEATSниже. - downgrade()
-
Установить или получить класс, к которому класс повышения типа преобразуется, если таковой имеется. Установите класс понижения типа в
undefдля отключения понижения типа. См. "ОГРАНИЧЕНИЯ" ниже. - 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 версии 5.9.4 и выше.
ОГРАНИЧЕНИЯ
- Методы upgrade() и downgrade()
-
Обратите внимание, что установка классов upgrade и downgrade во время выполнения с помощью методов "upgrade()" и "downgrade()" может не дать ожидаемого результата:
# Assuming that downgrading and upgrading hasn't been modified so far, so # the downgrade and upgrade classes are Math::BigInt and Math::BigFloat, # respectively, the following sets the upgrade class to Math::BigRat, i.e., # makes Math::BigInt upgrade to Math::BigRat: bignum -> upgrade("Math::BigRat"); # The following sets the downgrade class to Math::BigInt::Lite, i.e., makes # the new upgrade class Math::BigRat downgrade to Math::BigInt::Lite bignum -> downgrade("Math::BigInt::Lite"); # Note that at this point, it is still Math::BigInt, not Math::BigInt::Lite, # that upgrades to Math::BigRat, so to get Math::BigInt::Lite to upgrade to # Math::BigRat, we need to do the following (again): bignum -> upgrade("Math::BigRat");Более простой способ сделать это во время выполнения — использовать import(),
bignum -> import(upgrade => "Math::BigRat", downgrade => "Math::BigInt::Lite"); - Шестнадцатеричные, восьмеричные и двоичные литералы с плавающей точкой
-
Perl (и этот модуль) поддерживает шестнадцатеричные, восьмеричные и двоичные литералы с плавающей точкой, но используйте их с осторожностью в версиях Perl до v5.32.0, так как некоторые версии Perl молча генерируют неправильный результат.
- Перегрузка операторов и литералов
-
bigratработает, перегружая обработку целых и вещественных литералов, преобразуя их в объекты Math::BigRat.Это означает, что арифметические операции, включающие только строковые значения или строковые литералы, выполняются с помощью встроенных операторов Perl.
Например:
use bigrat; my $x = "900000000000000009"; my $y = "900000000000000007"; print $x - $y;выводит
0в стандартных 32-битных сборках, так какbignumникогда не видит строковые литералы. Чтобы гарантировать, что все выражение обрабатывается как объектыMath::BigFloat, используйте числовой литерал в выражении:print +(0+$x) - $y; - Диапазоны
-
Perl не позволяет перегружать диапазоны, поэтому вы не можете безопасно использовать диапазоны с
bignumконечными точками, и переменная-итератор не являетсяMath::BigFloat.use 5.010; for my $i (12..13) { for my $j (20..21) { say $i ** $j; # produces a floating-point number, # not an object } } - in_effect()
-
Этот метод работает только в Perl v5.9.4 и более поздних версиях.
- hex()/oct()
-
bignumпереопределяет эти функции версиями, которые также могут обрабатывать большие целые числа. Однако в Perl до версии v5.9.4 это произойдет только если вы явно запросите это с помощью двух тегов импорта "hex" и "oct" - и тогда это будет глобальным и нельзя будет отключить внутри области сno bignum:use bignum qw/hex oct/; print hex("0x1234567890123456"); { no bignum; print hex("0x1234567890123456"); }Второй вызов hex() выведет предупреждение о непереносимой константе.
Сравните это с:
use bignum; # will warn only under Perl older than v5.9.4 print hex("0x1234567890123456");
ПРИМЕРЫ
Некоторые интересные примеры командной строки, чтобы впечатлить аудиторию 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=l,GMP -le 'print 7 ** 7777' ОШИБКИ
Пожалуйста, сообщайте об ошибках или предложениях по улучшению в bug-bignum at rt.cpan.org, или через веб-интерфейс по адресу https://rt.cpan.org/Ticket/Create.html?Queue=bignum (требуется вход). Мы будем уведомлены, и затем вы автоматически будете получать уведомления о ходе выполнения вашей ошибки по мере внесения мной изменений.
ПОДДЕРЖКА
Вы можете найти документацию по этому модулю с помощью команды perldoc.
perldoc bignum Вы также можете найти информацию по следующим адресам:
-
GitHub
-
RT: Система отслеживания запросов CPAN
-
MetaCPAN
-
Матрица тестирования CPAN
-
Рейтинги CPAN
ЛИЦЕНЗИЯ
Эта программа является свободно распространяемым программным обеспечением; вы можете перераспределять его и/или изменять его на тех же условиях, что и Perl сам по себе.
См. также
Math::BigInt, Math::BigFloat, Math::BigRat и Math::Big, а также Math::BigInt::FastCalc, Math::BigInt::Pari и Math::BigInt::GMP.
АВТОРЫ
-
(C) Телс http://bloodgate.com/ в начале 2002—2007 годов.
-
Поддерживается Питером Джоном Эккламом <pjacklam@gmail.com>, 2014—н. в.
© 1993–2021 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.36.0/bignum