Точная арифметика произвольной точности и научные вычисления на PHP 8.1+ поверх BCMath: математика, статистика и проверка гипотез, финансы, геометрия, физика и химия.

Maintainers

Package info

gitverse.ru/cloud-castle/match

Homepage

Issues

Documentation

pkg:composer/cloud-castle/match

Transparency log

Statistics

Installs: 23

Dependents: 1

Suggesters: 0

v1.18.1 2026-07-27 18:54 UTC

README

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

CloudCastle Match

Packagist Version PHP Version License Downloads Monthly downloads Stars Dependents Suggesters

Репозиторий CI Задачи Релизы Wiki

PHPStan Psalm PHPMD PHPCS coverage Infection MSI

Точная арифметика произвольной точности и научные вычисления для PHP 8.1+: математика, статистика, финансы, геометрия, физика и химия — без ошибок плавающей точки. Все формулы вычисляются на десятичных числах произвольной точности поверх BCMath.

Зачем

float в PHP не хранит 0.1 + 0.2 точно (получается 0.30000000000000004). Для денег, науки и статистики это недопустимо. CloudCastle\Match считает точно: от базовой арифметики до тригонометрии, проверки гипотез, регрессий, финансовых потоков, физических законов и молярных масс.

Ключевое отличие от аналогов: точность не теряется на стыке задач. Не нужно считать деньги одной библиотекой, статистику другой, а на границе между ними получать float.

Установка

composer require cloud-castle/match

Требуется PHP 8.1+ и расширение bcmath.

Быстрый старт

<?php

use CloudCastle\Match\BigDecimal;
use CloudCastle\Match\RoundingMode;

// 0.1 + 0.2 = ровно 0.30, а не 0.30000000000000004.
echo BigDecimal::of('0.10')->plus(BigDecimal::of('0.20'));      // 0.30

// Деление с явным масштабом и округлением (7 режимов, включая банковское).
echo BigDecimal::of('10')->dividedBy(BigDecimal::of('3'), 5);   // 3.33333
echo BigDecimal::of('2')->sqrt(20);            // 1.41421356237309504880

Арифметика

use CloudCastle\Match\Arithmetic\{BigInteger, Fraction, Complex};

echo BigInteger::factorial(30);                        // 265252859812191058636308480000000
echo BigInteger::of('12')->gcd(BigInteger::of('18'));  // 6
echo Fraction::of(1, 2)->plus(Fraction::of(1, 3));     // 5/6 (точно, без округления)
echo Complex::of(1, 1)->power(2);                      // 2i

Математика

use CloudCastle\Match\Math\{Constants, Trigonometry, Logarithm, Statistics, Combinatorics, NumberTheory};

echo Constants::pi(20);                                 // 3.14159265358979323846
echo Trigonometry::sin(Constants::pi(20)->dividedBy(BigDecimal::of(6), 20), 10);  // 0.5000000000
echo Logarithm::ln(BigDecimal::of(2), 15);             // 0.693147180559945
echo Combinatorics::combinations(52, 5);               // 2598960
echo NumberTheory::eulerTotient(36);                   // 12
echo Statistics::standardDeviation([2, 4, 6], 10);     // 1.6329931618

Линейная алгебра и математический анализ

use CloudCastle\Match\Math\{Matrix, Calculus};

echo Matrix::of([[1, 2], [3, 4]])->determinant();          // -2
echo Matrix::of([[1, 2], [3, 4]])->inverse(4)->toArray()[0][0];  // -2.0000
echo Calculus::derivative(fn ($x) => $x->multipliedBy($x), BigDecimal::of(3), 4);  // 6.0000 ((x²)'=2x)
echo Calculus::integralSimpson(fn ($x) => $x->multipliedBy($x), BigDecimal::of(0), BigDecimal::of(3), 2, 4);  // 9.0000

Геометрия

use CloudCastle\Match\Geometry\{Vector3D, Triangle, Sphere};

echo Vector3D::of(1, 0, 0)->cross(Vector3D::of(0, 1, 0));   // (0, 0, 1)
echo Triangle::of(3, 4, 5)->area(4);                        // 6.0000 (формула Герона)
echo Sphere::of(2)->volume(4);                              // 33.5103

Физика

use CloudCastle\Match\Physics\{Kinematics, Dynamics, Gravitation};

echo Kinematics::displacement(10, 2, 5);                     // 75.0 (s = ut + at²/2)
echo Dynamics::kineticEnergy(2, 3);                          // 9.0 (E = mv²/2)
echo Gravitation::force(1, 1, 1, 16);                        // 0.0000000000667430 (G)

use CloudCastle\Match\Physics\NuclearPhysics;

echo NuclearPhysics::massEnergyEquivalence(1);              // 89875517873681764 (E = mc²)
echo NuclearPhysics::radioactiveDecay(100, 10, 20, 4);     // 25.0000 (через 2 периода полураспада)
echo NuclearPhysics::lorentzFactor('179875474.8', 6);      // 1.250000 (при v = 0.6c)

Химия

use CloudCastle\Match\Chemistry\{MolarMass, Stoichiometry};

echo MolarMass::of('Ca(OH)2');                              // 74.092 г/моль
echo MolarMass::of('(NH4)2SO4');                            // 132.134 г/моль
echo Stoichiometry::moles('36.03', '18.015', 2);           // 2.00 моль

Финансы

use CloudCastle\Match\BigDecimal;
use CloudCastle\Match\Finance\{Interest, TimeValue, Annuity};

// Сложные проценты, чистая приведённая стоимость и аннуитетный платёж —
// точно, без ошибок float (критично для денег).
echo Interest::compound(BigDecimal::of(1000), BigDecimal::of('0.1'), 2, 2);   // 210.00
echo TimeValue::internalRateOfReturn(
    [BigDecimal::of(-1000), BigDecimal::of(1100)],
    4,
);                                                                            // 0.1000 (IRR = 10%)
echo Annuity::payment(BigDecimal::of(1000), BigDecimal::of('0.1'), 2, 2);     // 576.19

Последовательности, полиномы и уравнения

use CloudCastle\Match\BigDecimal;
use CloudCastle\Match\Math\{Sequences, Polynomial, Equations};

echo Sequences::lucas(10);                                  // 123 (числа Люка)
echo Polynomial::of(BigDecimal::of(1), BigDecimal::of(2), BigDecimal::of(3))
    ->evaluate(BigDecimal::of(2));                          // 17 (схема Горнера)
echo Equations::quadraticRoots(BigDecimal::of(1), BigDecimal::of(-5), BigDecimal::of(6), 2)[0];  // 3.00

Разложения матриц, статистика и кватернионы

use CloudCastle\Match\Arithmetic\Quaternion;
use CloudCastle\Match\BigDecimal;
use CloudCastle\Match\Math\{Matrix, MatrixDecomposition, HypothesisTesting, Interpolation, InformationTheory};

// Разложения матриц и сингулярные числа (основа SVD).
$lu = MatrixDecomposition::lu(Matrix::of([[4, 3], [6, 3]]), 6);   // P·A = L·U
echo MatrixDecomposition::singularValues(Matrix::of([[1, 1], [0, 1]]), 6)[0];  // 1.618033

// Проверка гипотез: t-критерий и однофакторный дисперсионный анализ.
echo HypothesisTesting::oneSampleT([1, 2, 3, 4, 5], BigDecimal::of(2), 4);     // 1.4142
echo HypothesisTesting::oneWayAnovaF([[1, 2, 3], [4, 5, 6]], 4);               // 13.5000

// Интерполяция, энтропия и кватернионы.
echo Interpolation::lagrange([[0, 0], [1, 1], [2, 4]], BigDecimal::of('1.5'), 4);  // 2.2500
echo InformationTheory::shannonEntropy(['0.5', '0.5'], 6);                     // 1.000000 бит
echo Quaternion::of(0, 1, 0, 0)->multipliedBy(Quaternion::of(0, 0, 1, 0));     // 0 + 0i + 0j + 1k

Специальные функции и распределения

use CloudCastle\Match\BigDecimal;
use CloudCastle\Match\Math\{SpecialFunctions, Distributions};

