Skip to content

Commit 1f819a2

Browse files
feature #519 [PHP 8.4] Add bcdivmod (alexandre-daubois)
This PR was merged into the 1.x branch. Discussion ---------- [PHP 8.4] Add `bcdivmod` Supersedes #503. Thank you `@Ayesh`! Commits ------- 2d8a55d [PHP 8.4] Add `bcdivmod`
2 parents e373580 + 2d8a55d commit 1f819a2

File tree

5 files changed

+85
-0
lines changed

5 files changed

+85
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ Polyfills are provided for:
7373
- the `mb_trim`, `mb_ltrim` and `mb_rtrim` functions introduced in PHP 8.4;
7474
- the `CURL_HTTP_VERSION_3` and `CURL_HTTP_VERSION_3ONLY` constants introduced in PHP 8.4;
7575
- the `grapheme_str_split` function introduced in PHP 8.4;
76+
- the `bcdivmod` function introduced in PHP 8.4;
7677
- the `get_error_handler` and `get_exception_handler` functions introduced in PHP 8.5;
7778
- the `NoDiscard` attribute introduced in PHP 8.5;
7879
- the `array_first` and `array_last` functions introduced in PHP 8.5;

src/Php84/Php84.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,14 @@ public static function grapheme_str_split(string $string, int $length)
204204

205205
return $chunks;
206206
}
207+
208+
public static function bcdivmod(string $num1, string $num2, ?int $scale = null): ?array
209+
{
210+
if (null === $quot = \bcdiv($num1, $num2, 0)) {
211+
return null;
212+
}
213+
$scale = $scale ?? (\PHP_VERSION_ID >= 70300 ? \bcscale() : (ini_get('bcmath.scale') ?: 0);
214+
215+
return [$quot, \bcmod($num1, $num2, $scale)];
216+
}
207217
}

src/Php84/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Symfony Polyfill / Php84
44
This component provides features added to PHP 8.4 core:
55

66
- [`array_find`, `array_find_key`, `array_any` and `array_all`](https://wiki.php.net/rfc/array_find)
7+
- [`bcdivmod`](https://wiki.php.net/rfc/add_bcdivmod_to_bcmath)
78
- [`Deprecated`](https://wiki.php.net/rfc/deprecated_attribute)
89
- `CURL_HTTP_VERSION_3` and `CURL_HTTP_VERSION_3ONLY` constants
910
- [`fpow`](https://wiki.php.net/rfc/raising_zero_to_power_of_negative_number)

src/Php84/bootstrap.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ function mb_rtrim(string $string, ?string $characters = null, ?string $encoding
6767
}
6868
}
6969

70+
if (extension_loaded('bcmath')) {
71+
if (!function_exists('bcdivmod')) {
72+
function bcdivmod(string $num1, string $num2, ?int $scale = null): ?array { return p\Php84::bcdivmod($num1, $num2, $scale); }
73+
}
74+
}
75+
7076
if (\PHP_VERSION_ID >= 80200) {
7177
return require __DIR__.'/bootstrap82.php';
7278
}

tests/Php84/Php84Test.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,4 +693,71 @@ public static function graphemeStrSplitDataProvider(): array
693693

694694
return $cases;
695695
}
696+
697+
/**
698+
* @requires extension bcmath
699+
*
700+
* @covers \Symfony\Polyfill\Php84\Php84::bcdivmod
701+
*
702+
* @dataProvider bcDivModProvider
703+
*/
704+
public function testBcDivMod(string $num1, string $num2, ?int $scale, array $expected)
705+
{
706+
$this->assertSame($expected, bcdivmod($num1, $num2, $scale));
707+
}
708+
709+
/**
710+
* @requires extension bcmath
711+
*/
712+
public function testBcDivModDivideByZero()
713+
{
714+
$this->expectException(\DivisionByZeroError::class);
715+
716+
bcdivmod('1', '0');
717+
}
718+
719+
/**
720+
* @requires extension bcmath
721+
*/
722+
public function testBcDivModDivideByFloatingZero()
723+
{
724+
$this->expectException(\DivisionByZeroError::class);
725+
726+
bcdivmod('1', '0.00');
727+
}
728+
729+
/**
730+
* @requires PHP 8.0
731+
* @requires extension bcmath
732+
*/
733+
public function testBcDivModMalformedNumber()
734+
{
735+
$this->expectException(\ValueError::class);
736+
$this->expectExceptionMessage('Argument #1 ($num1) is not well-formed');
737+
738+
bcdivmod('a', '1');
739+
}
740+
741+
/**
742+
* @requires PHP 8.0
743+
* @requires extension bcmath
744+
*/
745+
public function testBcDivModMalformedNumber2()
746+
{
747+
$this->expectException(\ValueError::class);
748+
$this->expectExceptionMessage('Argument #2 ($num2) is not well-formed');
749+
750+
bcdivmod('1', 'a');
751+
}
752+
753+
public static function bcDivModProvider(): iterable
754+
{
755+
yield ['1', '1', null, ['1', '0']];
756+
yield ['1', '2', null, ['0', '1']];
757+
yield ['5', '2', null, ['2', '1']];
758+
yield ['5', '2', 0, ['2', '1']];
759+
yield ['5', '2', 1, ['2', '1.0']];
760+
yield ['5', '2', 2, ['2', '1.00']];
761+
yield ['7.2', '3', 2, ['2', '1.20']];
762+
}
696763
}

0 commit comments

Comments
 (0)