Skip to content

Commit

Permalink
merge conflict resolved
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastienDug committed Nov 27, 2023
2 parents 42daee9 + 21e0a1e commit 0ee0739
Show file tree
Hide file tree
Showing 20 changed files with 329 additions and 396 deletions.
27 changes: 22 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ on:
push:
pull_request:

env:
PSALM_PHP_VERSION: "8.2"
COVERAGE_PHP_VERSION: "8.2"

jobs:
psalm:
name: Psalm
Expand All @@ -16,7 +20,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1"
php-version: ${{ env.PSALM_PHP_VERSION }}

- name: Install composer dependencies
uses: "ramsey/composer-install@v1"
Expand All @@ -31,14 +35,25 @@ jobs:
strategy:
matrix:
php-version:
- "8.0"
- "8.1"
- "8.2"
- "8.3"
calculator:
- GMP
- BCMath
- Native
deps:
- "highest"
include:
- php-version: "8.1"
calculator: GMP
deps: "lowest"
- php-version: "8.1"
calculator: BCMath
deps: "lowest"
- php-version: "8.1"
calculator: Native
deps: "lowest"

steps:
- name: Checkout
Expand All @@ -52,20 +67,22 @@ jobs:

- name: Install composer dependencies
uses: "ramsey/composer-install@v1"
with:
dependency-versions: ${{ matrix.deps }}

- name: Run PHPUnit
run: vendor/bin/phpunit
env:
CALCULATOR: ${{ matrix.calculator }}
if: ${{ matrix.php-version != '8.0' }}
if: ${{ matrix.php-version != env.COVERAGE_PHP_VERSION }}

- name: Run PHPUnit with coverage
run: |
mkdir -p build/logs
vendor/bin/phpunit --coverage-clover build/logs/clover.xml
env:
CALCULATOR: ${{ matrix.calculator }}
if: ${{ matrix.php-version == '8.0' }}
if: ${{ matrix.php-version == env.COVERAGE_PHP_VERSION }}