echo SpecialFunctions::erf(BigDecimal::of(1), 10);        // 0.8427007929 (функция ошибок)
echo SpecialFunctions::gamma(5);                          // 24 (Γ(5) = 4!, точно)
echo SpecialFunctions::beta(2, 3, 6);                     // 0.083333 (B(2,3) = 1/12)

$zero = BigDecimal::of(0);
$one = BigDecimal::of(1);
echo Distributions::normalCdf(BigDecimal::of('1.96'), $zero, $one, 6);   // 0.975002
echo Distributions::binomialPmf(2, 5, BigDecimal::of('0.5'), 4);         // 0.3125 (точно)
echo Distributions::poissonPmf(0, $one, 10);                             // 0.3678794412

Прикладная статистика: от выборки до вывода

use CloudCastle\Match\BigDecimal;
use CloudCastle\Match\Math\{Correlation, HypothesisTesting, Regression, Outliers, PrincipalComponents};

// Ранговая корреляция улавливает и нелинейную связь: y = x² даёт ровно 1.
echo Correlation::spearman([1, 2, 3], [1, 4, 9], 6);            // 1.000000
echo Correlation::kendallTau([1, 2, 3, 4], [1, 3, 2, 4], 6);    // 0.666667

// Полный путь проверки гипотезы: статистика, затем её p-значение.
$t = HypothesisTesting::oneSampleT([1, 2, 3, 4, 5], BigDecimal::of(2), 8);
echo HypothesisTesting::pValueForT($t, 4, 4);                   // 0.2302 — различие незначимо

// Устойчивая регрессия не смещается одним выбросом, в отличие от МНК.
$data = [[1, 2], [2, 4], [3, 6], [4, 8], [5, 10], [6, 100]];
echo Regression::theilSen($data, 4)['slope'];                   // 2.0000
echo Regression::leastSquares($data, 4)['slope'];               // 14.5714

// Поиск выбросов и главные компоненты.
echo Outliers::byInterquartileRange([1, 2, 3, 4, 100], 4)[0];   // 100
echo PrincipalComponents::analyse([[1, 2], [3, 6], [5, 10]], 4)['explained'][0];  // 1.0000

Возможности

СлойКлассы
АрифметикаBigDecimal (7 режимов округления, √), BigInteger, Fraction, Complex, Quaternion
Базовая математикаConstants (π, e, √2, φ, ln2, ln10 до 100 знаков), Power, Logarithm, Trigonometry, Combinatorics, NumberTheory (в т. ч. μ, σ, τ, ω), Sequences (Люка, Пелля, фигурные), SetTheory
Алгебра и анализPolynomial, Equations (бисекция, Ньютон, секущие), Algebra (кубические уравнения, корни многочленов любой степени), Calculus (производные и интегралы), Interpolation (Лагранж, Ньютон), OrthogonalPolynomials (Лежандра, Чебышёва, Эрмита, Лагерра), SpecialFunctions (Γ, B, erf, Бесселя, неполные бета и гамма, сигмоида, softmax)
Линейная алгебраMatrix, MatrixDecomposition (LU, QR, Холецкий, сингулярные числа, собственные векторы), LinearSystems (СЛАУ, ранг), PrincipalComponents (метод главных компонент)
СтатистикаStatistics (средние, дисперсия, Пирсон, регрессия), Descriptive (процентили, асимметрия, эксцесс, специальные средние), Correlation (Спирмен, Кендалл), Ranking, Regression (МНК, Тейл — Сен, степенная, показательная, R²), EffectSize (d Коэна, η², V Крамера), Outliers (Граббс, z-оценки, межквартильный размах), CircularStatistics, KernelDensity
Проверка гипотезHypothesisTesting (t-критерий, ANOVA, p-значения), NonparametricTests (Манн — Уитни, Краскел — Уоллис, хи-квадрат, Уилкоксон, знаковый, p-значения)
ВероятностиDistributions (нормальное, биномиальное, пуассоновское, показательное, равномерное), ContinuousDistributions (Лапласа, логистическое, Парето, Вейбулла, логнормальное, Коши, Стьюдента, хи-квадрат, Фишера), DiscreteDistributions (Бернулли, геометрическое, гипергеометрическое, Паскаля, Ципфа), MultivariateDistributions (полиномиальное, Дирихле, многомерное нормальное), InformationTheory (энтропия, Кульбак — Лейблер), Distance (9 метрик расстояний)
ГеометрияVector2D/Vector3D, Circle, Rectangle, Triangle, Sphere, Cylinder, Cone, Theorems (Пифагор, косинусов, синусов, шнуровка)
ФизикаPhysicalConstants (СИ), Kinematics, Dynamics, Gravitation, Electricity, Thermodynamics, NuclearPhysics (E=mc², распад, релятивизм)
ХимияPeriodicTable, Element, MolarMass, Stoichiometry, Concentration
ФинансыInterest (простые/сложные проценты, эффективная и номинальная ставка), TimeValue (FV/PV/NPV/IRR), Annuity (аннуитетный платёж, PV/FV потока)

