diff --git a/CHANGELOG.md b/CHANGELOG.md index 87e6bb6..98e35e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [[v0.2.2](https://github.com/The-FireHub-Project/Runtime/compare/v0.2.1...v0.2.2)] – 2026-08-31 + +### Added +* Improved `mod` method for `DecimalEngine` by @dieselxxx + ## [[v0.2.1](https://github.com/The-FireHub-Project/Runtime/compare/v0.2.0...v0.2.1)] – 2026-08-31 ### Added diff --git a/README.md b/README.md index 6552d30..b7d6b4e 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ PHP Runtime Foundation
release version @@ -22,25 +22,46 @@ /> -[![PHPStan](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPStan.yml/badge.svg?branch=develop)](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPStan.yml) -[![PHPUnit](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPUnit.yml/badge.svg?branch=develop)](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPUnit.yml) -[![Codecov](https://codecov.io/gh/The-FireHub-Project/Runtime/branch/develop/graph/badge.svg?token=XW2YEONF51)](https://app.codecov.io/gh/The-FireHub-Project/Runtime/tree/develop) -

- + + GitHub created at + GitHub last commit (branch) - + GitHub activity (branch) - + + GitHub contributors + GitHub commit difference between two branches + + GitHub top language + + GitHub repo size + + GitHub code size

@@ -52,47 +73,55 @@ It contains no domain logic, no business rules, and no framework coupling. Its r --- -## FireHub Icon Development Branch +## FireHub Icon Repository Purpose -⚠️ **This is the `develop` branch** +This repository provides a lightweight PHP runtime abstraction layer that wraps native PHP functionality into clean, consistent, and deterministic APIs. -- Unstable -- APIs may change without notice -- Not intended for production use +Its purpose is to reduce boilerplate and standardize common execution patterns across the FireHub ecosystem by offering ergonomic helper classes for arrays, strings, files, environment access, and other low-level runtime operations. -## FireHub Icon Branch Purpose +It is strictly focused on execution-level concerns and does not contain domain logic, business rules, or framework-level orchestration. It exists to improve developer productivity while preserving native PHP behavior and ensuring zero framework coupling. -The `develop` branch is the **primary integration branch** for all ongoing development. +## FireHub Icon Security -It serves as the staging area where: -- Feature branches are merged -- Bug fixes are integrated -- Experimental work is stabilized -- Code is prepared for upcoming releases +For security reporting and guidelines, please refer to our [SECURITY.md](https://github.com/The-FireHub-Project/.github/blob/master/.github/SECURITY.md) file. -All **release branches** are created **from `develop`**. +## FireHub Icon Community -## Stability Guarantee +![GitHub watchers](https://img.shields.io/github/watchers/The-FireHub-Project/Runtime?style=social) +![GitHub Repo stars](https://img.shields.io/github/stars/The-FireHub-Project/Runtime?style=social) +![GitHub forks](https://img.shields.io/github/forks/The-FireHub-Project/Runtime?style=social) -❌ No backward compatibility guarantee -❌ APIs may change without notice -❌ Behavior may be incomplete or inconsistent -❌ Breaking changes are expected +- Be sure to review the [Code of Conduct](https://github.com/The-FireHub-Project/.github/blob/master/.github/CODE_OF_CONDUCT.md). +- Read a [Contributing](https://github.com/The-FireHub-Project/.github/blob/master/.github/CONTRIBUTING.md) file to see how you can contribute to this project. +- Read our [Security policy](https://github.com/The-FireHub-Project/.github/blob/master/.github/SECURITY.md) file to see how you can report a vulnerability. +- Review the project [Governance model](https://github.com/The-FireHub-Project/.github/blob/master/.github/GOVERNANCE.md), including roles, decision-making, RFC process, and releases. -This branch is intended **only for contributors and advanced testers**. +## FireHub Icon Support -## FireHub Icon Composer Usage (Not Recommended) +

+ + GitHub in-progress issues + + GitHub total issues + + GitHub opened pull requests +

-For internal testing only: +For help with FireHub products, please refer to the following resources: -```json -{ - "require": { - "the-firehub-project/runtime": "dev-develop" - } -} -``` -⚠️ Never use dev-develop in production. +- **General questions & discussions**: [GitHub Discussions](https://github.com/orgs/The-FireHub-Project/discussions) +- **Bug reports & issues**: [Support](https://github.com/The-FireHub-Project/Runtime/issues) +- **Documentation & guides**: [FireHub Docs](https://the-firehub-project.github.io) +- **Commercial support** (Pro/Enterprise): contact your account manager ## FireHub Icon Authors and Contributors diff --git a/src/Math/Decimal/Divide.php b/src/Math/Decimal/Divide.php index fe38fd1..d25ae0a 100644 --- a/src/Math/Decimal/Divide.php +++ b/src/Math/Decimal/Divide.php @@ -37,7 +37,7 @@ trait Divide { * @param non-empty-string $right

* The divisor. *

- * @param positive-int $scale [optional]

+ * @param non-negative-int $scale [optional]

* The number of decimal places to calculate. *

* diff --git a/src/Math/Decimal/Mod.php b/src/Math/Decimal/Mod.php new file mode 100644 index 0000000..4416384 --- /dev/null +++ b/src/Math/Decimal/Mod.php @@ -0,0 +1,66 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=7.4 + * @package Runtime + */ + +namespace FireHub\Runtime\Math\Decimal; + +use DivisionByZeroError; + +/** + * ### Decimal Number Modulo + * @since 1.0.0 + */ +trait Mod { + + /** + * ### Calculates the remainder of a decimal division + * + * The remainder follows truncation-toward-zero semantics. Its sign is the same as the dividend. + * @since 1.0.0 + * + * @uses \FireHub\Runtime\Math\DecimalEngine::normalize() To normalize the decimal values. + * @uses \FireHub\Runtime\Math\DecimalEngine::divide() To calculate the truncated quotient. + * @uses \FireHub\Runtime\Math\DecimalEngine::multiply() To calculate the product of the quotient and divisor. + * @uses \FireHub\Runtime\Math\DecimalEngine::subtract() To calculate the remainder. + * + * @param non-empty-string $left

+ * The dividend. + *

+ * @param non-empty-string $right

+ * The divisor. + *

+ * + * @throws \FireHub\Runtime\Exception\InvalidDecimalNumberException If either decimal value is invalid. + * @throws \DivisionByZeroError If the divisor is zero. + * + * @return numeric-string The remainder of the division. + */ + public static function mod (string $left, string $right):string { + + [, $right_integer, $right_fraction] = self::normalize($right); + + if ($right_integer === '0' && $right_fraction === '') + throw new DivisionByZeroError('Modulo by zero.'); + + [, $left_integer, $left_fraction] = self::normalize($left); + + if ($left_integer === '0' && $left_fraction === '') return '0'; + + $quotient = self::divide($left, $right, 0); + $product = self::multiply($quotient, $right); + + /** @var numeric-string */ + return self::subtract($left, $product); + + } + +} \ No newline at end of file diff --git a/src/Math/DecimalEngine.php b/src/Math/DecimalEngine.php index dbd13fb..ca72296 100644 --- a/src/Math/DecimalEngine.php +++ b/src/Math/DecimalEngine.php @@ -16,7 +16,7 @@ use FireHub\Core\Boundary\Runtime\NativeRuntime; use FireHub\Core\Meta\Enum\Side; use FireHub\Runtime\Math\Decimal\ { - Arithmetic, Divide, Multiply, Round + Arithmetic, Divide, Mod, Multiply, Round }; use FireHub\Runtime; use FireHub\Runtime\Exception\InvalidDecimalNumberException; @@ -37,7 +37,7 @@ final class DecimalEngine extends NativeRuntime { * ### Implements operations * @since 1.0.0 */ - use Arithmetic, Divide, Multiply, Round; + use Arithmetic, Divide, Mod, Multiply, Round; /** * ### Compares two positive decimal values diff --git a/tests/Unit/Math/DecimalEngineTest.php b/tests/Unit/Math/DecimalEngineTest.php index 176e9b4..2e498aa 100644 --- a/tests/Unit/Math/DecimalEngineTest.php +++ b/tests/Unit/Math/DecimalEngineTest.php @@ -523,4 +523,60 @@ public function testPositiveInfinity (string $expected, string $value, int $prec } + /** + * @since 1.0.0 + * + * @param string $expected + * @param non-empty-string $left + * @param non-empty-string $right + * + * @throws \FireHub\Runtime\Exception\InvalidDecimalNumberException + * @throws \DivisionByZeroError + * + * @return void + */ + #[TestWith(['1', '10', '3'])] + #[TestWith(['2', '11', '3'])] + #[TestWith(['0', '12', '3'])] + #[TestWith(['1', '13', '3'])] + #[TestWith(['2', '14', '3'])] + #[TestWith(['0', '0', '3'])] + #[TestWith(['0', '3', '3'])] + #[TestWith(['1', '4', '3'])] + #[TestWith(['2', '5', '3'])] + #[TestWith(['-1', '-10', '3'])] + #[TestWith(['-2', '-11', '3'])] + #[TestWith(['0', '-12', '3'])] + #[TestWith(['-1', '-13', '3'])] + #[TestWith(['1', '10', '-3'])] + #[TestWith(['2', '11', '-3'])] + #[TestWith(['0', '12', '-3'])] + #[TestWith(['-1', '-10', '-3'])] + #[TestWith(['-2', '-11', '-3'])] + #[TestWith(['0', '-12', '-3'])] + #[TestWith(['0.34', '12.34', '4'])] + #[TestWith(['0.34', '12.34', '4.0'])] + #[TestWith(['1.34', '13.34', '4'])] + #[TestWith(['0.5', '10.5', '5'])] + #[TestWith(['0.25', '10.25', '5'])] + #[TestWith(['0.01', '10.01', '5'])] + #[TestWith(['2.23', '12.23', '2.5'])] + #[TestWith(['0.1', '1.1', '0.5'])] + #[TestWith(['0', '1.5', '0.5'])] + #[TestWith(['0.34', '12.34', '4.0'])] + #[TestWith(['1.34', '13.34', '4.0'])] + #[TestWith(['0.02', '1.02', '0.5'])] + #[TestWith(['0.25', '1.25', '0.5'])] + #[TestWith(['1', '100000000000000000000000000000000000001', '100000000000000000000000000000000000000'])] + #[TestWith(['999999999999999999', '1999999999999999999', '1000000000000000000'])] + #[TestWith(['0', '100000000000000000000000000000000000000', '100000000000000000000000000000000000000'])] + #[TestWith(['1', '0000010', '0000003'])] + #[TestWith(['0.5', '0010.5', '5'])] + #[TestWith(['0.5', '10.5000', '5.0000'])] + public function testMod (string $expected, string $left, string $right):void { + + self::assertSame($expected, DecimalEngine::mod($left, $right)); + + } + } \ No newline at end of file