Spec-Zone.ru › Perl 5.36

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

    https://github.com/pjacklam/p5-bignum

  • RT: Система отслеживания запросов CPAN

    https://rt.cpan.org/Dist/Display.html?Name=bignum

  • MetaCPAN

    https://metacpan.org/release/bignum

  • Матрица тестирования CPAN

    http://matrix.cpantesters.org/?dist=bignum

  • Рейтинги CPAN

    https://cpanratings.perl.org/dist/bignum

ЛИЦЕНЗИЯ

Эта программа является свободно распространяемым программным обеспечением; вы можете перераспределять его и/или изменять его на тех же условиях, что и Perl сам по себе.

См. также

bigint и bigrat.

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API