Сравнение с аналогами

Функциональность

ВозможностьMatchbrick/mathmarkrogoyski/math-phplitipk/php-bignumbersmoontoast/mathmarkbaker/complex+matrix🏆 Победитель
Точная десятичная арифметика🏆 ничья
Целые произвольной точности🏆 ничья
Рациональные дроби🏆 Match, brick/math, markrogoyski/math-php
Комплексные числа🟡🟡🏆 Match
Точная тригонометрия🟡🏆 Match, litipk/php-bignumbers
Точные логарифмы и экспонента🟡🏆 Match, litipk/php-bignumbers
Матрицы и линейная алгебра🟡🟡🏆 Match
Разложения матриц (LU, QR, SVD)🟡🟡🏆 Match
Собственные векторы и числа🟡🟡🏆 Match
Решение СЛАУ и ранг матрицы🟡🟡🏆 Match
Метод главных компонент🟡🏆 Match
Статистика🟡🏆 Match
Ранговые корреляции (Спирмен, Кендалл)🟡🏆 Match
Проверка гипотез (t-тест, ANOVA)🟡🏆 Match
p-значения критериев🟡🏆 Match
Неполные бета- и гамма-функции🟡🏆 Match
Распределения Стьюдента, χ², Фишера🟡🏆 Match
Непараметрические критерии🟡🏆 Match
Меры величины эффекта🟡🏆 Match
Поиск выбросов (Граббс, IQR)🟡🏆 Match
Круговая статистика🟡🏆 Match
Оценка плотности ядром🟡🏆 Match
Регрессии (МНК, Тейл — Сен, степенная)🟡🏆 Match
Вероятностные распределения🟡🏆 Match
Многомерные распределения🟡🏆 Match
Тяжёлохвостые распределения (Парето, Коши)🟡🏆 Match
Распределения надёжности (Вейбулла, логнорм.)🟡🏆 Match
Специальные функции (Γ, B, erf)🟡🏆 Match
Функции Бесселя🟡🏆 Match
Ортогональные многочлены🟡🏆 Match
Активационные функции (сигмоида, softmax)🟡🏆 Match
Численное решение уравнений🟡🏆 Match
Кубические уравнения (Кардано)🟡🏆 Match
Корни многочленов любой степени🏆 Match
Интерполяция🟡🏆 Match
Комбинаторика и теория чисел🟡🏆 Match, brick/math
Мультипликативные функции (μ, σ, τ, ω)🟡🏆 Match
Числовые последовательности🟡🏆 Match
Теория множеств🏆 Match, markrogoyski/math-php
Кватернионы🟡🏆 Match
Теория информации (энтропия)🟡🏆 Match
Метрики расстояний и расхождений🟡🏆 Match
Порядковые статистики и меры формы🟡🏆 Match
Геометрия (фигуры и тела)🏆 Match
Физические законы и константы🏆 Match
Химия (молярные массы)🏆 Match
Финансы (NPV, IRR, аннуитеты)🟡🏆 Match
Итого точных возможностей4743320🏆 Match

✅ — точно · 🟡 — только на float (~15 знаков) · ❌ — нет

Match — единственная библиотека, где точная десятичная арифметика и полный научный стек живут на одном ядре: по числу возможностей, реализованных точно, она опережает ближайший аналог в несколько раз.

Честно о границах: у markrogoyski/math-php остаются встроенные выборочные наборы данных — их место в отдельной подключаемой библиотеке, а не в ядре точной арифметики. Все вычислительные разделы реализованы, причём на точной арифметике вместо float. Всё это он считает на float. litipk/php-bignumbers даёт точную тригонометрию и логарифмы наравне с нами.

