Spec-Zone.ru › Perl 5.38

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, используйте pragma 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, используйте pragma 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 или accuracy

Это устанавливает точность для всех математических операций. Аргумент должен быть больше или равен нулю. Подробнее см. метод bround() в Math::BigInt.

perl -Mbignum=a,50 -le 'print sqrt(20)'

Обратите внимание, что одновременная установка точности и значения accuracy невозможна.

p или precision

Это устанавливает точность для всех математических операций. Аргумент может быть любым целым числом. Отрицательные значения означают фиксированное количество цифр после запятой, а положительное значение округляет до этой цифры слева от запятой. 0 означает округление до целого числа. Подробности см. в методе bfround() в Math::BigInt.

perl -Mbignum=p,-50 -le 'print sqrt(20)'

Обратите внимание, что одновременная установка точности и значения accuracy невозможна.

l, lib, try или only

Загрузить другую библиотеку математических функций, см. "Библиотека математических функций".

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() лексически переопределяется в текущем пространстве имён, когда активен pragma bignum.

oct

Переопределить встроенный метод oct() версией, которая может обрабатывать большие числа. Это переопределяет его путём экспорта в текущий пакет. В Perl версии 5.10.0 и выше это не так необходимо, так как oct() лексически переопределяется в текущем пространстве имён, когда активен pragma bignum.

v или version

выводит имя и версию модулей, а затем завершается.

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()

Устанавливает или получает значение accuracy.

precision()

Устанавливает или получает значение 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 этого не произойдет, если вы не запросите это явно с помощью двух тегов import "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–2023 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.38.0/bignum

Spec-Zone.ru

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