|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to this project will be documented in this file. |
| 4 | + |
| 5 | +The format is based on [Keep a Changelog](https://keepachangelog.com/), |
| 6 | +and this project adheres to [Semantic Versioning](https://semver.org/). |
| 7 | + |
| 8 | +## [Unreleased] |
| 9 | + |
| 10 | +## [3.0.0] - 2026-02-08 |
| 11 | + |
| 12 | +### Changed |
| 13 | + |
| 14 | +- **BREAKING:** `Math` is now immutable by default — every operation returns a new instance, leaving the original unchanged |
| 15 | +- `MathImmutable` replaced by `MathMutable` — mutability is now the explicit opt-in for performance-sensitive hot loops |
| 16 | +- `__toString()` bypasses redundant regex validation for better performance |
| 17 | +- PHPStan level 9 compliance for `src/` |
| 18 | +- GitHub Actions workflows updated to latest action versions |
| 19 | + |
| 20 | +### Added |
| 21 | + |
| 22 | +- `MathMutableCast` — Laravel Eloquent cast that returns `MathMutable` instances. Use `MathMutableCast::class` (with optional `:nullable`) instead of `MathCast::class` for mutable cast attributes. Separate cast classes enable proper static type resolution. **Upgrading from v2:** since `Math` is now immutable, existing Laravel models that rely on in-place mutation of cast attributes should switch from `MathCast::class` to `MathMutableCast::class` to restore the previous behavior. |
| 23 | +- `MathMutable` — mutable variant of `Math` where operations modify the instance in place. Extends `Math` and is accepted anywhere `Math` is type-hinted. |
| 24 | +- `negate()` — flip sign, zero stays zero |
| 25 | +- `clamp($min, $max)` — clip value between bounds |
| 26 | +- `quotientAndRemainder($divisor)` — returns `[$quotient, $remainder]` in one call |
| 27 | +- `isZero()` — precision-aware zero check |
| 28 | +- `isNegative()` — complement to `isPositive()` |
| 29 | +- `isEven()` / `isOdd()` — integer parity checks, return `false` for non-integers |
| 30 | +- `getScale()` — number of meaningful decimal places (normalized) |
| 31 | +- `getIntegralPart()` — part before the decimal point (normalized, `-0` becomes `0`) |
| 32 | +- `getFractionalPart()` — part after the decimal point (normalized, trailing zeros stripped) |
| 33 | +- `declare(strict_types=1)` in all source files |
| 34 | +- `phpstan-tests.neon` — dedicated PHPStan configuration for tests at level 5 |
| 35 | + |
| 36 | +### Fixed |
| 37 | + |
| 38 | +- `toBase()` / `fromBase()` now preserve the sign of negative numbers instead of silently stripping it — `Math::number('-42')->toBase(16)` returns `'-2a'` and `Math::fromBase('-2a', 16)` returns `'-42'` |
| 39 | +- `fromBase()` now normalizes input case for bases <= 36 — `Math::fromBase('FF', 16)` works consistently with and without GMP |
| 40 | +- `format()` now works correctly with immutable default (captures `abs()` return value) |
| 41 | +- `bcDec2Base()` properly initializes result as `'0'` |
| 42 | + |
| 43 | +### Removed |
| 44 | + |
| 45 | +- `MathImmutable` — no longer needed, `Math` itself is now immutable |
| 46 | + |
| 47 | +## [2.0.0] - 2024-04-24 |
| 48 | + |
| 49 | +### Added |
| 50 | + |
| 51 | +- `MathCast` — Laravel Eloquent cast for `Math` instances with nullable support |
| 52 | + |
| 53 | +### Changed |
| 54 | + |
| 55 | +- Minimum PHP version raised to 8.1 |
| 56 | + |
| 57 | +### Removed |
| 58 | + |
| 59 | +- PHP < 8.1 support |
| 60 | + |
| 61 | +## [1.0.1] - 2021-06-16 |
| 62 | + |
| 63 | +### Added |
| 64 | + |
| 65 | +- PHP 8.0 support |
| 66 | + |
| 67 | +## [1.0.0] - 2019-07-31 |
| 68 | + |
| 69 | +Initial release. |
| 70 | + |
| 71 | +[Unreleased]: https://github.com/fab2s/Math/compare/3.0.0...HEAD |
| 72 | +[3.0.0]: https://github.com/fab2s/Math/compare/2.0.0...3.0.0 |
| 73 | +[2.0.0]: https://github.com/fab2s/Math/compare/1.0.1...2.0.0 |
| 74 | +[1.0.1]: https://github.com/fab2s/Math/compare/1.0.0...1.0.1 |
| 75 | +[1.0.0]: https://github.com/fab2s/Math/releases/tag/1.0.0 |
0 commit comments