Производительность и память

Замеры выполняются командой composer bench в изолированных процессах без Xdebug; таблицы ниже генерируются автоматически (composer docs:sync).

Сложение (20 000 операций) (ops/s, больше — лучше)

БиблиотекаРезультат🏆 Победитель
Match2 221 414
brick/math882 242
litipk/php-bignumbers1 223 583
moontoast/math2 716 500
markrogoyski/math-php (float)156 482 278🏆
markbaker/complex (float)884 553

Деление с масштабом 10 (5 000) (ops/s, больше — лучше)

БиблиотекаРезультат🏆 Победитель
Match373 019
brick/math334 267
litipk/php-bignumbers389 583
moontoast/math1 086 798
markrogoyski/math-php (float)225 123 818🏆
markbaker/complex (float)697 567

Память на одно значение (байт, меньше — лучше)

БиблиотекаРезультат🏆 Победитель
Match130,3
brick/math130,3
litipk/php-bignumbers130,3
moontoast/math130,3
markrogoyski/math-php (float)0,0🏆
markbaker/complex (float)106,3

Замерено 27.07.2026 на PHP 8.1.34, изолированными процессами без Xdebug, лучшее из трёх прогонов.

Как читать эти числа честно:

  • float (math-php) выигрывает всегда и с огромным отрывом — это аппаратная арифметика. Но она даёт лишь ~15 верных знаков и накапливает погрешность: 0.1 + 0.2 ≠ 0.3. Для денег и точной науки она непригодна, поэтому включена как нижняя граница стоимости, а не как соперник по точности.
  • moontoast/math быстрее нас в обоих сценариях — и это честный результат, а не артефакт замера: его BigNumber — тонкая обёртка над bcmath без валидации ввода, без семи режимов округления (деление только усекает) и без анализа точного остатка. Мы платим этой разницей за строгую проверку на границе и предсказуемое округление. В замере его изменяемые объекты копируются, чтобы работа была эквивалентна неизменяемым библиотекам.
  • Match быстрее brick/math в обоих сценариях (сложение — более чем вдвое) и заметно быстрее litipk/php-bignumbers на сложении; на делении с litipk идём вровень (разница в пределах шума).
  • Итог без прикрас: по «сырой» скорости мы не первые — первым остаётся moontoast/math, платящий за это отсутствием валидации и режимов округления. Среди библиотек с сопоставимыми гарантиями корректности мы быстрее всех.
  • По памяти объектные библиотеки неразличимы (≈130 байт на значение): расход определяется не реализацией, а тем, как PHP размещает объект и строку. Выигрывает только float — он хранится прямо в ячейке массива. Память — единственный критерий, которым мы сознательно жертвуем ради точности и неизменяемости.

Качество кода

МетрикаMatchbrick/mathmarkrogoyski/math-phplitipk/php-bignumbersmoontoast/mathmarkbaker/complex+matrix🏆 Победитель
Файлы со строгой типизацией100%100%0%33%0%0%🏆 ничья
Финальные классы (защита от подмены)100%21%0%20%0%0%🏆 Match
Функции с объявленным типом результата97%98%87%89%0%95%🏆 brick/math
Покрытие строк тестами100%не публикуетсяне публикуетсяне публикуетсяне публикуетсяне публикуется🏆 Match
Мутационный балл (MSI)98.25%не публикуетсяне публикуетсяне публикуетсяне публикуетсяне публикуется🏆 Match
Статический анализPHPStan max, Psalm 1не заявленне заявленне заявленне заявленне заявлен🏆 Match

Первые три строки измерены разбором исходников установленных версий (composer analyse:competitors). Покрытие и MSI аналоги не публикуют — отмечено честно.

Безопасность