- name: Run PHPUnit with bcscale()
run: vendor/bin/phpunit
Expand All @@ -78,4 +95,4 @@ jobs:
run: vendor/bin/php-coveralls --coverage_clover=build/logs/clover.xml -v
env:
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: ${{ matrix.php-version == '8.0' }}
if: ${{ matrix.php-version == env.COVERAGE_PHP_VERSION }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/vendor
/composer.lock
/.phpunit.result.cache
/.phpunit.cache
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

All notable changes to this project will be documented in this file.

## [0.12.0](https://github.com/brick/math/releases/tag/0.12.0) - 2023-11-26

💥 **Breaking changes**

- Minimum PHP version is now 8.1
- `RoundingMode` is now an `enum`; if you're type-hinting rounding modes, you need to type-hint against `RoundingMode` instead of `int` now
- `BigNumber` classes do not implement the `Serializable` interface anymore (they use the [new custom object serialization mechanism](https://wiki.php.net/rfc/custom_object_serialization))
- The following breaking changes only affect you if you're creating your own `BigNumber` subclasses:
- the return type of `BigNumber::of()` is now `static`
- `BigNumber` has a new abstract method `from()`
- all `public` and `protected` functions of `BigNumber` are now `final`

## [0.11.0](https://github.com/brick/math/releases/tag/0.11.0) - 2023-01-16

💥 **Breaking changes**
Expand Down
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ composer require brick/math

### Requirements

This library requires PHP 8.0 or later.
This library requires PHP 8.1 or later.

For PHP 7.4 compatibility, you can use version `0.10`. For PHP 7.1, 7.2 & 7.3, you can use version `0.9`. Note that [these PHP versions are EOL](http://php.net/supported-versions.php) and not supported anymore. If you're still using one of these PHP versions, you should consider upgrading as soon as possible.
For PHP 8.0 compatibility, you can use version `0.12`. For PHP 7.4, you can use version `0.10`. For PHP 7.1, 7.2 & 7.3, you can use version `0.9`. Note that [these PHP versions are EOL](http://php.net/supported-versions.php) and not supported anymore. If you're still using one of these PHP versions, you should consider upgrading as soon as possible.

Although the library can work seamlessly on any PHP installation, it is highly recommended that you install the
[GMP](http://php.net/manual/en/book.gmp.php) or [BCMath](http://php.net/manual/en/book.bc.php) extension
Expand All @@ -38,7 +38,7 @@ existing code, etc.), `y` is incremented.

**When a breaking change is introduced, a new `0.x` version cycle is always started.**

It is therefore safe to lock your project to a given release cycle, such as `^0.11`.
It is therefore safe to lock your project to a given release cycle, such as `^0.12`.

If you need to upgrade to a newer release cycle, check the [release history](https://github.com/brick/math/releases)
for a list of changes introduced by each further `0.x.0` version.
Expand All @@ -47,20 +47,20 @@ for a list of changes introduced by each further `0.x.0` version.

This library provides the following public classes in the `Brick\Math` namespace:

- [BigNumber](https://github.com/brick/math/blob/0.11.0/src/BigNumber.php): base class for `BigInteger`, `BigDecimal` and `BigRational`
- [BigInteger](https://github.com/brick/math/blob/0.11.0/src/BigInteger.php): represents an arbitrary-precision integer number.
- [BigDecimal](https://github.com/brick/math/blob/0.11.0/src/BigDecimal.php): represents an arbitrary-precision decimal number.
- [BigRational](https://github.com/brick/math/blob/0.11.0/src/BigRational.php): represents an arbitrary-precision rational number (fraction).
- [RoundingMode](https://github.com/brick/math/blob/0.11.0/src/RoundingMode.php): holds constants for the rounding modes.
- [BigNumber](https://github.com/brick/math/blob/0.12.0/src/BigNumber.php): base class for `BigInteger`, `BigDecimal` and `BigRational`
- [BigInteger](https://github.com/brick/math/blob/0.12.0/src/BigInteger.php): represents an arbitrary-precision integer number.
- [BigDecimal](https://github.com/brick/math/blob/0.12.0/src/BigDecimal.php): represents an arbitrary-precision decimal number.
- [BigRational](https://github.com/brick/math/blob/0.12.0/src/BigRational.php): represents an arbitrary-precision rational number (fraction).
- [RoundingMode](https://github.com/brick/math/blob/0.12.0/src/RoundingMode.php): enum representing all available rounding modes.

And the following exceptions in the `Brick\Math\Exception` namespace:

- [MathException](https://github.com/brick/math/blob/0.11.0/src/Exception/MathException.php): base class for all exceptions
- [DivisionByZeroException](https://github.com/brick/math/blob/0.11.0/src/Exception/DivisionByZeroException.php): thrown when a division by zero occurs
- [IntegerOverflowException](https://github.com/brick/math/blob/0.11.0/src/Exception/IntegerOverflowException.php): thrown when attempting to convert a too large `BigInteger` to `int`
- [NumberFormatException](https://github.com/brick/math/blob/0.11.0/src/Exception/NumberFormatException.php): thrown when parsing a number string in an invalid format
- [RoundingNecessaryException](https://github.com/brick/math/blob/0.11.0/src/Exception/RoundingNecessaryException.php): thrown when the result of the operation cannot be represented without explicit rounding
- [NegativeNumberException](https://github.com/brick/math/blob/0.11.0/src/Exception/NegativeNumberException.php): thrown when attempting to calculate the square root of a negative number
- [MathException](https://github.com/brick/math/blob/0.12.0/src/Exception/MathException.php): base class for all exceptions
- [DivisionByZeroException](https://github.com/brick/math/blob/0.12.0/src/Exception/DivisionByZeroException.php): thrown when a division by zero occurs
- [IntegerOverflowException](https://github.com/brick/math/blob/0.12.0/src/Exception/IntegerOverflowException.php): thrown when attempting to convert a too large `BigInteger` to `int`
- [NumberFormatException](https://github.com/brick/math/blob/0.12.0/src/Exception/NumberFormatException.php): thrown when parsing a number string in an invalid format
- [RoundingNecessaryException](https://github.com/brick/math/blob/0.12.0/src/Exception/RoundingNecessaryException.php): thrown when the result of the operation cannot be represented without explicit rounding
- [NegativeNumberException](https://github.com/brick/math/blob/0.12.0/src/Exception/NegativeNumberException.php): thrown when attempting to calculate the square root of a negative number

### Overview

Expand Down Expand Up @@ -88,7 +88,7 @@ BigRational::of('2/3');
BigRational::of('1.1'); // 11/10
```

Note that all `of()` methods accept all of the representations above, *as long as it can be safely converted to
Note that all `of()` methods accept all the representations above, *as long as it can be safely converted to
the current type*:

```php
Expand Down Expand Up @@ -174,7 +174,7 @@ echo BigInteger::of(999)->dividedBy(3); // 333
echo BigInteger::of(1000)->dividedBy(3); // RoundingNecessaryException
```

You can pass an optional [rounding mode](https://github.com/brick/math/blob/0.11.0/src/RoundingMode.php) to round the result, if necessary:
You can pass an optional [rounding mode](https://github.com/brick/math/blob/0.12.0/src/RoundingMode.php) to round the result, if necessary:

```php
echo BigInteger::of(1000)->dividedBy(3, RoundingMode::DOWN); // 333
Expand All @@ -197,7 +197,7 @@ You can even get both at the same time:
##### BigDecimal

Dividing a `BigDecimal` always requires a scale to be specified. If the exact result of the division does not fit in
the given scale, a [rounding mode](https://github.com/brick/math/blob/0.11.0/src/RoundingMode.php) must be provided.
the given scale, a [rounding mode](https://github.com/brick/math/blob/0.12.0/src/RoundingMode.php) must be provided.

```php
echo BigDecimal::of(1)->dividedBy('8', 3); // 0.125
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
],
"license": "MIT",
"require": {
"php": "^8.0"
"php": "^8.1"
},
"require-dev": {
"phpunit/phpunit": "^9.0",
"phpunit/phpunit": "^10.1",
"php-coveralls/php-coveralls": "^2.2",
"vimeo/psalm": "5.14.1"
"vimeo/psalm": "5.16.0"
},
"autoload": {
"psr-4": {
Expand Down
8 changes: 4 additions & 4 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" bootstrap="phpunit.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" bootstrap="phpunit.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" cacheDirectory=".phpunit.cache">
<testsuites>
<testsuite name="Math tests">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<source>
<include>
<directory suffix=".php">src</directory>
<directory>src</directory>
</include>
</coverage>
</source>
</phpunit>
6 changes: 0 additions & 6 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,5 @@
<file name="src/Internal/Calculator/BcMathCalculator.php" />
</errorLevel>
</ArgumentTypeCoercion>

<ImpureByReferenceAssignment>
<errorLevel type="suppress">
<file name="src/Internal/Calculator.php" />
</errorLevel>
</ImpureByReferenceAssignment>
</issueHandlers>
</psalm>
10 changes: 5 additions & 5 deletions random-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
use Brick\Math\Internal\Calculator;

(new class(30) { // max digits
private Calculator\GmpCalculator $gmp;
private Calculator\BcMathCalculator $bcmath;
private Calculator\NativeCalculator $native;
private readonly Calculator\GmpCalculator $gmp;
private readonly Calculator\BcMathCalculator $bcmath;
private readonly Calculator\NativeCalculator $native;

private int $testCounter = 0;
private float $lastOutputTime = 0.0;
Expand All @@ -23,7 +23,7 @@
private int $testsPerSecond = 0;

public function __construct(
private int $maxDigits,
private readonly int $maxDigits,
) {
$this->gmp = new Calculator\GmpCalculator();
$this->bcmath = new Calculator\BcMathCalculator();
Expand Down Expand Up @@ -132,7 +132,7 @@ private function test(string $test, Closure $callback) : void
* @param string $c2 The name of the second calculator.
* @param string $test A string representing the test being executed.
*/
private function failure(string $c1, string $c2, string $test) : void
private function failure(string $c1, string $c2, string $test) : never
{
echo PHP_EOL;
echo 'FAILURE!', PHP_EOL;
Expand Down
50 changes: 9 additions & 41 deletions src/BigDecimal.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ final class BigDecimal extends BigNumber
* No leading zero must be present.
* No leading minus sign must be present if the value is 0.
*/
private string $value;
private readonly string $value;

/**
* The scale (number of digits after the decimal point) of this decimal number.
*
* This must be zero or more.
*/
private int $scale;
private readonly int $scale;

/**
* Protected constructor. Use a factory method to obtain an instance.
Expand All @@ -45,15 +45,11 @@ protected function __construct(string $value, int $scale = 0)
}

/**
* Creates a BigDecimal of the given value.
*
* @throws MathException If the value cannot be converted to a BigDecimal.
*
* @psalm-pure
*/
public static function of(BigNumber|int|float|string $value) : BigDecimal
protected static function from(BigNumber $number): static
{
return parent::of($value)->toBigDecimal();
return $number->toBigDecimal();
}

/**
Expand Down Expand Up @@ -223,12 +219,12 @@ public function multipliedBy(BigNumber|int|float|string $that) : BigDecimal
*
* @param BigNumber|int|float|string $that The divisor.
* @param int|null $scale The desired scale, or null to use the scale of this number.
* @param int $roundingMode An optional rounding mode.
* @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY.
*
* @throws \InvalidArgumentException If the scale or rounding mode is invalid.
* @throws MathException If the number is invalid, is zero, or rounding was necessary.
*/
public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
{
$that = BigDecimal::of($that);

Expand Down Expand Up @@ -384,6 +380,8 @@ public function remainder(BigNumber|int|float|string $that) : BigDecimal
*
* @return BigDecimal[] An array containing the quotient and the remainder.
*
* @psalm-return array{BigDecimal, BigDecimal}
*
* @throws MathException If the divisor is not a valid decimal number, or is zero.
*/
public function quotientAndRemainder(BigNumber|int|float|string $that) : array
Expand Down Expand Up @@ -631,7 +629,7 @@ public function toBigRational() : BigRational
return self::newBigRational($numerator, $denominator, false);
}

public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
{
if ($scale === $this->scale) {
return $this;
Expand Down Expand Up @@ -693,36 +691,6 @@ public function __unserialize(array $data): void
$this->scale = $data['scale'];
}

/**
* This method is required by interface Serializable and SHOULD NOT be accessed directly.
*
* @internal
*/
public function serialize() : string
{
return $this->value . ':' . $this->scale;
}

/**
* This method is only here to implement interface Serializable and cannot be accessed directly.
*
* @internal
* @psalm-suppress RedundantPropertyInitializationCheck
*
* @throws \LogicException
*/
public function unserialize($value) : void
{
if (isset($this->value)) {
throw new \LogicException('unserialize() is an internal function, it must not be called directly.');
}

[$value, $scale] = \explode(':', $value);

$this->value = $value;
$this->scale = (int) $scale;
}

/**
* Puts the internal values of the given decimal numbers on the same scale.
*
Expand Down
Loading

0 comments on commit 0ee0739

Please sign in to comment.