Skip to content

Commit dd20ad6

Browse files
authored
Merge pull request #96 from JesterIruka/master
Add clamp function to BigDecimal and BigInteger
2 parents 80c4108 + f2a3d34 commit dd20ad6

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

src/BigDecimal.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,28 @@ public function exactlyDividedBy(BigNumber|int|float|string $that) : BigDecimal
297297
return $this->dividedBy($that, $scale)->stripTrailingZeros();
298298
}
299299

300+
/**
301+
* Limits (clamps) this number between the given minimum and maximum values.
302+
*
303+
* If the number is lower than $min, returns a copy of $min.
304+
* If the number is greater than $max, returns a copy of $max.
305+
* Otherwise, returns this number unchanged.
306+
*
307+
* @param BigNumber|int|float|string $min The minimum. Must be convertible to a BigDecimal.
308+
* @param BigNumber|int|float|string $max The maximum. Must be convertible to a BigDecimal.
309+
*
310+
* @throws MathException If min/max are not convertible to a BigDecimal.
311+
*/
312+
public function clamp(BigNumber|int|float|string $min, BigNumber|int|float|string $max) : BigDecimal
313+
{
314+
if ($this->isLessThan($min)) {
315+
return BigDecimal::of($min);
316+
} elseif ($this->isGreaterThan($max)) {
317+
return BigDecimal::of($max);
318+
}
319+
return $this;
320+
}
321+
300322
/**
301323
* Returns this number exponentiated to the given value.
302324
*

src/BigInteger.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,29 @@ public function dividedBy(BigNumber|int|float|string $that, RoundingMode $roundi
450450
return new BigInteger($result);
451451
}
452452

453+
/**
454+
* Limits (clamps) this number between the given minimum and maximum values.
455+
*
456+
* If the number is lower than $min, returns a copy of $min.
457+
* If the number is greater than $max, returns a copy of $max.
458+
* Otherwise, returns this number unchanged.
459+
*
460+
* @param BigNumber|int|float|string $min The minimum. Must be convertible to a BigInteger.
461+
* @param BigNumber|int|float|string $max The maximum. Must be convertible to a BigInteger.
462+
*
463+
* @throws MathException If min/max are not convertible to a BigInteger.
464+
*/
465+
public function clamp(BigNumber|int|float|string $min, BigNumber|int|float|string $max) : BigInteger
466+
{
467+
if ($this->isLessThan($min)) {
468+
return BigInteger::of($min);
469+
} elseif ($this->isGreaterThan($max)) {
470+
return BigInteger::of($max);
471+
}
472+
return $this;
473+
}
474+
475+
453476
/**
454477
* Returns this number exponentiated to the given value.
455478
*

tests/BigDecimalTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,28 @@ public function testSqrtWithNegativeScale() : void
17481748
$number->sqrt(-1);
17491749
}
17501750

1751+
#[DataProvider('providerClamp')]
1752+
public function testClamp(string $number, string $min, string $max, string $expected)
1753+
{
1754+
self::assertBigDecimalEquals($expected, BigDecimal::of($number)->clamp($min, $max));
1755+
}
1756+
1757+
public static function providerClamp() : array
1758+
{
1759+
return [
1760+
["1.00", "0.50", "1.50", "1.00"],
1761+
["0.25", "0.50", "1.50", "0.50"],
1762+
["2.00", "0.50", "1.50", "1.50"],
1763+
["0.50", "0.50", "1.50", "0.50"],
1764+
["1.50", "0.50", "1.50", "1.50"],
1765+
["0.00", "0.50", "1.50", "0.50"],
1766+
["1.00", "0.50", "1.50", "1.00"],
1767+
["0.25", "0.00", "0.50", "0.25"],
1768+
["-1.00", "0.50", "1.50", "0.50"],
1769+
["-1.00", "-1.50", "-0.50", "-1.00"],
1770+
];
1771+
}
1772+
17511773
/**
17521774
* @param string $number The base number.
17531775
* @param int $exponent The exponent to apply.

tests/BigIntegerTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,28 @@ public function testModPowZeroThrowsException() : void
14561456
BigInteger::of(1)->modPow(1, 0);
14571457
}
14581458

1459+
#[DataProvider('providerClamp')]
1460+
public function testClamp(string $number, string $min, string $max, string $expected)
1461+
{
1462+
self::assertBigIntegerEquals($expected, BigInteger::of($number)->clamp($min, $max));
1463+
}
1464+
1465+
public static function providerClamp() : array
1466+
{
1467+
return [
1468+
["100", "50", "150", "100"],
1469+
["25", "50", "150", "50"],
1470+
["200", "50", "150", "150"],
1471+
["50", "50", "150", "50"],
1472+
["150", "50", "150", "150"],
1473+
["0", "50", "150", "50"],
1474+
["100", "50", "150", "100"],
1475+
["25", "0", "50", "25"],
1476+
["-100", "50", "150", "50"],
1477+
["-100", "-150", "-50", "-100"]
1478+
];
1479+
}
1480+
14591481
/**
14601482
* @param string $number The base number.
14611483
* @param int $exponent The exponent to apply.

0 commit comments

Comments
 (0)