АспектMatchbrick/mathmarkrogoyski/math-phplitipk/php-bignumbersmoontoast/mathmarkbaker/complex+matrix🏆 Победитель
Строгая типизация (защита от подмены типов)100%100%0%33%0%0%🏆 ничья
Финальные классы (нельзя переопределить логику)100%21%0%20%0%0%🏆 Match
Неизменяемые свойства (readonly)31 шт.6 шт.0 шт.0 шт.0 шт.0 шт.🏆 Match
Явные выбросы исключений на 100 функций18233628539🏆 markbaker/complex+matrix
Проверка ввода на границевсегдачастичночастичночастичночастичночастично🏆 Match
Известные уязвимости (composer audit)нетнетнетнетнетнет🏆 ничья

Первые четыре строки измерены разбором исходников установленных версий. Больше явных исключений — строже реакция на некорректный ввод.

Плюсы и минусы — честно

Сильные стороны

  • Единственная библиотека, где точная десятичная арифметика и научный и финансовый стек живут на одном ядре — не нужно склеивать brick/math для денег с math-php для формул и терять точность на стыке.
  • Самая быстрая среди неизменяемых точных библиотек на сложении.
  • Все значения неизменяемы, любой ввод валидируется на границе, ошибки — явные исключения вместо «тихих» NAN/INF.
  • Путь проверки гипотезы проходится целиком: от выборки до p-значения, без внешних таблиц критических значений.
  • Корни многочленов любой степени — аналоги останавливаются на четвёртой.
  • Одна runtime-зависимость — расширение bcmath из коробки PHP.

Слабые стороны (и когда они важны)

  • Медленнее аппаратного float на порядки. Это цена точности, а не недоработка: там, где хватает 15 знаков, float выгоднее.
  • Памяти на значение примерно на 9% больше, чем у brick/math и litipk/php-bignumbers.
  • Масштаб деления задаётся явно. dividedBy() требует указать число знаков — это защита от случайного усечения, но кода становится чуть больше.
  • Точность рядов ограничена Constants::MAX_SCALE (100 знаков) для функций, опирающихся на π и √2 (erf, нормальное распределение).
  • Тригонометрия, логарифмы и erf считаются рядами: чем выше запрошенный масштаб, тем дороже вызов.

Рекомендации по применению

Сфера / системаРекомендация
Финтех, биллинг, бухгалтерияИспользовать. Деньги нельзя считать в float: Finance и BigDecimal дают воспроизводимый результат до копейки, а режим HALF_EVEN соответствует банковскому округлению.
Отчётность, налоги, тарификацияИспользовать. Явный масштаб деления и семь режимов округления закрывают требования регуляторов к правилам округления.
Научные и инженерные расчётыИспользовать, когда важен верный последний знак: физика, химия, метрология, лабораторные вычисления.
Статистика и аналитика на больших выборкахВзвешенно. Для точных агрегатов — да; для разведочного анализа миллионов строк быстрее float-инструменты.
ОбразованиеИспользовать: точные дроби, комплексные числа, матрицы и пошаговые формулы удобно демонстрировать без артефактов float.
Графика, игры, симуляции реального времениНе использовать. Нужны миллионы приближённых операций в секунду — аппаратный float уместнее.
Машинное обучение, обработка сигналовВзвешенно. Метод главных компонент, регрессии и оценка плотности есть и считаются точно, но обучение моделей упирается в скорость: матричные операции требуют BLAS/SIMD. Годится для небольших выборок и воспроизводимых расчётов, не для обучения на больших данных.
КриптографияНе использовать. Нужны операции постоянного времени и модульная арифметика больших чисел — берите ext-gmp или специализированные библиотеки.

Разработка

composer install
composer check                # линтеры + статический анализ + тесты
composer fix                  # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci                   # полный CI-пайплайн локально
composer test:mutation        # мутационное тестирование (Infection)
composer test:coverage        # покрытие в var/coverage/clover.xml
composer bench                # замеры против пяти аналогов без Xdebug
composer analyse:competitors  # разбор исходников аналогов для таблиц
composer docs:sync            # пересборка бейджей и сравнительных таблиц
composer docs:check           # проверка, что документация не отстала

Сравнительные таблицы и бейджи качества в этом файле генерируются из фактических отчётов покрытия, мутационного тестирования и замеров — руками их не правят. Стенд сравнения живёт в tools/benchmark и в дистрибутив пакета не попадает.

Документация

Лицензия

MIT © CloudCastle (alex-4-17@yandex.ru)

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano