cloud-castle / match
Точная арифметика произвольной точности и научные вычисления на PHP 8.1+ поверх BCMath: математика, статистика и проверка гипотез, финансы, геометрия, физика и химия.
Requires
- php: >=8.1
- ext-bcmath: *
Requires (Dev)
- deptrac/deptrac: ^3.0 || ^4.0
- ergebnis/composer-normalize: ^2.45
- friendsofphp/php-cs-fixer: ^3.75
- icanhazstring/composer-unused: ^0.9
- infection/infection: ^0.29 || ^0.33
- php-parallel-lint/php-parallel-lint: ^1.4
- phpmd/phpmd: ^2.15
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^1.12 || ^2.1
- phpstan/phpstan-deprecation-rules: ^1.2 || ^2.0
- phpstan/phpstan-phpunit: ^1.4 || ^2.0
- phpstan/phpstan-strict-rules: ^1.6 || ^2.0
- phpunit/phpunit: ^10.5 || ^11.5
- psalm/plugin-phpunit: ^0.19 || ^0.20
- rector/rector: ^1.2 || ^2.0
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^3.12 || ^4.0
- vimeo/psalm: ^6.0
- webmozart/assert: ^1.11
README
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano
CloudCastle Match
Точная арифметика произвольной точности и научные вычисления для 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 потока) |
Сравнение с аналогами
Функциональность
| Возможность | Match | brick/math | markrogoyski/math-php | litipk/php-bignumbers | moontoast/math | markbaker/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 |
| Итого точных возможностей | 47 | 4 | 3 | 3 | 2 | 0 | 🏆 Match |
✅ — точно · 🟡 — только на float (~15 знаков) · ❌ — нет
Match — единственная библиотека, где точная десятичная арифметика и полный
научный стек живут на одном ядре: по числу возможностей, реализованных точно,
она опережает ближайший аналог в несколько раз.
Честно о границах: у markrogoyski/math-php остаются встроенные выборочные
наборы данных — их место в отдельной подключаемой библиотеке, а не в ядре
точной арифметики. Все вычислительные разделы реализованы, причём на точной
арифметике вместо float. Всё это он считает
на float. litipk/php-bignumbers даёт точную тригонометрию и логарифмы
наравне с нами.
Производительность и память
Замеры выполняются командой composer bench в изолированных процессах без
Xdebug; таблицы ниже генерируются автоматически (composer docs:sync).
Сложение (20 000 операций) (ops/s, больше — лучше)
| Библиотека | Результат | 🏆 Победитель |
|---|---|---|
| Match | 2 221 414 | |
| brick/math | 882 242 | |
| litipk/php-bignumbers | 1 223 583 | |
| moontoast/math | 2 716 500 | |
| markrogoyski/math-php (float) | 156 482 278 | 🏆 |
| markbaker/complex (float) | 884 553 |
Деление с масштабом 10 (5 000) (ops/s, больше — лучше)
| Библиотека | Результат | 🏆 Победитель |
|---|---|---|
| Match | 373 019 | |
| brick/math | 334 267 | |
| litipk/php-bignumbers | 389 583 | |
| moontoast/math | 1 086 798 | |
| markrogoyski/math-php (float) | 225 123 818 | 🏆 |
| markbaker/complex (float) | 697 567 |
Память на одно значение (байт, меньше — лучше)
| Библиотека | Результат | 🏆 Победитель |
|---|---|---|
| Match | 130,3 | |
| brick/math | 130,3 | |
| litipk/php-bignumbers | 130,3 | |
| moontoast/math | 130,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— он хранится прямо в ячейке массива. Память — единственный критерий, которым мы сознательно жертвуем ради точности и неизменяемости.
Качество кода
| Метрика | Match | brick/math | markrogoyski/math-php | litipk/php-bignumbers | moontoast/math | markbaker/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 аналоги не публикуют — отмечено честно.
Безопасность
| Аспект | Match | brick/math | markrogoyski/math-php | litipk/php-bignumbers | moontoast/math | markbaker/complex+matrix | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Строгая типизация (защита от подмены типов) | 100% | 100% | 0% | 33% | 0% | 0% | 🏆 ничья |
| Финальные классы (нельзя переопределить логику) | 100% | 21% | 0% | 20% | 0% | 0% | 🏆 Match |
Неизменяемые свойства (readonly) | 31 шт. | 6 шт. | 0 шт. | 0 шт. | 0 шт. | 0 шт. | 🏆 Match |
| Явные выбросы исключений на 100 функций | 18 | 23 | 36 | 28 | 5 | 39 | 🏆 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 и в
дистрибутив пакета не попадает.
Документация
- Репозиторий: https://gitverse.ru/cloud-castle/match
- История изменений: CHANGELOG.md
- Политика безопасности: SECURITY.md
Лицензия
MIT © CloudCastle (alex-4-17@yandex.ru)
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano