Глава 122 · От первого большого числа к специальным алгоритмам
GMP: большие целые, арифметика, биты и теория чисел
Полный справочник GMP: точные большие числа, все операции и методы, системы счисления, двоичные форматы и математические задачи.
Зачем нужны большие целые: сохранить номер без потери одной цифры
Сервис прислал счётчик 100000000000000000001. Его нельзя бездумно превратить в обычный int: на 64-битной PHP верхняя положительная граница int — 9223372036854775807. Переход во float позволяет хранить большой масштаб, но не все младшие цифры. Если надо точно прибавить единицу, вычислить разность или выполнить целочисленный алгоритм, подходит расширение GMP.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
<?php
declare(strict_types=1);
$counter = gmp_init('100000000000000000001', 10);
$next = gmp_add($counter, 1);
echo gmp_strval($next), "\n";
Ожидаемый результат
100000000000000000002
В переменной counter лежит GMP-объект. gmp_add создаёт результат, а gmp_strval получает точный текст. Основание 10 явно говорит, что цифры обозначают десятичное число.
| Задача | Подход |
|---|---|
| Посчитать небольшое число товаров | Обычный PHP int и + обычно достаточно. |
| Хранить ID без арифметики | Часто достаточно строки; ведущие нули могут быть значимы. |
| Точно работать с огромными целыми | GMP. |
| Считать десятичные дроби | BCMath или другая подходящая десятичная модель. |
| Денежные суммы | Целые минимальные единицы либо проверенная десятичная модель; явно определить округление и валюту. |
GMP не требует писать свои классы. Объект GMP представляет число, а большинство действий вызываются обычными функциями gmp_*. У каждого аргумента всё равно есть ограничения: большое целое не превращается автоматически в дату, деньги или валидный идентификатор.
Установка, требования и проверка конкретного окружения
GMP — расширение PHP. При сборке PHP из исходников его включают параметром --with-gmp; официальная документация указывает минимум GMP 4.2, отдельным возможностям нужна более новая библиотека. Windows-сборки используют совместимую библиотеку MPIR. Пакет расширения или DLL должен соответствовать версии PHP, архитектуре и TS/NTS вашей сборки.
<?php
declare(strict_types=1);
var_dump(extension_loaded('gmp'));
var_dump(class_exists(GMP::class));
var_dump(defined('GMP_VERSION'));
Ожидаемый результат
bool(true)
bool(true)
bool(true)
Ожидаемый результат относится к окружению с загруженным GMP. Для браузерного PHP и CLI могут действовать разные ini: успешная консольная проверка не подтверждает настройку PHP-FPM или Apache.
При отсутствии расширения gmp_* не вызываются. Сначала установите его через средства своей системы или хостинга, настройте ini нужного SAPI и перезапустите соответствующий серверный процесс. Не размещайте общедоступный phpinfo с конфигурацией сервера. GMP не добавляет прикладной схемы данных: вход проверяется вашим кодом.
GMP как объект: операторы, копирование, bool и версии
Начиная с PHP 5.6 GMP-значения представлены объектами. Они поддерживают арифметические, битовые операторы и сравнения, но собственного набора методов add/sub у них нет: основной API процедурный. Конструктор с параметрами доступен с PHP 8.2.4; до этого числа обычно создавали через gmp_init. С PHP 8.4 класс final: наследоваться от него нельзя. Если нужна предметная модель суммы, она может хранить GMP внутри, а не расширять этот класс.
<?php
declare(strict_types=1);
$a = gmp_init('100000000000000000000', 10);
$b = $a + 2;
echo gmp_strval($a), "\n";
echo gmp_strval($b), "\n";
var_dump($b > $a);
Ожидаемый результат
100000000000000000000
100000000000000000002
bool(true)
Один операнд — GMP, поэтому используется его арифметика. Две обычные строковые переменные с оператором + сами по себе не включают GMP. Функции gmp_* делают выбранную модель особенно явной.
<?php
declare(strict_types=1);
var_dump((bool) gmp_init(0));
var_dump((bool) gmp_init(-1));
Ожидаемый результат
bool(false)
bool(true)
С PHP 8.4 GMP-ноль преобразуется в false, ненулевое число — в true. Ранее такое приведение вызывало E_RECOVERABLE_ERROR. Для API GMP|false используйте === false: нулевой объект нельзя спутать с признаком неудачи.
Присваивание объекта второй переменной даёт ещё одно имя того же объекта. Большинство вычислений возвращает новый объект, но setbit/clrbit меняют переданный. Для независимой изменяемой копии нужен clone. Сериализация поддерживает __serialize/__unserialize с PHP 8.1; для межсервисного обмена числом обычно проще строка из gmp_strval. gmp_setbit показывает различие оригинала, второго имени и копии.
Все константы GMP: округление, двоичный порядок и версии
| Константа | Назначение |
|---|---|
| GMP_ROUND_ZERO | Частное округляется к нулю; режим по умолчанию у div_q/r/qr. |
| GMP_ROUND_PLUSINF | Частное округляется к плюс бесконечности. |
| GMP_ROUND_MINUSINF | Частное округляется к минус бесконечности. |
| GMP_MSW_FIRST | При import/export первое слово — наиболее значимое. |
| GMP_LSW_FIRST | Первое слово — наименее значимое. Выберите ровно один порядок слов. |
| GMP_LITTLE_ENDIAN | Внутри каждого слова младший байт идёт первым. |
| GMP_BIG_ENDIAN | Внутри каждого слова старший байт идёт первым. |
| GMP_NATIVE_ENDIAN | Порядок байтов машины. Для обмена между разными машинами обычно задают явный порядок. |
| GMP_VERSION | Строка версии библиотеки GMP/API; не версия PHP. |
| GMP_MPIR_VERSION | Строка версии MPIR, когда сборка основана на ней. Перед чтением проверьте defined. |
В import/export порядок слов и порядок байтов — две разные настройки. Выберите один MSW/LSW и один LITTLE/BIG/NATIVE; объединяйте разные группы оператором |. Режимы ROUND относятся к частному целочисленного деления, а не к десятичному форматированию. Числовые значения констант в коде не заменяют их имена.
Комбинация функций: от учебного цикла к готовому факториалу
Факториал n — произведение целых от 1 до n. Сначала соберём его обычным циклом, чтобы было видно накопление GMP-значения. Затем сравним с готовой gmp_fact. Это пример сочетания знакомых управляющих конструкций с расширением, а не требование каждый раз реализовывать библиотечный алгоритм заново.
<?php
declare(strict_types=1);
$result = gmp_init(1);
for ($factor = 2; $factor <= 20; $factor++) {
$result = gmp_mul($result, $factor);
}
echo gmp_strval($result), "\n";
var_dump(gmp_cmp($result, gmp_fact(20)) === 0);
Ожидаемый результат
2432902008176640000
bool(true)
Начальное значение 1 не меняет первое умножение. Новое произведение присваивается result на каждом шаге. Для прикладного кода готовая функция короче и обычно выполняет вычисление эффективнее.
Справочник GMP по категориям: все функции и методы
| Категория | Операции |
|---|---|
| Создание, представления и сериализация | gmp_init · GMP::__construct · gmp_strval · gmp_intval · gmp_import · gmp_export · GMP::__serialize · GMP::__unserialize |
| Арифметика и сравнение | gmp_add · gmp_sub · gmp_mul · gmp_abs · gmp_neg · gmp_cmp · gmp_sign |
| Деление и остаток | gmp_div_q · gmp_div · gmp_div_r · gmp_div_qr · gmp_mod · gmp_divexact |
| Степени, корни, комбинаторика | gmp_pow · gmp_powm · gmp_sqrt · gmp_sqrtrem · gmp_root · gmp_rootrem · gmp_perfect_square · gmp_perfect_power · gmp_fact · gmp_binomial |
| Биты и маски | gmp_and · gmp_or · gmp_xor · gmp_com · gmp_setbit · gmp_clrbit · gmp_testbit · gmp_popcount · gmp_hamdist · gmp_scan0 · gmp_scan1 |
| Теория чисел | gmp_gcd · gmp_gcdext · gmp_lcm · gmp_invert · gmp_legendre · gmp_jacobi · gmp_kronecker · gmp_nextprime · gmp_prob_prime |
| Псевдослучайные числа и перенос старого кода | gmp_random_bits · gmp_random_range · gmp_random_seed · gmp_random |
Карточки ниже содержат сигнатуру, параметры, результат, ограничения и отдельные примеры. gmp_div сохранена как именованный alias, gmp_random — как историческая удалённая функция с миграцией. Поэтому дерево помогает читать и современный, и старый код.
Границы применения: точность не отменяет стоимость и проверку входа
Количество цифр определяет расход памяти и время алгоритма. Пользовательские строки, показатели степени, битовые индексы и размеры случайных значений ограничивают до тяжёлой операции. Прямое pow с последующим mod обычно уступает powm; полный перебор факториального числа вариантов останется дорогим, даже если их количество вычисляется быстро. Универсальных обещаний «эта функция всегда медленная» без размера входа и окружения здесь нет.
В JSON большие ID передавайте строками по согласованной схеме: принимающий JavaScript тоже имеет ограничения точности обычного Number. В двоичном import/export сохраняется модуль, а знак и ширину описывает внешний формат. Не приводите GMP в int только ради вывода. Функции случайности GMP не подходят для секретов, а числовые теоретические операции не заменяют проверенную криптографическую библиотеку.
Источники контрактов: PHP Manual и реализация расширения PHP 8.5.11; поведение математической библиотеки сверено с руководством GNU GMP. В конкретной Windows-сборке используется MPIR, поэтому не закрепляйте последовательности random или детали вероятностного теста как межплатформенный формат.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
gmp_initСохранить большое целое без округления и явно выбрать систему счисления.
gmp_init(int|string $num, int $base = 0): GMPСохранить большое целое без округления и явно выбрать систему счисления.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | int либо строка целого. Пробельные символы внутри строки игнорируются; это не строгая проверка формата пользовательского ввода. |
| base | 0 — автоопределение; 2…62 — явное основание. При 0: 0x/0X — 16, 0b/0B — 2, 0o/0O или начальный 0 — 8, иначе 10. Поддержка 0o появилась в PHP 8.1. |
| Буквы | В основаниях до 36 регистр не важен. В 37…62 A…Z дают 10…35, a…z дают 36…61. |
| Ошибки | Некорректное основание или непригодная запись — ValueError; неподходящий тип — TypeError. Для форм отдельно ограничьте длину и допустимые символы. |
| Возврат | Новый объект GMP. Предварительный вызов необязателен для операций, которые сами принимают int/string. |
- Строка с точными цифрами
- Разбор в выбранном основании
- GMP-число
- Арифметика без перехода во float
<?php
declare(strict_types=1);
$counter = gmp_init('100000000000000000001', 10);
echo gmp_strval($counter), "\n";
Ожидаемый результат
100000000000000000001
Кавычки важны до вызова: без них PHP мог бы сначала получить неточный float. GMP не восстанавливает цифры, которые были потеряны раньше.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_init('010')), "\n";
echo gmp_strval(gmp_init('010', 10)), "\n";
echo gmp_strval(gmp_init('ff', 16)), "\n";
Ожидаемый результат
8
10
255
Артикул 010 вообще может быть текстовым идентификатором, который не надо преобразовывать в число. Для именно десятичного количества выбирайте основание 10.
<?php
declare(strict_types=1);
try {
$quantity = gmp_init('12 items', 10);
} catch (ValueError $error) {
echo "Некорректное целое\n";
}
Ожидаемый результат
Некорректное целое
Ошибка преобразования отличается от допустимого нуля. Не подставляйте 0 после любого исключения, если это изменит остаток или сумму операции.
Связанные операции: GMP::__construct; gmp_strval; gmp_add.
GMP::__constructСоздать объект большого целого через new вместо gmp_init.
new GMP(int|string $num = 0, int $base = 0)Создать объект большого целого через new вместо gmp_init.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | int либо строка целого. Пробельные символы внутри строки игнорируются; это не строгая проверка формата пользовательского ввода. |
| base | 0 — автоопределение; 2…62 — явное основание. При 0: 0x/0X — 16, 0b/0B — 2, 0o/0O или начальный 0 — 8, иначе 10. Поддержка 0o появилась в PHP 8.1. |
| Буквы | В основаниях до 36 регистр не важен. В 37…62 A…Z дают 10…35, a…z дают 36…61. |
| Ошибки | Некорректное основание или непригодная запись — ValueError; неподходящий тип — TypeError. Для форм отдельно ограничьте длину и допустимые символы. |
| По умолчанию | new GMP() хранит ноль. Публичный конструктор с параметрами доступен с PHP 8.2.4. |
| Класс | GMP окончательный (final) с PHP 8.4; арифметические операции предоставлены функциями и перегруженными операторами, а не методами add/mul. |
- new GMP
- num/base → точное целое
- Функции GMP или операторы
- Строковый результат
<?php
declare(strict_types=1);
$zero = new GMP();
$large = new GMP('100000000000000000001', 10);
echo gmp_strval($zero), "\n", gmp_strval($large), "\n";
Ожидаемый результат
0
100000000000000000001
new не запускает внешних процессов. Объект хранит значение, пригодное для дальнейшей точной арифметики.
<?php
declare(strict_types=1);
$counter = new GMP('100000000000000000001', 10);
$next = $counter + 1;
echo gmp_strval($next), "\n";
echo gmp_strval($counter), "\n";
Ожидаемый результат
100000000000000000002
100000000000000000001
Оператор + поддерживается GMP и возвращает результат. Исходный counter здесь не меняется. Это не означает, что все методы объекта неизменяемы: setbit/clrbit меняют сам объект.
Связанные операции: gmp_init; gmp_add; gmp_setbit.
gmp_strvalПолучить точную текстовую запись для вывода, JSON или хранения.
gmp_strval(GMP|int|string $num, int $base = 10): stringПолучить точную текстовую запись для вывода, JSON или хранения.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | GMP-объект или целое в поддерживаемом входном формате. |
| base | 2…62 либо -2…-36. Положительные основания до 36 используют строчные буквы; отрицательные — заглавные. По умолчанию 10. |
| Возврат | Строка числа, без автоматического сохранения ведущих нулей и исходных разделителей. |
| Ошибка | Недопустимое основание ValueError. Форматировать уже неточный float этой функцией нельзя. |
- GMP-значение
- Выбрать основание
- Строка точных цифр
- Передать без приведения к float
<?php
declare(strict_types=1);
$number = gmp_init(255);
echo gmp_strval($number), "\n";
echo gmp_strval($number, 16), "\n";
echo gmp_strval($number, -16), "\n";
echo gmp_strval($number, 2), "\n";
Ожидаемый результат
255
ff
FF
11111111
Это четыре записи одного значения. Основание не является настройкой памяти объекта; оно выбирается при текстовом представлении.
<?php
declare(strict_types=1);
$count = gmp_add('100000000000000000000', 7);
$payload = ['count' => gmp_strval($count)];
echo json_encode($payload, JSON_THROW_ON_ERROR), "\n";
Ожидаемый результат
{"count":"100000000000000000007"}
Поле count намеренно строковое по контракту API. Если отправить огромное число как JSON number, другой язык или JavaScript-клиент может округлить его. Не включайте JSON_NUMERIC_CHECK для такого payload.
Связанные операции: gmp_init; gmp_intval; gmp_export.
gmp_intvalПреобразовать GMP в обычный PHP int, только когда значение заведомо помещается.
gmp_intval(GMP|int|string $num): intПреобразовать GMP в обычный PHP int, только когда значение заведомо помещается.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Большое целое или принимаемая строковая запись. |
| Возврат | Машинный знаковый int. Полезен только в пределах PHP_INT_MIN…PHP_INT_MAX. |
| Ограничение | Не используйте переполнение как проверку границ и не полагайтесь на конкретный усечённый результат. Размер int зависит от платформы. |
- GMP-число
- Сравнить с границами int
- gmp_intval
- Обычное целое для API
<?php
declare(strict_types=1);
$quantity = gmp_init('42', 10);
if (gmp_cmp($quantity, PHP_INT_MIN) < 0 || gmp_cmp($quantity, PHP_INT_MAX) > 0) {
throw new RangeException('Не помещается в int');
}
var_dump(gmp_intval($quantity));
Ожидаемый результат
int(42)
Проверка происходит до преобразования. После неё число подходит параметру int стороннего API, если также выполнены его прикладные ограничения.
<?php
declare(strict_types=1);
$counter = gmp_init('100000000000000000001');
if (gmp_cmp($counter, PHP_INT_MAX) > 0) {
echo 'Keep as string: ', gmp_strval($counter), "\n";
}
Ожидаемый результат
Keep as string: 100000000000000000001
Для отображения число не обязано помещаться в int. gmp_strval выполняет задачу напрямую, без опасного промежуточного преобразования.
Связанные операции: gmp_cmp; gmp_strval.
gmp_importПревратить байты двоичного протокола в большое неотрицательное целое.
gmp_import(string $data, int $word_size = 1, int $flags = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN): GMPПревратить байты двоичного протокола в большое неотрицательное целое.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| data | Двоичная строка, не текст с шестнадцатеричными цифрами. Знак отдельно не закодирован; пустая строка соответствует нулю. |
| word_size | Число байтов в одном слове, минимум 1; длина data обязана делиться на word_size. |
| flags | Одно направление слов MSW_FIRST/LSW_FIRST и один порядок байтов внутри слова BIG_ENDIAN/LITTLE_ENDIAN/NATIVE_ENDIAN, объединённые |. |
| Возврат / ошибки | GMP; неправильный размер/противоречивые флаги ValueError. С PHP 8.0 отказ не возвращает false. |
- Байты пакета
- Разбить по word_size
- Применить порядок слов/байтов
- GMP-число без знака
<?php
declare(strict_types=1);
$bytes = "\x01\x02";
$counter = gmp_import($bytes, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN);
echo gmp_strval($counter), "\n";
Ожидаемый результат
258
0x01 идёт перед 0x02: 1×256 + 2 = 258. При word_size=1 внутри слова один байт; endian в этом случае ничего не переставляет.
<?php
declare(strict_types=1);
$bytes = "\x01\x02";
echo gmp_strval(gmp_import($bytes, 2, GMP_MSW_FIRST | GMP_BIG_ENDIAN)), "\n";
echo gmp_strval(gmp_import($bytes, 2, GMP_MSW_FIRST | GMP_LITTLE_ENDIAN)), "\n";
Ожидаемый результат
258
513
word_size=2 связывает оба байта в одно слово. Его порядок даёт либо 0x0102, либо 0x0201. NATIVE_ENDIAN не подходит для переносимого сетевого контракта без явного согласования.
<?php
declare(strict_types=1);
try {
gmp_import("\x01\x02\x03", 2, GMP_MSW_FIRST | GMP_BIG_ENDIAN);
} catch (ValueError $error) {
echo "Неполное двоичное слово\n";
}
Ожидаемый результат
Неполное двоичное слово
Три байта нельзя полностью разделить на слова по два. Не дополняйте данные нулём без разрешения формата: это изменит значение.
Связанные операции: gmp_export; gmp_strval.
gmp_exportЗаписать большое целое в байты с заданным порядком слов и байтов.
gmp_export(GMP|int|string $num, int $word_size = 1, int $flags = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN): stringЗаписать большое целое в байты с заданным порядком слов и байтов.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Экспортируется абсолютное значение. Отрицательный знак игнорируется; это не signed two's-complement формат. |
| word_size | Байты на слово; минимум 1. Длина результата кратна размеру слова, но это не фиксированная длина всего поля. |
| flags | Порядок слов и байтов как у gmp_import. |
| Возврат | Двоичная строка. Для нуля возвращается пустая строка. С PHP 8.0 ошибку не выражают false. |
| Ошибки | Неприемлемый размер слова/противоречивые флаги ValueError; не выделяйте гигантское слово по данным клиента. |
- GMP абсолютное значение
- Слова выбранного размера
- Байты в выбранном порядке
- Передача/файл протокола
<?php
declare(strict_types=1);
$bytes = gmp_export(258, 2, GMP_MSW_FIRST | GMP_BIG_ENDIAN);
echo bin2hex($bytes), "\n";
echo gmp_strval(gmp_import($bytes, 2, GMP_MSW_FIRST | GMP_BIG_ENDIAN)), "\n";
Ожидаемый результат
0102
258
bin2hex здесь только показывает байты для человека. В двоичный сокет отправляют $bytes, если протокол требует именно два байта, а не четыре символа 0102.
<?php
declare(strict_types=1);
echo bin2hex(gmp_export(-258, 2, GMP_MSW_FIRST | GMP_BIG_ENDIAN)), "\n";
echo strlen(gmp_export(0)), "\n";
Ожидаемый результат
0102
0
Отрицательное значение экспортировалось как положительное. Ноль занял ноль байтов. Если протокол требует знак/фиксированную ширину, кодируйте эти правила отдельно и сначала проверяйте диапазон.
Нельзя восстанавливать произвольное отрицательное целое простым import(export($n)): знак потерян по договору. Для JSON обычно проще десятичная строка; бинарное представление выбирают по внешнему формату. Сначала проверяйте размер результата, затем добавляйте нужное число ведущих нулей под фиксированную ширину поля.
Связанные операции: gmp_import; gmp_strval; gmp_sign.
GMP::__serializeПредоставить внутренние данные объекта механизму serialize.
public GMP::__serialize(): arrayПредоставить внутренние данные объекта механизму serialize.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| Аргументы | Нет. |
| Возврат | Массив состояния. В PHP 8.5.11 индекс 0 — шестнадцатеричная строка; необязательный индекс 1 содержит свойства объекта. Это внутренний формат PHP, не контракт JSON/API. |
| Версия | Метод доступен с PHP 8.1. Обычно вызывается автоматически через serialize($number). |
- Объект GMP
- __serialize → состояние
- serialize → строка PHP
- Восстановление только доверенных данных
<?php
declare(strict_types=1);
$number = gmp_init('100000000000000000001');
$stored = serialize($number);
$restored = unserialize($stored, ['allowed_classes' => [GMP::class]]);
echo gmp_strval($restored), "\n";
Ожидаемый результат
100000000000000000001
Строка создана самим приложением в этом примере. Не используйте unserialize для произвольного содержимого запроса; для передачи числа наружу достаточно gmp_strval.
<?php
declare(strict_types=1);
$number = gmp_init(255);
$state = $number->__serialize();
echo $state[0], "\n";
Ожидаемый результат
ff
Это демонстрация внутренней шестнадцатеричной записи в проверенной PHP 8.5.11. Прикладной код не должен зависеть от такого расположения полей, если ему нужна только текстовая запись числа.
Связанные операции: GMP::__unserialize; gmp_strval.
GMP::__unserializeВосстановить состояние GMP из массива, подготовленного __serialize.
public GMP::__unserialize(array $data): voidВосстановить состояние GMP из массива, подготовленного __serialize.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| data | Массив внутреннего состояния; в PHP 8.5.11 обязателен строковый индекс 0 с hex-числом, индекс 1 при наличии должен быть массивом свойств. |
| Возврат | void: меняет текущий объект. |
| Ошибки | Отсутствующее/неправильное число или неверные свойства приводят к Exception. Не передавайте произвольный клиентский массив как доверенное состояние. |
- Состояние от __serialize
- Проверка внутреннего формата
- Обновление существующего GMP
<?php
declare(strict_types=1);
$source = gmp_init(512);
$target = new GMP();
$target->__unserialize($source->__serialize());
echo gmp_strval($target), "\n";
Ожидаемый результат
512
Прямой вызов показан, чтобы объяснить механизм. Для обычного хранения целого строкой используйте gmp_init($text, 10): это понятнее и не привязывает к формату сериализации объектов.
<?php
declare(strict_types=1);
$number = new GMP();
try {
$number->__unserialize([]);
} catch (Exception $error) {
echo "Нет состояния GMP\n";
}
Ожидаемый результат
Нет состояния GMP
Пустой массив не означает число ноль. Ноль передают как число или корректную строку, а не как повреждённый пакет сериализации.
Связанные операции: GMP::__serialize; gmp_init.
gmp_addСложить два целых без потери точности.
gmp_add(GMP|int|string $num1, GMP|int|string $num2): GMPСложить два целых без потери точности.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Первое и второе целые; GMP, int или допустимая строка. Порядок особенно важен для вычитания. |
| Возврат | Новый GMP-результат. Переданные объекты сами по себе не изменяются. |
| Ошибки | Некорректная числовая строка ValueError; неподходящий тип TypeError. Большие входы требуют памяти и времени. |
- Первое целое
- Операция + со вторым
- Новый объект GMP
- gmp_strval → точный текст
<?php
declare(strict_types=1);
$result = gmp_add(12, 7);
echo gmp_strval($result), "\n";
Ожидаемый результат
19
Сначала выполняется арифметическая функция; затем gmp_strval делает результат читаемым текстом, echo выводит его.
<?php
declare(strict_types=1);
$events = gmp_init('100000000000000000000', 10);
$events = gmp_add($events, 750);
echo gmp_strval($events), "\n";
Ожидаемый результат
100000000000000000750
Счётчик продолжает храниться как GMP. Для записи в БД/JSON передайте десятичную строку и выберите поддерживающий её контракт.
Для простых чисел в пределах int обычный оператор часто понятнее и не требует расширения. Здесь GMP нужен ради диапазона целого, а не ради превращения всякого вычисления в объект. Если операнд — объект GMP, поддерживается и соответствующий арифметический оператор.
Связанные операции: gmp_sub; gmp_mul; gmp_strval.
gmp_subВычесть второе целое из первого.
gmp_sub(GMP|int|string $num1, GMP|int|string $num2): GMPВычесть второе целое из первого.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Первое и второе целые; GMP, int или допустимая строка. Порядок особенно важен для вычитания. |
| Возврат | Новый GMP-результат. Переданные объекты сами по себе не изменяются. |
| Ошибки | Некорректная числовая строка ValueError; неподходящий тип TypeError. Большие входы требуют памяти и времени. |
- Первое целое
- Операция − со вторым
- Новый объект GMP
- gmp_strval → точный текст
<?php
declare(strict_types=1);
$result = gmp_sub(12, 7);
echo gmp_strval($result), "\n";
Ожидаемый результат
5
Сначала выполняется арифметическая функция; затем gmp_strval делает результат читаемым текстом, echo выводит его.
<?php
declare(strict_types=1);
$before = gmp_init('100000000000000000000', 10);
$after = gmp_init('100000000000000000042', 10);
echo gmp_strval(gmp_sub($after, $before)), "\n";
Ожидаемый результат
42
Вычитание сохраняет небольшую разницу между огромными числами. Перевод обоих показаний во float до операции мог бы уничтожить эту разницу.
Для простых чисел в пределах int обычный оператор часто понятнее и не требует расширения. Здесь GMP нужен ради диапазона целого, а не ради превращения всякого вычисления в объект. Если операнд — объект GMP, поддерживается и соответствующий арифметический оператор.
gmp_mulУмножить два целых и сохранить все цифры.
gmp_mul(GMP|int|string $num1, GMP|int|string $num2): GMPУмножить два целых и сохранить все цифры.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Первое и второе целые; GMP, int или допустимая строка. Порядок особенно важен для вычитания. |
| Возврат | Новый GMP-результат. Переданные объекты сами по себе не изменяются. |
| Ошибки | Некорректная числовая строка ValueError; неподходящий тип TypeError. Большие входы требуют памяти и времени. |
- Первое целое
- Операция × со вторым
- Новый объект GMP
- gmp_strval → точный текст
<?php
declare(strict_types=1);
$result = gmp_mul(12, 7);
echo gmp_strval($result), "\n";
Ожидаемый результат
84
Сначала выполняется арифметическая функция; затем gmp_strval делает результат читаемым текстом, echo выводит его.
<?php
declare(strict_types=1);
$first = gmp_init('1000000000000', 10);
$second = gmp_init('1000000000000', 10);
echo gmp_strval(gmp_mul($first, $second)), "\n";
Ожидаемый результат
1000000000000000000000000
Если один выбор допускает first вариантов, а независимый второй — second, произведение считает пары. Это подсчёт количества, а не материализация всех комбинаций в массиве.
Для простых чисел в пределах int обычный оператор часто понятнее и не требует расширения. Здесь GMP нужен ради диапазона целого, а не ради превращения всякого вычисления в объект. Если операнд — объект GMP, поддерживается и соответствующий арифметический оператор.
gmp_absПолучить величину изменения независимо от его направления.
gmp_abs(GMP|int|string $num): GMPПолучить величину изменения независимо от его направления.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое любого знака. |
| Возврат | Неотрицательное GMP-значение: модуль num, исходный объект не меняется. |
- −42: уменьшение
- Убрать знак
- 42: размер изменения
<?php
declare(strict_types=1);
echo gmp_strval(gmp_abs(-42)), "\n";
echo gmp_strval(gmp_abs(0)), "\n";
Ожидаемый результат
42
0
Модуль показывает расстояние до нуля, а не направление. Для нуля результат тоже ноль.
<?php
declare(strict_types=1);
$expected = gmp_init('100000000000000000050', 10);
$actual = gmp_init('100000000000000000008', 10);
$distance = gmp_abs(gmp_sub($actual, $expected));
echo gmp_strval($distance), "\n";
var_dump(gmp_cmp($distance, 10) > 0);
Ожидаемый результат
42
bool(true)
Расхождение больше допустимых 10 единиц независимо от того, какое показание больше. Направление при необходимости храните отдельно, до abs.
gmp_negИзменить знак целого: поступление превратить в обратное изменение.
gmp_neg(GMP|int|string $num): GMPИзменить знак целого: поступление превратить в обратное изменение.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое в поддерживаемом формате. |
| Возврат | Новый GMP, равный -num. Отрицательное становится положительным, ноль остаётся нулём. |
- Изменение +250
- Противоположное действие
- Изменение −250
<?php
declare(strict_types=1);
echo gmp_strval(gmp_neg(250)), "\n";
echo gmp_strval(gmp_neg(-250)), "\n";
Ожидаемый результат
-250
250
Это смена знака, а не операция «сделать отрицательным всегда». У уже отрицательного значения получится положительное.
<?php
declare(strict_types=1);
$delta = gmp_init('100000000000000000000', 10);
$reversal = gmp_neg($delta);
echo gmp_strval(gmp_add($delta, $reversal)), "\n";
Ожидаемый результат
0
Сумма изменения и его точной компенсации равна нулю. В журнале сервиса нужна также связь с исходной операцией и защита от повторного применения; арифметика этого не обеспечивает.
gmp_cmpСравнить два больших целых по значению.
gmp_cmp(GMP|int|string $num1, GMP|int|string $num2): intСравнить два больших целых по значению.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Сравниваемые целые. |
| Возврат | Отрицательное целое если num1 < num2; ноль при равенстве; положительное при num1 > num2. Проверяйте знак, не конкретно -1/+1. |
- Два значения
- Числовое сравнение
- Меньше / равно / больше
<?php
declare(strict_types=1);
var_dump(gmp_cmp(12, 20) < 0);
var_dump(gmp_cmp('20', 20) === 0);
var_dump(gmp_cmp(25, 20) > 0);
Ожидаемый результат
bool(true)
bool(true)
bool(true)
Строка 20 и целое 20 означают одно число. Числовое сравнение отличается от сравнения длины строки или идентичности объектов через ===.
<?php
declare(strict_types=1);
$total = gmp_init('100000000000000000001', 10);
$limit = gmp_init('100000000000000000000', 10);
echo gmp_cmp($total, $limit) > 0 ? "Лимит превышен\n" : "В пределах лимита\n";
Ожидаемый результат
Лимит превышен
Одна последняя цифра меняет решение. Преобразование во float могло бы сделать эти значения неразличимыми. Для конкурентного изменения лимита нужна также атомарная проверка в хранилище.
Связанные операции: gmp_sign; gmp_intval; gmp_sub.
gmp_signУзнать только направление значения: отрицательное, нулевое или положительное.
gmp_sign(GMP|int|string $num): intУзнать только направление значения: отрицательное, нулевое или положительное.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое; GMP/int/строка. Число не обязано помещаться в машинный int. |
| Возврат | Именно -1, 0 или 1 соответственно знаку числа. |
- Целое изменение
- Проверка знака
- −1 / 0 / 1 для выбора ветки
<?php
declare(strict_types=1);
echo gmp_sign(-12), '/', gmp_sign(0), '/', gmp_sign(12), "\n";
Ожидаемый результат
-1/0/1
В отличие от cmp, который сравнивает два значения, sign сравнивает одно значение с нулём.
<?php
declare(strict_types=1);
$change = gmp_init('-100000000000000000000', 10);
$label = match (gmp_sign($change)) {
-1 => 'Уменьшение',
0 => 'Без изменения',
1 => 'Увеличение',
};
echo $label, ': ', gmp_strval(gmp_abs($change)), "\n";
Ожидаемый результат
Уменьшение: 100000000000000000000
match выбирает подпись по возвращённому int, а abs даёт величину. Представление не меняет исходную операцию; знак нельзя терять при сохранении данных.
gmp_div_qПолучить целую часть деления с явно выбранным направлением округления.
gmp_div_q(GMP|int|string $num1, GMP|int|string $num2, int $rounding_mode = GMP_ROUND_ZERO): GMPПолучить целую часть деления с явно выбранным направлением округления.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Делимое: сколько целых единиц имеется. |
| num2 | Ненулевой делитель. Ноль вызывает DivisionByZeroError. |
| rounding_mode | GMP_ROUND_ZERO — к нулю; GMP_ROUND_PLUSINF — вверх к +∞; GMP_ROUND_MINUSINF — вниз к −∞. Иное значение ValueError. |
| Возврат | GMP-частное q. Дробная часть не возвращается. |
- 25 единиц / упаковка по 6
- Частное 4 с остатком
- q = 4 полных упаковки
<?php
declare(strict_types=1);
echo gmp_strval(gmp_div_q(25, 6)), "\n";
echo gmp_strval(gmp_div_q(25, 6, GMP_ROUND_PLUSINF)), "\n";
Ожидаемый результат
4
5
Четыре полные коробки вместят 24 единицы; чтобы разместить все 25, нужна пятая неполная. Округление выбирает бизнес-смысл результата.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_div_q(-25, 6, GMP_ROUND_ZERO)), "\n";
echo gmp_strval(gmp_div_q(-25, 6, GMP_ROUND_MINUSINF)), "\n";
Ожидаемый результат
-4
-5
На отрицательных значениях к нулю и вниз расходятся. Например, вычисление номера блока слева от начала координат обычно требует пола, а не усечения.
Связанные операции: gmp_div_qr; gmp_div_r; gmp_div.
gmp_divИспользовать старое краткое имя gmp_div_q с тем же договором.
gmp_div(GMP|int|string $num1, GMP|int|string $num2, int $rounding_mode = GMP_ROUND_ZERO): GMPИспользовать старое краткое имя gmp_div_q с тем же договором.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Делимое: сколько целых единиц имеется. |
| num2 | Ненулевой делитель. Ноль вызывает DivisionByZeroError. |
| rounding_mode | GMP_ROUND_ZERO — к нулю; GMP_ROUND_PLUSINF — вверх к +∞; GMP_ROUND_MINUSINF — вниз к −∞. Иное значение ValueError. |
| Возврат | GMP-целое частное. Это алиас gmp_div_q, не отдельный алгоритм и не дробное деление. |
- Вызов gmp_div
- То же целое деление, что div_q
- GMP-частное
<?php
declare(strict_types=1);
echo gmp_strval(gmp_div(25, 6)), "\n";
var_dump(gmp_cmp(gmp_div(25, 6), gmp_div_q(25, 6)) === 0);
Ожидаемый результат
4
bool(true)
Поведение одинаково. В новом коде суффикс _q помогает рядом с _r и _qr увидеть, какая часть результата нужна.
<?php
declare(strict_types=1);
$blocks = gmp_div(25, 6, GMP_ROUND_PLUSINF);
echo gmp_strval($blocks), "\n";
Ожидаемый результат
5
Если переименовываете вызов в gmp_div_q, сохраните третий аргумент. Потеря режима превратит 5 требуемых блоков в 4.
Связанные операции: gmp_div_q; gmp_div_qr.
gmp_div_rПолучить остаток, согласованный с выбранным округлением частного.
gmp_div_r(GMP|int|string $num1, GMP|int|string $num2, int $rounding_mode = GMP_ROUND_ZERO): GMPПолучить остаток, согласованный с выбранным округлением частного.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Делимое: сколько целых единиц имеется. |
| num2 | Ненулевой делитель. Ноль вызывает DivisionByZeroError. |
| rounding_mode | GMP_ROUND_ZERO — к нулю; GMP_ROUND_PLUSINF — вверх к +∞; GMP_ROUND_MINUSINF — вниз к −∞. Иное значение ValueError. |
| Возврат | GMP-остаток r = num1 − q×num2. При режиме к нулю ненулевой r имеет знак делимого; для других режимов знак может отличаться. |
- 25 = 4×6 + 1
- Выбран режим частного
- r = 1 оставшаяся единица
<?php
declare(strict_types=1);
echo gmp_strval(gmp_div_r(25, 6)), "\n";
Ожидаемый результат
1
После четырёх комплектов по шесть останется одна единица. Если нужны и комплекты, и остаток, выбирайте gmp_div_qr.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_div_r(-25, 6, GMP_ROUND_ZERO)), "\n";
echo gmp_strval(gmp_div_r(-25, 6, GMP_ROUND_MINUSINF)), "\n";
Ожидаемый результат
-1
5
При q=-4 остаток -1; при q=-5 остаток 5. Оба восстанавливают -25. Для всегда неотрицательного остатка по модулю есть gmp_mod.
Связанные операции: gmp_div_q; gmp_div_qr; gmp_mod.
gmp_div_qrОдним вызовом получить число полных групп и остаток.
gmp_div_qr(GMP|int|string $num1, GMP|int|string $num2, int $rounding_mode = GMP_ROUND_ZERO): arrayОдним вызовом получить число полных групп и остаток.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Делимое: сколько целых единиц имеется. |
| num2 | Ненулевой делитель. Ноль вызывает DivisionByZeroError. |
| rounding_mode | GMP_ROUND_ZERO — к нулю; GMP_ROUND_PLUSINF — вверх к +∞; GMP_ROUND_MINUSINF — вниз к −∞. Иное значение ValueError. |
| Возврат | Массив [0 => GMP q, 1 => GMP r], где num1 = q×num2 + r. Оба элемента — GMP, не машинные int. |
- 25 единиц, размер группы 6
- Одно деление
- [4 полные группы, 1 остаток]
<?php
declare(strict_types=1);
[$boxes, $remainder] = gmp_div_qr(25, 6);
echo 'Boxes: ', gmp_strval($boxes), ', left: ', gmp_strval($remainder), "\n";
Ожидаемый результат
Boxes: 4, left: 1
Квадратные скобки слева распаковывают массив результата: первый элемент попадает в boxes, второй в remainder.
<?php
declare(strict_types=1);
try {
[$groups, $left] = gmp_div_qr(25, 0);
} catch (DivisionByZeroError $error) {
echo "Размер группы не может быть нулём\n";
}
Ожидаемый результат
Размер группы не может быть нулём
Для реальных коробок дополнительно запрещают отрицательный размер. Это прикладная проверка поверх математического договора функции.
gmp_modПолучить неотрицательный остаток для циклической нумерации или модульной арифметики.
gmp_mod(GMP|int|string $num1, GMP|int|string $num2): GMPПолучить неотрицательный остаток для циклической нумерации или модульной арифметики.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Целое любого знака. |
| num2 | Ненулевой модуль; знак игнорируется. Ноль DivisionByZeroError. |
| Возврат | GMP r, 0 ≤ r < abs(num2). Режима округления у этой функции нет. |
- Индекс −1
- Модуль 7
- Позиция 6 в цикле 0…6
<?php
declare(strict_types=1);
echo gmp_strval(gmp_mod(-1, 7)), "\n";
echo gmp_strval(gmp_mod(-1, -7)), "\n";
Ожидаемый результат
6
6
При циклической нумерации отрицательный шаг приводит к последней позиции. Знак модуля не меняет результат.
<?php
declare(strict_types=1);
$sequence = gmp_init('100000000000000000001', 10);
$bucket = gmp_mod($sequence, 8);
echo gmp_strval($bucket), "\n";
Ожидаемый результат
1
Результат лежит в 0…7. Такая группировка не является криптографическим хешем и не обеспечивает равномерность произвольных идентификаторов сама по себе.
Связанные операции: gmp_div_r; gmp_powm; gmp_div_qr.
gmp_divexactВыполнить точное деление, когда делимость уже гарантирована.
gmp_divexact(GMP|int|string $num1, GMP|int|string $num2): GMPВыполнить точное деление, когда делимость уже гарантирована.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Целые; num2 должен делить num1 без остатка. |
| Возврат | GMP-частное. При нарушении делимости результат не определён договором; функция не является её проверкой. |
| Ошибка | Нулевой делитель DivisionByZeroError. Не ожидайте исключения только потому, что остаток не нулевой. |
- Доказанная делимость
- Специализированное точное деление
- Целый результат
<?php
declare(strict_types=1);
$units = gmp_init('100000000000000000000', 10);
$packed = gmp_mul($units, 6);
echo gmp_strval(gmp_divexact($packed, 6)), "\n";
Ожидаемый результат
100000000000000000000
Делимость здесь следует из предыдущего умножения на 6. Такой контракт может быть частью алгоритма, а не проверкой каждого шага.
<?php
declare(strict_types=1);
$units = gmp_init(25);
$size = gmp_init(6);
if (gmp_cmp(gmp_mod($units, $size), 0) !== 0) {
echo "Нельзя разделить на полные комплекты\n";
} else {
echo gmp_strval(gmp_divexact($units, $size)), "\n";
}
Ожидаемый результат
Нельзя разделить на полные комплекты
Когда проверка остатка всё равно необходима, gmp_div_qr часто удобнее: сразу даёт обе части без второго деления. Специальный алгоритм не означает безусловный выигрыш всей программы.
Связанные операции: gmp_div_qr; gmp_mod; gmp_mul.
gmp_powВозвести целое в целую неотрицательную степень без потери цифр.
gmp_pow(GMP|int|string $num, int $exponent): GMPВозвести целое в целую неотрицательную степень без потери цифр.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Основание любого знака; GMP/int/строка целого. |
| exponent | Неотрицательный PHP int; отрицательное значение ValueError. Огромную строку показателя здесь передавать нельзя. |
| Возврат | Новый GMP. Нулевая степень даёт 1, включая 0 в степени 0 по договору функции. |
- Количество вариантов на шаг
- Число независимых шагов
- Точное количество последовательностей
<?php
declare(strict_types=1);
echo gmp_strval(gmp_pow(2, 10)), "\n";
echo gmp_strval(gmp_pow(0, 0)), "\n";
Ожидаемый результат
1024
1
2 в степени 10 — произведение десяти двоек. Эта функция не вычисляет дробные степени и не возвращает вещественное приближение.
<?php
declare(strict_types=1);
$variants = gmp_pow(16, 20);
echo gmp_strval($variants), "\n";
Ожидаемый результат
1208925819614629174706176
У каждой из 20 позиций по 16 вариантов. Число последовательностей вычислено без их создания. Большой результат всё равно занимает память: ограничивайте показатель и длину входа, особенно при пользовательском управлении ими.
Если далее нужен только остаток по модулю, используйте gmp_powm: не требуется сначала строить огромное промежуточное число. Для обычного PHP возведения в степень есть оператор **, но переполнение int приводит к другой модели точности.
gmp_powmСразу вычислить остаток от степени, не материализуя саму огромную степень.
gmp_powm(GMP|int|string $num, GMP|int|string $exponent, GMP|int|string $modulus): GMPСразу вычислить остаток от степени, не материализуя саму огромную степень.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Основание целое. |
| exponent | Неотрицательное целое, в том числе GMP или большая строка; в PHP 8.5 отрицательное значение ValueError. |
| modulus | Ненулевое целое; для прикладной модульной арифметики обычно положительное. Ноль DivisionByZeroError. |
| Возврат | GMP: num в степени exponent по модулю modulus. |
- Основание и показатель
- Возведение с сокращением по модулю
- Небольшой остаток
<?php
declare(strict_types=1);
echo gmp_strval(gmp_powm(3, 4, 5)), "\n";
echo gmp_strval(gmp_mod(gmp_pow(3, 4), 5)), "\n";
Ожидаемый результат
1
1
81 делится на 5 с остатком 1. Второй способ показан только для проверки на маленьких числах; на больших он может создать ненужный огромный промежуточный результат.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_powm(2, '100000000000000000000', 3)), "\n";
try {
gmp_powm(2, -1, 5);
} catch (ValueError $error) {
echo "Показатель должен быть неотрицательным\n";
}
Ожидаемый результат
1
Показатель должен быть неотрицательным
Строка показателя не помещается в обычный int, но подходит этому API. Остатки степеней двойки по модулю 3 чередуются; у чётной степени остаток 1. Это математический инструмент, а не готовая безопасная реализация шифрования.
Связанные операции: gmp_pow; gmp_mod; gmp_invert.
gmp_sqrtПолучить целую часть квадратного корня точно, без float.
gmp_sqrt(GMP|int|string $num): GMPПолучить целую часть квадратного корня точно, без float.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Неотрицательное целое; отрицательное ValueError. |
| Возврат | GMP r, для которого r² ≤ num < (r+1)². Это округление вниз, не ближайшее целое. |
- Количество элементов
- Сторона полного квадрата
- Целое число
<?php
declare(strict_types=1);
echo gmp_strval(gmp_sqrt(25)), "\n";
echo gmp_strval(gmp_sqrt(26)), "\n";
Ожидаемый результат
5
5
При 26 шестая строка квадратной раскладки ещё не заполнена; целая сторона остаётся 5.
<?php
declare(strict_types=1);
$tiles = gmp_init('100000000000000000001', 10);
$side = gmp_sqrt($tiles);
$left = gmp_sub($tiles, gmp_mul($side, $side));
echo gmp_strval($side), ' / ', gmp_strval($left), "\n";
Ожидаемый результат
10000000000 / 1
Сторона и остаток сохраняют точность для большого количества. Если обе величины нужны сразу, короче вызвать gmp_sqrtrem.
Связанные операции: gmp_sqrtrem; gmp_perfect_square; gmp_root.
gmp_sqrtremПолучить квадратный корень и остаток одной операцией.
gmp_sqrtrem(GMP|int|string $num): arrayПолучить квадратный корень и остаток одной операцией.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Неотрицательное целое; отрицательное ValueError. |
| Возврат | Массив из двух GMP: [целая часть корня, num − корень²]. Остаток 0 означает точный квадрат. |
- Количество плиток
- [сторона, остаток]
- Проверка точного квадрата
<?php
declare(strict_types=1);
[$side, $left] = gmp_sqrtrem(29);
echo gmp_strval($side), "\n";
echo gmp_strval($left), "\n";
Ожидаемый результат
5
4
5² = 25, а 29 − 25 = 4. Остаток — целое число после вычитания квадрата, а не дробная часть корня.
<?php
declare(strict_types=1);
foreach ([36, 37] as $number) {
[$root, $remainder] = gmp_sqrtrem($number);
echo $number, ': ', gmp_cmp($remainder, 0) === 0 ? 'square' : 'not square', "\n";
}
Ожидаемый результат
36: square
37: not square
Если сам корень не нужен, gmp_perfect_square выражает проверку напрямую.
Связанные операции: gmp_sqrt; gmp_perfect_square; gmp_rootrem.
gmp_rootВычислить целую часть корня заданной степени.
gmp_root(GMP|int|string $num, int $nth): GMPВычислить целую часть корня заданной степени.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое; отрицательное допустимо только при нечётном nth. |
| nth | Положительный PHP int; 0/отрицательное ValueError. Чётный корень отрицательного числа ValueError. |
| Возврат | GMP, целая часть корня. Для отрицательных нечётных корней усечение идёт к нулю. |
- Количество трёхмерных ячеек
- Корень степени 3
- Целая длина стороны
<?php
declare(strict_types=1);
echo gmp_strval(gmp_root(28, 3)), "\n";
echo gmp_strval(gmp_root(-28, 3)), "\n";
Ожидаемый результат
3
-3
3³ = 27, а (−3)³ = −27. Результат −3 не является округлением к минус бесконечности.
<?php
declare(strict_types=1);
$cells = gmp_init('1000000000000000000000000', 10);
echo gmp_strval(gmp_root($cells, 3)), "\n";
Ожидаемый результат
100000000
Здесь данные — количество, поэтому область num ≥ 0 дополнительно следует из задачи. Корень высшей степени не означает, что нужно создавать многомерный массив из всех ячеек.
Связанные операции: gmp_rootrem; gmp_pow; gmp_sqrt.
gmp_rootremПолучить целый корень n-й степени вместе с невместившимся остатком.
gmp_rootrem(GMP|int|string $num, int $nth): arrayПолучить целый корень n-й степени вместе с невместившимся остатком.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num / nth | Как у gmp_root: nth > 0; отрицательное num разрешено только с нечётной степенью. |
| Возврат | Два GMP: [r, num − r^nth]. При отрицательном num остаток может быть отрицательным. |
| Ошибки | Неподходящая степень или чётный корень отрицательного числа ValueError. |
- Объём
- Целая сторона и остаток
- Полный куб плюс оставшиеся ячейки
<?php
declare(strict_types=1);
[$side, $left] = gmp_rootrem(30, 3);
echo gmp_strval($side), ' / ', gmp_strval($left), "\n";
Ожидаемый результат
3 / 3
Три по каждой стороне дают 27 ячеек; остаются три. Остаток от корня отличается от остатка обычного деления.
<?php
declare(strict_types=1);
[$root, $remainder] = gmp_rootrem(-30, 3);
$restored = gmp_add(gmp_pow($root, 3), $remainder);
echo gmp_strval($root), ' / ', gmp_strval($remainder), "\n";
echo gmp_strval($restored), "\n";
Ожидаемый результат
-3 / -3
-30
Тождество r^nth + remainder = num помогает проверить смысл пары результатов.
Связанные операции: gmp_root; gmp_pow; gmp_sqrtrem.
gmp_perfect_squareПроверить, является ли целое квадратом целого числа.
gmp_perfect_square(GMP|int|string $num): boolПроверить, является ли целое квадратом целого числа.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое любого знака; для отрицательного результат false. |
| Возврат | true для точного квадрата, включая 0 и 1; иначе false. |
- Целое количество
- Существует ли целая квадратная сторона?
- true / false
<?php
declare(strict_types=1);
foreach ([-4, 0, 1, 24, 25] as $number) {
echo $number, ': ', gmp_perfect_square($number) ? 'yes' : 'no', "\n";
}
Ожидаемый результат
-4: no
0: yes
1: yes
24: no
25: yes
Это проверка точной целой арифметики; сравнение sqrt(float) с округлённым значением для огромных чисел не равноценная замена.
<?php
declare(strict_types=1);
$count = gmp_init('100000000000000000000', 10);
if (gmp_perfect_square($count)) {
echo 'Side: ', gmp_strval(gmp_sqrt($count)), "\n";
}
Ожидаемый результат
Side: 10000000000
Если нужны одновременно проверка и корень, gmp_sqrtrem может избежать отдельной операции проверки.
Связанные операции: gmp_sqrtrem; gmp_sqrt; gmp_perfect_power.
gmp_perfect_powerПроверить, представимо ли число как целая степень с показателем больше единицы.
gmp_perfect_power(GMP|int|string $num): boolПроверить, представимо ли число как целая степень с показателем больше единицы.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое любого знака. |
| Возврат | true, если num = a^b для целых a и b > 1. Отрицательные числа возможны при нечётном показателе; 0, 1 и −1 тоже считаются степенями. |
| Ограничение | Функция не возвращает основание и показатель; true не означает именно квадрат. |
- Число
- Поиск признака совершенной степени
- Логический ответ
<?php
declare(strict_types=1);
foreach ([16, 27, 12, -8, -1, 0, 1] as $number) {
echo $number, ': ', gmp_perfect_power($number) ? 'yes' : 'no', "\n";
}
Ожидаемый результат
16: yes
27: yes
12: no
-8: yes
-1: yes
0: yes
1: yes
27 — куб, но не квадрат. Отрицательное −8 = (−2)³ тоже удовлетворяет условию.
<?php
declare(strict_types=1);
$candidates = ['64', '65', '81'];
foreach ($candidates as $candidate) {
if (gmp_perfect_power($candidate)) {
echo $candidate, "\n";
}
}
Ожидаемый результат
64
81
Такой фильтр применяется в задачах целочисленной математики. Он не доказывает простоту и не заменяет разложение на множители; если нужен только квадрат, выбирайте более конкретную функцию.
Связанные операции: gmp_perfect_square; gmp_root; gmp_prob_prime.
gmp_factСосчитать число перестановок n различных элементов: n факториал.
gmp_fact(GMP|int|string $num): GMPСосчитать число перестановок n различных элементов: n факториал.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Неотрицательное целое; отрицательное ValueError. Ограничьте прикладной диапазон небольшим разумным пределом. |
| Возврат | GMP: произведение 1…num; 0! = 1. |
| Предел | Большой точный результат не означает безгранично допустимый аргумент. Реализация передаёт аргумент библиотеке через машинное unsigned long; не подавайте произвольно огромное GMP-значение. |
- n различных элементов
- Все возможные перестановки
- n! вариантов
<?php
declare(strict_types=1);
echo gmp_strval(gmp_fact(3)), "\n";
echo gmp_strval(gmp_fact(0)), "\n";
Ожидаемый результат
6
1
Для A, B, C есть шесть порядков. Единственная перестановка пустого набора — пустой порядок; поэтому 0! равно 1.
<?php
declare(strict_types=1);
$taskCount = 25;
if ($taskCount < 0 || $taskCount > 1000) {
throw new InvalidArgumentException('Недопустимое число заданий');
}
echo gmp_strval(gmp_fact($taskCount)), "\n";
Ожидаемый результат
15511210043330985984000000
Посчитать число вариантов значительно проще, чем перебрать их. Факториал быстро растёт; в оптимизации расписаний это повод выбирать другой алгоритм, а не создавать все перестановки.
Связанные операции: gmp_binomial; gmp_mul; gmp_pow.
gmp_binomialСосчитать выбор k элементов из n без учёта порядка.
gmp_binomial(GMP|int|string $n, int $k): GMPСосчитать выбор k элементов из n без учёта порядка.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| n | Целое; отрицательное n поддерживается как обобщённый биномиальный коэффициент. |
| k | Неотрицательный PHP int; отрицательное ValueError. |
| Возврат | GMP: число сочетаний при обычных n ≥ 0. При k = 0 результат 1, при k > n ≥ 0 результат 0. |
- n разных позиций
- Выбрать k без порядка
- Количество сочетаний
<?php
declare(strict_types=1);
echo gmp_strval(gmp_binomial(5, 2)), "\n";
echo gmp_strval(gmp_binomial(5, 6)), "\n";
Ожидаемый результат
10
0
Пара A–B и B–A считается одним выбором. Поэтому это сочетания, не перестановки и не выбор с возвращением.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_binomial(100, 50)), "\n";
echo gmp_strval(gmp_binomial(-3, 2)), "\n";
Ожидаемый результат
100891344545564193334812497256
6
Первое число показывает, насколько велик полный перебор половины из 100 разных опций. Второй вызов демонстрирует математическое расширение: (−3)(−4)/2 = 6; это не выбор людей из отрицательного количества.
Связанные операции: gmp_fact; gmp_mul; gmp_divexact.
gmp_andОставить биты, установленные в обеих масках.
gmp_and(GMP|int|string $num1, GMP|int|string $num2): GMPОставить биты, установленные в обеих масках.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Два целых числа. Для прикладных масок обычно неотрицательные. |
| Возврат | Новый GMP; исходные объекты не меняются. |
| Отрицательные | Логические операции ведут себя как над дополнением до двух с неограниченным знаковым расширением. Это не фиксированное 8/32/64-битное поле. |
- Первая маска
- Сравнить соответствующие биты со второй
- Новая маска
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_and(12, 10)), "\n";
Ожидаемый результат
8
1100 AND 1010 = 1000. Двоичную запись результата можно получить gmp_strval($result, 2).
<?php
declare(strict_types=1);
$requested = gmp_init('1101', 2);
$allowed = gmp_init('1011', 2);
echo gmp_strval(gmp_and($requested, $allowed), 2), "\n";
Ожидаемый результат
1001
Разрешены только позиции, в которых обе маски имеют 1. Это операция над данными; сама проверка полномочий пользователя должна происходить на сервере.
Связанные операции: gmp_or; gmp_xor; gmp_testbit.
gmp_orУстановить биты, присутствующие хотя бы в одной маске.
gmp_or(GMP|int|string $num1, GMP|int|string $num2): GMPУстановить биты, присутствующие хотя бы в одной маске.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Два целых числа. Для прикладных масок обычно неотрицательные. |
| Возврат | Новый GMP; исходные объекты не меняются. |
| Отрицательные | Логические операции ведут себя как над дополнением до двух с неограниченным знаковым расширением. Это не фиксированное 8/32/64-битное поле. |
- Первая маска
- Сравнить соответствующие биты со второй
- Новая маска
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_or(12, 10)), "\n";
Ожидаемый результат
14
1100 OR 1010 = 1110. Двоичную запись результата можно получить gmp_strval($result, 2).
<?php
declare(strict_types=1);
$basic = gmp_init('0011', 2);
$optional = gmp_init('1100', 2);
echo gmp_strval(gmp_or($basic, $optional), 2), "\n";
Ожидаемый результат
1111
OR объединяет позиции и не считает дубликаты. Если одна возможность включена в обоих наборах, её бит остаётся одной единицей.
Связанные операции: gmp_and; gmp_xor; gmp_setbit.
gmp_xorНайти биты, различающиеся в двух масках.
gmp_xor(GMP|int|string $num1, GMP|int|string $num2): GMPНайти биты, различающиеся в двух масках.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Два целых числа. Для прикладных масок обычно неотрицательные. |
| Возврат | Новый GMP; исходные объекты не меняются. |
| Отрицательные | Логические операции ведут себя как над дополнением до двух с неограниченным знаковым расширением. Это не фиксированное 8/32/64-битное поле. |
- Первая маска
- Сравнить соответствующие биты со второй
- Новая маска
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_xor(12, 10)), "\n";
Ожидаемый результат
6
1100 XOR 1010 = 0110. Двоичную запись результата можно получить gmp_strval($result, 2).
<?php
declare(strict_types=1);
$before = gmp_init('1011', 2);
$after = gmp_init('1101', 2);
$changed = gmp_xor($before, $after);
echo gmp_strval($changed, 2), "\n";
echo gmp_popcount($changed), "\n";
Ожидаемый результат
110
2
Изменились две позиции. XOR показывает отличие, но не направление изменения; за новым значением конкретного флага обращаются к after.
Связанные операции: gmp_and; gmp_or; gmp_hamdist.
gmp_comИнвертировать все биты целого числа.
gmp_com(GMP|int|string $num): GMPИнвертировать все биты целого числа.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое любого знака. |
| Возврат | GMP: побитовое дополнение, математически −num−1. |
| Ширина | Функция не знает, что прикладное поле должно быть ровно байтом. Для конечной ширины дополнительно применяют маску. |
- Число
- Поменять 0 и 1 с учётом знакового расширения
- GMP, возможно отрицательный
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
echo gmp_strval(gmp_com(0)), "\n";
echo gmp_strval(gmp_com(5)), "\n";
Ожидаемый результат
-1
-6
Без ограничения ширины инвертируются и все старшие нулевые биты. Это не результат 255 или 250, пока мы не выбрали именно восемь бит.
<?php
declare(strict_types=1);
$value = gmp_init(5);
$byteMask = gmp_init(255);
$invertedByte = gmp_and(gmp_com($value), $byteMask);
echo gmp_strval($invertedByte), "\n";
echo gmp_strval($invertedByte, 2), "\n";
Ожидаемый результат
250
11111010
AND с 255 оставляет восемь младших бит. Для протокольного поля ширину и порядок байтов задают явно, а не выводят из числа.
Связанные операции: gmp_and; gmp_xor; gmp_export.
gmp_setbitИзменить один бит в уже созданном объекте GMP.
gmp_setbit(GMP $num, int $index, bool $value = true): voidИзменить один бит в уже созданном объекте GMP.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Именно объект GMP; передать вместо него int/string нельзя. |
| index | Неотрицательный индекс от младшего бита 0; выход за поддерживаемый диапазон ValueError. Ограничивайте прикладную максимальную позицию. |
| value | true устанавливает бит в 1, false очищает его. |
| Возврат | void: изменяется num, нового числа функция не возвращает. |
- Объект маски
- Изменить одну позицию
- Тот же объект с новым состоянием
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
$mask = gmp_init(0);
gmp_setbit($mask, 3);
echo gmp_strval($mask), "\n";
gmp_setbit($mask, 3, false);
echo gmp_strval($mask), "\n";
Ожидаемый результат
8
0
Позиция 3 имеет вес 8. Не пишите mask = gmp_setbit(...): полезный эффект находится в переданном объекте, а не в возвращаемом значении.
<?php
declare(strict_types=1);
$original = gmp_init(1);
$alias = $original;
$copy = clone $original;
gmp_setbit($alias, 5);
echo gmp_strval($original), "\n";
echo gmp_strval($copy), "\n";
Ожидаемый результат
33
1
alias и original обозначают один объект, поэтому изменение видно через оба имени. clone создаёт независимый объект GMP. Большой пользовательский index способен потребовать много памяти.
Связанные операции: gmp_clrbit; gmp_testbit; gmp_or.
gmp_clrbitОчистить конкретный бит, сохранив остальные позиции маски.
gmp_clrbit(GMP $num, int $index): voidОчистить конкретный бит, сохранив остальные позиции маски.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Изменяемый объект GMP, не int/string. |
| index | Неотрицательная позиция с индексом 0 справа; недопустимая позиция ValueError. |
| Возврат | void; бит становится 0. Повторная очистка уже нулевого бита не меняет число. |
- Текущая маска
- Снять один флаг
- Изменённый исходный объект
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
$mask = gmp_init(7);
gmp_clrbit($mask, 2);
echo gmp_strval($mask), "\n";
Ожидаемый результат
3
111₂ превращается в 011₂. Вычитание 4 было бы неверной общей заменой: если бит уже был 0, оно изменило бы другие позиции.
<?php
declare(strict_types=1);
$mask = gmp_init(3);
gmp_clrbit($mask, 2);
gmp_clrbit($mask, 2);
echo gmp_strval($mask), "\n";
Ожидаемый результат
3
Очистка одного флага идемпотентна: повтор не меняет результат. Это удобно при применении команды «выключить», которая может прийти повторно.
Связанные операции: gmp_setbit; gmp_testbit; gmp_and.
gmp_testbitПроверить состояние конкретной позиции маски.
gmp_testbit(GMP|int|string $num, int $index): boolПроверить состояние конкретной позиции маски.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое; в отличие от setbit/clrbit допускаются также int/string. |
| index | Неотрицательная позиция; недопустимый индекс ValueError. |
| Возврат | true, если бит равен 1. Исходное число не меняется. |
- Маска
- Номер проверяемой возможности
- true / false
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
var_dump(gmp_testbit(5, 0));
var_dump(gmp_testbit(5, 1));
Ожидаемый результат
bool(true)
bool(false)
5 = 101₂: младшая позиция 0 включена, позиция 1 выключена.
<?php
declare(strict_types=1);
$features = gmp_init(0);
gmp_setbit($features, 100);
echo gmp_testbit($features, 100) ? "Enabled\n" : "Disabled\n";
echo gmp_testbit($features, 99) ? "Enabled\n" : "Disabled\n";
Ожидаемый результат
Enabled
Disabled
Порядок номеров флагов — часть формата: изменение значения позиции 100 требует миграции данных или версии протокола.
Связанные операции: gmp_setbit; gmp_clrbit; gmp_scan1.
gmp_popcountПосчитать единичные биты неотрицательной маски.
gmp_popcount(GMP|int|string $num): intПосчитать единичные биты неотрицательной маски.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Для конечного прикладного подсчёта требуется num ≥ 0. |
| Возврат | PHP int: количество единичных битов. Это не длина двоичной записи и не максимальный индекс. |
| Отрицательные | У отрицательного числа в модели дополнения до двух бесконечно много старших единиц; библиотека возвращает специальное значение, а не полезное конечное количество. Не используйте его как число флагов. |
- Неотрицательная маска
- Посчитать позиции с 1
- Количество включённых возможностей
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
echo gmp_popcount(13), "\n";
echo gmp_popcount(0), "\n";
Ожидаемый результат
3
0
13 = 1101₂: четыре позиции, но только три единицы.
<?php
declare(strict_types=1);
$features = gmp_init(0);
foreach ([2, 100, 250] as $index) {
gmp_setbit($features, $index);
}
echo gmp_popcount($features), "\n";
Ожидаемый результат
3
Не требуется перебирать все позиции от 0 до 250 в PHP. Это подсчёт включённых битов, а не людей или запросов, если один бит может означать сразу группу.
Связанные операции: gmp_hamdist; gmp_scan1; gmp_testbit.
gmp_hamdistПосчитать, сколько битов различаются у двух неотрицательных чисел.
gmp_hamdist(GMP|int|string $num1, GMP|int|string $num2): intПосчитать, сколько битов различаются у двух неотрицательных чисел.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Неотрицательные целые, включая 0. Более короткая запись дополняется старшими нулями. |
| Возврат | PHP int: число различных позиций, эквивалентно popcount(xor(a,b)) в этой области. |
| Смысл | Расстояние Хэмминга относится к битам; это не расстояние редактирования строк и не разность чисел. |
- Два снимка флагов
- Сравнить соответствующие биты
- Сколько позиций изменилось
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
echo gmp_hamdist(10, 12), "\n";
echo gmp_popcount(gmp_xor(10, 12)), "\n";
Ожидаемый результат
2
2
Различаются позиции 1 и 2. Старшая единица и младший ноль совпадают.
<?php
declare(strict_types=1);
$before = gmp_init(0);
gmp_setbit($before, 100);
$after = clone $before;
gmp_setbit($after, 5);
gmp_clrbit($after, 100);
echo gmp_hamdist($before, $after), "\n";
Ожидаемый результат
2
Включился один флаг и выключился другой. Для перечисления самих изменившихся позиций сначала получите XOR, затем обходите его единицы.
Связанные операции: gmp_xor; gmp_popcount; gmp_scan1.
gmp_scan0Найти первый бит 0 начиная с указанной позиции.
gmp_scan0(GMP|int|string $num1, int $start): intНайти первый бит 0 начиная с указанной позиции.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Целое; для прикладных масок удобнее неотрицательное. |
| start | Неотрицательный стартовый индекс, включительно; движение к более значимым битам. Недопустимый индекс ValueError. |
| Возврат | Индекс найденного бита; документированный признак отсутствия — −1. На границах представления библиотечного bitcnt проверяйте также прикладную верхнюю границу. |
| Знак | У положительных чисел бесконечное продолжение нулями: scan0 найдёт старший свободный бит. У отрицательных — продолжение единицами; смысл фиксированной ширины задаёт ваш код. |
- Начальная позиция
- Искать 0 к старшим битам
- Индекс или отсутствие
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
echo gmp_scan0(7, 0), "\n";
Ожидаемый результат
3
Нумерация начинается с нуля, старт включается в проверку. Это номер позиции, не значение бита и не вес 2 в этой степени.
<?php
declare(strict_types=1);
$occupied = gmp_init('10111', 2);
$free = gmp_scan0($occupied, 0);
if ($free < 5) {
echo 'Free slot: ', $free, "\n";
} else {
echo "No free slots\n";
}
Ожидаемый результат
Free slot: 3
Маска не хранит число физических слотов. Биты после пятого тоже нулевые, поэтому прикладной верхний предел проверяется отдельно.
Связанные операции: gmp_scan1; gmp_testbit; gmp_setbit.
gmp_scan1Найти первый бит 1 начиная с указанной позиции.
gmp_scan1(GMP|int|string $num1, int $start): intНайти первый бит 1 начиная с указанной позиции.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Целое; для прикладных масок удобнее неотрицательное. |
| start | Неотрицательный стартовый индекс, включительно; движение к более значимым битам. Недопустимый индекс ValueError. |
| Возврат | Индекс найденного бита; документированный признак отсутствия — −1. На границах представления библиотечного bitcnt проверяйте также прикладную верхнюю границу. |
| Знак | У положительных чисел бесконечное продолжение нулями: scan0 найдёт старший свободный бит. У отрицательных — продолжение единицами; смысл фиксированной ширины задаёт ваш код. |
- Начальная позиция
- Искать 1 к старшим битам
- Индекс или отсутствие
Двоичная запись описывает число битами 0 и 1. Самый правый бит имеет индекс 0 и вес 1, следующий индекс 1 и вес 2, затем 2 и вес 4. Поэтому 13 = 1101₂ содержит единицы в позициях 0, 2, 3. В битовой маске каждой позиции заранее назначают смысл: например, наличие одной возможности. GMP позволяет маскам выходить за разрядность обычного int.
<?php
declare(strict_types=1);
echo gmp_scan1(40, 0), "\n";
Ожидаемый результат
3
Нумерация начинается с нуля, старт включается в проверку. Это номер позиции, не значение бита и не вес 2 в этой степени.
<?php
declare(strict_types=1);
$mask = gmp_init(40);
$width = 8;
$start = 0;
while ($start < $width) {
$found = gmp_scan1($mask, $start);
if ($found < 0 || $found >= $width) {
break;
}
echo $found, "\n";
$start = $found + 1;
}
Ожидаемый результат
3
5
Следующий поиск начинается после найденной позиции, иначе цикл находил бы тот же бит бесконечно. Проверка верхней границы учитывает заданную ширину и не позволяет принять специальное значение «не найдено» за допустимый индекс.
Связанные операции: gmp_scan0; gmp_testbit; gmp_popcount.
gmp_gcdНайти наибольший общий делитель двух целых.
gmp_gcd(GMP|int|string $num1, GMP|int|string $num2): GMPНайти наибольший общий делитель двух целых.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Целые любого знака; знак игнорируется. |
| Возврат | Неотрицательный GMP. gcd(0,b) = abs(b), gcd(0,0) = 0. |
- Две части отношения
- Общий делитель
- Сокращённые части без потери пропорции
<?php
declare(strict_types=1);
echo gmp_strval(gmp_gcd(18, 24)), "\n";
echo gmp_strval(gmp_gcd(-18, 24)), "\n";
Ожидаемый результат
6
6
Оба числа делятся на 6 без остатка; большего положительного общего делителя нет.
<?php
declare(strict_types=1);
$width = gmp_init(1920);
$height = gmp_init(1080);
$divisor = gmp_gcd($width, $height);
echo gmp_strval(gmp_divexact($width, $divisor)), ':',
gmp_strval(gmp_divexact($height, $divisor)), "\n";
Ожидаемый результат
16:9
Здесь размеры положительны, поэтому делитель не нулевой. Для произвольной внешней пары сначала отклоните недопустимые размеры. divexact допустим, поскольку делимость гарантирована определением НОД.
Связанные операции: gmp_lcm; gmp_gcdext; gmp_divexact.
gmp_gcdextНайти общий делитель и коэффициенты, выражающие его через исходные числа.
gmp_gcdext(GMP|int|string $num1, GMP|int|string $num2): arrayНайти общий делитель и коэффициенты, выражающие его через исходные числа.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Два целых любого знака. |
| Возврат | Ассоциативный массив g, s, t, каждый GMP; num1*s + num2*t = g = gcd(num1,num2). |
| Коэффициенты | Они могут быть отрицательными и не единственны. Полагайтесь на тождество, а не на одну фиксированную пару s/t. |
- a и b
- Расширенный алгоритм Евклида
- g = a*s + b*t
Это следующий шаг после обычного НОД. Например, нужно понять, можно ли выразить требуемое изменение как целую комбинацию двух шагов. Если g делит нужное значение c, то коэффициенты для c получаются умножением s и t на c/g. Отрицательное число шагов означает обратное направление, а не допустимое количество коробок.
<?php
declare(strict_types=1);
$result = gmp_gcdext(30, 18);
$restored = gmp_add(gmp_mul(30, $result['s']), gmp_mul(18, $result['t']));
echo gmp_strval($result['g']), "\n";
echo gmp_strval($restored), "\n";
Ожидаемый результат
6
6
Ключи s и t — коэффициенты при первом и втором аргументах. Функция сразу возвращает их вместе с общим делителем.
<?php
declare(strict_types=1);
$result = gmp_gcdext(30, 18);
$target = gmp_init(12);
if (gmp_cmp(gmp_mod($target, $result['g']), 0) === 0) {
$factor = gmp_divexact($target, $result['g']);
$x = gmp_mul($result['s'], $factor);
$y = gmp_mul($result['t'], $factor);
echo gmp_strval(gmp_add(gmp_mul(30, $x), gmp_mul(18, $y))), "\n";
}
Ожидаемый результат
12
Проверка существования целого решения не доказывает существование неотрицательного решения. Если оба исходных шага равны нулю, g тоже ноль: этот отдельный случай надо разобрать до операции mod.
Связанные операции: gmp_gcd; gmp_invert; gmp_mod.
gmp_lcmНайти наименьшее общее кратное двух целых.
gmp_lcm(GMP|int|string $num1, GMP|int|string $num2): GMPНайти наименьшее общее кратное двух целых.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Целые любого знака; знак результата неотрицательный. |
| Возврат | GMP. Если хотя бы один аргумент 0, результат 0. |
- Два периода
- Первая общая граница
- Кратное обоим периодам
<?php
declare(strict_types=1);
echo gmp_strval(gmp_lcm(6, 8)), "\n";
echo gmp_strval(gmp_lcm(0, 8)), "\n";
Ожидаемый результат
24
0
24 делится и на 6, и на 8. Это НОК, в отличие от НОД 2.
<?php
declare(strict_types=1);
$firstPeriod = 12;
$secondPeriod = 18;
echo gmp_strval(gmp_lcm($firstPeriod, $secondPeriod)), " minutes\n";
Ожидаемый результат
36 minutes
Оба таймера стартуют в один момент и имеют фиксированные положительные интервалы в минутах. Смещённые старты, календарные месяцы и переходы часовых поясов требуют другой модели расписания.
gmp_invertНайти обратный множитель в арифметике по модулю.
gmp_invert(GMP|int|string $num1, GMP|int|string $num2): GMP|falseНайти обратный множитель в арифметике по модулю.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Целое a, для которого ищется x. |
| num2 | Ненулевой модуль m; 0 вызывает DivisionByZeroError. Для обычной задачи выбирают m > 1. |
| Возврат | GMP x, если a*x имеет остаток 1 по m; false, если обратного нет. Проверяйте === false. |
| Условие | При m > 1 обратный существует тогда и только тогда, когда gcd(a,m)=1. |
- Умножение a*x по модулю m
- Найти обратный коэффициент
- x или false
Обычное деление 1/a даёт дробь. Здесь задача другая: подобрать целый множитель, отменяющий умножение после взятия остатка. Это применяется в модульных алгоритмах и кодировании; функция не является шифром сама по себе.
<?php
declare(strict_types=1);
$inverse = gmp_invert(3, 11);
if ($inverse !== false) {
echo gmp_strval($inverse), "\n";
echo gmp_strval(gmp_mod(gmp_mul(3, $inverse), 11)), "\n";
}
Ожидаемый результат
4
1
3 × 4 = 12, а остаток от деления 12 на 11 равен 1. Для 6 и 9 обратного нет: общий делитель 3.
<?php
declare(strict_types=1);
$modulus = 11;
$encoded = gmp_mod(gmp_mul(3, 7), $modulus);
$inverse = gmp_invert(3, $modulus);
if ($inverse === false) {
throw new RuntimeException('Нет обратного множителя');
}
echo gmp_strval(gmp_mod(gmp_mul($encoded, $inverse), $modulus)), "\n";
var_dump(gmp_invert(6, 9) === false);
Ожидаемый результат
7
bool(true)
Восстановили исходную позицию 7 в диапазоне 0…10. Для защиты данных такого простого преобразования недостаточно. Строгая проверка отличает false от допустимого GMP-объекта, включая нулевое значение в особых модульных случаях.
Связанные операции: gmp_gcd; gmp_gcdext; gmp_powm.
gmp_legendreПроверить существование ненулевого квадратного остатка по простому нечётному модулю.
gmp_legendre(GMP|int|string $num1, GMP|int|string $num2): intПроверить существование ненулевого квадратного остатка по простому нечётному модулю.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Любое целое a. |
| num2 | Положительное нечётное простое p. Проверка простоты не выполняется автоматически. |
| Возврат | PHP int: 0, если a делится на p; 1, если a — ненулевой квадратный остаток; −1, если такого квадрата нет. |
| Предусловие | При нарушении требования к p математический договор не действует; не рассчитывайте на корректный ответ или удобное исключение. |
- Можно ли решить x² ≡ a (mod p)?
- p — нечётное простое
- Символ Лежандра
«Квадратный остаток» означает: существует целое x, чей квадрат после mod p даёт a mod p. Это инструмент теории чисел, используемый в математических алгоритмах. Он сообщает существование, но не возвращает сам x.
<?php
declare(strict_types=1);
echo gmp_legendre(2, 7), "\n";
echo gmp_legendre(3, 7), "\n";
echo gmp_legendre(7, 7), "\n";
Ожидаемый результат
1
-1
0
3² mod 7 = 2, поэтому для 2 ответ 1. Квадраты по модулю 7 не дают 3. Число 7 само делится на модуль, поэтому третий ответ 0.
<?php
declare(strict_types=1);
$prime = 7;
for ($candidate = 1; $candidate < $prime; $candidate++) {
if (gmp_legendre($candidate, $prime) === 1) {
echo $candidate, "\n";
}
}
Ожидаемый результат
1
2
4
Это учебное перечисление для маленького p, а не эффективный способ построить список огромного размера. Для составного нечётного знаменателя существует символ Якоби с другим смыслом.
Связанные операции: gmp_jacobi; gmp_kronecker; gmp_prob_prime.
gmp_jacobiВычислить символ Якоби для положительного нечётного знаменателя.
gmp_jacobi(GMP|int|string $num1, GMP|int|string $num2): intВычислить символ Якоби для положительного нечётного знаменателя.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 | Целое a. |
| num2 | Положительное нечётное b; оно может быть составным. |
| Возврат | PHP int −1, 0 или 1. В старом тексте документации встречается неточная аннотация GMP; действующий API возвращает int. |
| Ограничение | При составном b значение 1 не доказывает существование квадратного корня по модулю b. Предусловие нечётности/положительности обеспечивает вызывающий код. |
- a и нечётное b
- Числовой символ для модульного алгоритма
- −1 / 0 / 1
Символ Якоби обобщает символ Лежандра: для простого знаменателя результаты совпадают. Для составного он определяется произведением символов по простым множителям с учётом кратности. Это помогает строить алгоритмы теории чисел, но не заменяет все их проверки.
<?php
declare(strict_types=1);
echo gmp_jacobi(2, 3), "\n";
echo gmp_jacobi(2, 7), "\n";
echo gmp_jacobi(3, 9), "\n";
Ожидаемый результат
-1
1
0
При общем делителе с нечётным знаменателем возможен ноль; знак −1 не является ошибкой PHP.
<?php
declare(strict_types=1);
echo gmp_jacobi(2, 15), "\n";
$found = false;
for ($x = 0; $x < 15; $x++) {
if (($x * $x) % 15 === 2) {
$found = true;
}
}
var_dump($found);
Ожидаемый результат
1
bool(false)
Для 2 по модулю 15 символ равен 1, но ни один остаток x не даёт квадрат 2. Перебор показан для объяснения на 15 значениях, не как масштабируемый алгоритм.
Связанные операции: gmp_legendre; gmp_kronecker; gmp_mod.
gmp_kroneckerВычислить обобщение символа Якоби для любого целого знаменателя.
gmp_kronecker(GMP|int|string $num1, GMP|int|string $num2): intВычислить обобщение символа Якоби для любого целого знаменателя.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num1 / num2 | Целые; допускаются чётный, отрицательный и нулевой знаменатель. |
| Возврат | PHP int −1, 0 или 1 по определению символа Кронекера. |
| Границы | При знаменателе 0 ответ 1 только для числителя ±1, иначе 0; при знаменателе 1 ответ 1. Это не арифметическое деление. |
- Модульная задача с общим знаменателем
- Обобщённый числовой символ
- Один из −1, 0, 1
Этот символ нужен в специализированных математических алгоритмах, где ограничения Якоби слишком узкие. Для нечётного положительного знаменателя он совпадает с Якоби. Множитель 2 обрабатывается по остатку нечётного числителя modulo 8: ±1 дают 1, ±3 дают −1; чётный числитель даёт 0.
<?php
declare(strict_types=1);
echo gmp_kronecker(3, 2), "\n";
echo gmp_kronecker(7, 2), "\n";
echo gmp_kronecker(4, 2), "\n";
Ожидаемый результат
-1
1
0
Вызов Якоби с знаменателем 2 нарушал бы его предусловие; здесь этот случай входит в определение.
<?php
declare(strict_types=1);
var_dump(gmp_kronecker(2, 15) === gmp_jacobi(2, 15));
echo gmp_kronecker(1, 0), "\n";
echo gmp_kronecker(2, 0), "\n";
Ожидаемый результат
bool(true)
1
0
Нулевой знаменатель здесь имеет специальное определение символа. Это не разрешение делить на ноль в gmp_div_q или gmp_mod.
Связанные операции: gmp_jacobi; gmp_legendre; gmp_mod.
gmp_nextprimeНайти следующее простое число, строго больше заданного.
gmp_nextprime(GMP|int|string $num): GMPНайти следующее простое число, строго больше заданного.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Целое; найденный кандидат всегда строго больше него. |
| Возврат | GMP. Даже если num само простое, оно не возвращается. |
| Проверка | Для больших чисел библиотека использует вероятностные тесты; это не сертификат простоты. Время зависит от размера и поиска следующего кандидата. |
- Нижняя граница
- Поиск следующего простого
- Новый кандидат
<?php
declare(strict_types=1);
echo gmp_strval(gmp_nextprime(10)), "\n";
echo gmp_strval(gmp_nextprime(11)), "\n";
Ожидаемый результат
11
13
Первый результат 11, а следующий вызов уже переходит к 13. Если требовалось «не меньше», это другая задача.
<?php
declare(strict_types=1);
$current = gmp_init(20);
for ($i = 0; $i < 4; $i++) {
$current = gmp_nextprime($current);
echo gmp_strval($current), "\n";
}
Ожидаемый результат
23
29
31
37
Последовательность используется в учебном алгоритме. Не создавайте этим способом криптографические ключи: кроме простоты там нужны случайность, распределение и требования протокола.
Связанные операции: gmp_prob_prime; gmp_gcd; gmp_random_range.
gmp_prob_primeПроверить, является ли число составным, вероятно простым или доказанно простым для данного теста.
gmp_prob_prime(GMP|int|string $num, int $repetitions = 10): intПроверить, является ли число составным, вероятно простым или доказанно простым для данного теста.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| num | Проверяемое целое; для прикладной проверки простоты рассматривают num ≥ 2. |
| repetitions | Число/параметр повторений теста, по умолчанию 10. Выбирайте положительное разумное значение; детали алгоритма зависят от версии GMP/MPIR. |
| Возврат | 0 — составное, 1 — вероятно простое, 2 — определённо простое. Это три состояния, не bool. |
| Стоимость | Увеличение работы теста обычно повышает уверенность и расход времени, но ответ 1 не превращается в математическое доказательство. |
- Кандидат
- Библиотечные проверки простоты
- 0 / 1 / 2
<?php
declare(strict_types=1);
foreach ([21, 23] as $candidate) {
$status = gmp_prob_prime($candidate, 25);
echo $candidate, ': ', $status === 0 ? 'composite' : 'prime candidate', "\n";
}
Ожидаемый результат
21: composite
23: prime candidate
Здесь вывод объединяет 1 и 2 только для отбора кандидатов. В журнале результата сохраняйте исходное состояние, если важно различать уверенность.
<?php
declare(strict_types=1);
$numbers = ['100', '101', '102', '103'];
foreach ($numbers as $text) {
$number = gmp_init($text, 10);
if (gmp_cmp($number, 2) >= 0 && gmp_prob_prime($number, 25) !== 0) {
echo $text, "\n";
}
}
Ожидаемый результат
101
103
Явное основание 10 исключает случайное чтение десятичной записи как восьмеричной. Параметр 25 — выбор для примера, а не универсальная криптографическая гарантия. При требованиях к доказательству нужен отдельный сертифицирующий алгоритм.
Связанные операции: gmp_nextprime; gmp_gcd; gmp_perfect_power.
gmp_random_bitsПолучить псевдослучайное неотрицательное целое в заданном битовом диапазоне.
gmp_random_bits(int $bits): GMPПолучить псевдослучайное неотрицательное целое в заданном битовом диапазоне.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| bits | Положительное число битов; 0 или отрицательное ValueError. Верхний практический предел задают память и политика приложения. |
| Возврат | GMP в замкнутом диапазоне 0…2^bits−1. Самый старший бит может быть 0, поэтому фактическая длина числа может быть меньше bits. |
| Состояние | Использует состояние генератора GMP; gmp_random_seed меняет последовательность. |
- Выбрать диапазон по числу битов
- Сгенерировать число
- GMP внутри границ
Генератор GMP подходит для математических экспериментов и воспроизводимых тестов. Его случайность не является криптографически безопасной: не используйте эти функции для токенов, ключей и непредсказуемых кодов. Для таких задач есть Random\Engine\Secure и безопасная случайность, random_int и random_bytes.
<?php
declare(strict_types=1);
$number = gmp_random_bits(8);
var_dump(gmp_cmp($number, 0) >= 0 && gmp_cmp($number, 255) <= 0);
Ожидаемый результат
bool(true)
В результате может оказаться и 0, и 255. В примере проверяется договор, поэтому ожидаемый вывод стабилен, хотя само число меняется.
<?php
declare(strict_types=1);
$number = gmp_random_bits(128);
gmp_setbit($number, 127);
var_dump(gmp_cmp($number, gmp_pow(2, 127)) >= 0);
var_dump(gmp_cmp($number, gmp_pow(2, 128)) < 0);
Ожидаемый результат
bool(true)
bool(true)
Явно установлен старший бит, так что число действительно имеет 128 значимых двоичных позиций. Это не делает источник криптографическим. Не путайте количество битов со строкой из 128 десятичных цифр.
Связанные операции: gmp_random_range; gmp_random_seed; gmp_setbit.
gmp_random_rangeВыбрать псевдослучайное целое из замкнутого диапазона.
gmp_random_range(GMP|int|string $min, GMP|int|string $max): GMPВыбрать псевдослучайное целое из замкнутого диапазона.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| min / max | Два целых, включая отрицательные; min должен быть строго меньше max. |
| Возврат | GMP: равномерный выбор из [min,max], включая обе границы. |
| Ошибки | min ≥ max вызывает ValueError в PHP 8.5; равные границы не являются отдельным допустимым случаем этого API. |
- Нижняя и верхняя границы
- Выбор внутри интервала
- GMP-результат
Генератор GMP подходит для математических экспериментов и воспроизводимых тестов. Его случайность не является криптографически безопасной: не используйте эти функции для токенов, ключей и непредсказуемых кодов. Для таких задач есть Random\Engine\Secure и безопасная случайность, random_int и random_bytes.
<?php
declare(strict_types=1);
$offset = gmp_random_range(-5, 5);
var_dump(gmp_cmp($offset, -5) >= 0 && gmp_cmp($offset, 5) <= 0);
Ожидаемый результат
bool(true)
Нулевое отклонение тоже возможно. Такая модель годится для несекретной симуляции, но сама по себе не описывает физическое распределение измерений.
<?php
declare(strict_types=1);
$min = gmp_init('100000000000000000000', 10);
$max = gmp_add($min, 100);
$sample = gmp_random_range($min, $max);
var_dump(gmp_cmp($sample, $min) >= 0 && gmp_cmp($sample, $max) <= 0);
try {
gmp_random_range(5, 5);
} catch (ValueError $error) {
echo "Нужны разные границы\n";
}
Ожидаемый результат
bool(true)
Нужны разные границы
Строка сохранила точность границы, а API выбрал одно из 101 допустимого значения. Для единственного допустимого значения просто используйте его; генератор не требуется.
Связанные операции: gmp_random_bits; gmp_random_seed; gmp_add.
gmp_random_seedЗадать начальное состояние псевдослучайной последовательности GMP.
gmp_random_seed(GMP|int|string $seed): voidЗадать начальное состояние псевдослучайной последовательности GMP.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| seed | Целое, в том числе большое GMP или строка. Некорректная запись ValueError в PHP 8. |
| Возврат | void. Изменяется состояние, используемое последующими GMP random-вызовами. |
| Воспроизводимость | Одинаковые seed, окружение и порядок вызовов дают повторяемую последовательность. Не обещайте идентичные числа между разными версиями/реализациями библиотеки. |
| До PHP 8 | Старые версии возвращали null при успехе и false с warning при ошибке; современный код ориентируется на исключения. |
- Seed для сценария
- Повторить те же вызовы
- Воспроизвести эксперимент
Генератор GMP подходит для математических экспериментов и воспроизводимых тестов. Его случайность не является криптографически безопасной: не используйте эти функции для токенов, ключей и непредсказуемых кодов. Для таких задач есть Random\Engine\Secure и безопасная случайность, random_int и random_bytes.
<?php
declare(strict_types=1);
gmp_random_seed(42);
$first = gmp_strval(gmp_random_bits(32));
$second = gmp_strval(gmp_random_bits(32));
gmp_random_seed(42);
var_dump($first === gmp_strval(gmp_random_bits(32)));
var_dump($second === gmp_strval(gmp_random_bits(32)));
Ожидаемый результат
bool(true)
bool(true)
Сравниваем последовательность с самой собой после сброса, не фиксируем конкретные числа из одной версии GMP в учебном контракте.
<?php
declare(strict_types=1);
function testInputs($seed)
{
gmp_random_seed($seed);
$inputs = [];
for ($i = 0; $i < 3; $i++) {
$inputs[] = gmp_strval(gmp_random_range(1, 1000));
}
return $inputs;
}
$original = testInputs(2026);
$replayed = testInputs(2026);
var_dump($original === $replayed);
Ожидаемый результат
bool(true)
Запишите seed и версии окружения вместе с ошибкой. Вызов этой функции затрагивает общее состояние GMP random внутри процесса; это не независимый генератор на каждый объект. Для изолированного состояния рассмотрите Random\Randomizer.
Связанные операции: gmp_random_bits; gmp_random_range.
gmp_randomИсторический генератор GMP: как читать старый код и переносить его на современный API.
gmp_random(int $limiter = 20): GMP — удалена в PHP 8.0Исторический генератор GMP: как читать старый код и переносить его на современный API.
GMP хранит целые числа, которые могут быть больше диапазона обычного PHP int. Большое число передают строкой, например '100000000000000000000', чтобы PHP не округлил его как float ещё до вызова. Результат большинства операций — объект GMP; gmp_strval превращает его в строку для вывода или передачи.
Вход GMP|int|string означает объект GMP, обычное целое или строковую запись целого. Строки автоматически распознают основание, как gmp_init с base=0: ведущий 0 может означать восьмеричную запись. Для внешних десятичных значений сначала используйте gmp_init($text, 10). Дробь 12.50 — не целое GMP; для десятичных дробей нужен BCMath.
| Часть вызова | Договор |
|---|---|
| Статус | Устарела в PHP 7.2, удалена в PHP 8.0. В новой программе её не вызывают. |
| limiter | Исторический множитель числа битов внутреннего limb. Размер limb зависел от платформы/библиотеки; отрицательное значение давало отрицательное число. |
| Замена | gmp_random_bits для явной битовой ширины или gmp_random_range для явных числовых границ. |
| Перенос | Нельзя заменить limiter на bits один к одному: сначала восстановите требуемый диапазон задачи. |
- Старый неявный размер
- Определить действительные требования
- Выбрать явные биты или границы
Генератор GMP подходит для математических экспериментов и воспроизводимых тестов. Его случайность не является криптографически безопасной: не используйте эти функции для токенов, ключей и непредсказуемых кодов. Для таких задач есть Random\Engine\Secure и безопасная случайность, random_int и random_bytes.
<?php
declare(strict_types=1);
$number = gmp_random_bits(160);
var_dump(gmp_cmp($number, 0) >= 0);
var_dump(gmp_cmp($number, gmp_pow(2, 160)) < 0);
Ожидаемый результат
bool(true)
bool(true)
Здесь требование прямо сформулировано как 160 бит. Это не обещание совпадения со старым gmp_random(20) на произвольной машине.
<?php
declare(strict_types=1);
$number = gmp_random_range(-1000, -1);
var_dump(gmp_cmp($number, -1000) >= 0 && gmp_cmp($number, -1) <= 0);
Ожидаемый результат
bool(true)
Задан именно нужный закрытый диапазон. Перед миграцией также проверьте, не использовался ли небезопасный старый генератор для секретов: тогда нужна замена источника случайности.
Связанные операции: gmp_random_bits; gmp_random_range; gmp_random_seed.