function Calculator::divRound
Performs a rounded division.
Rounding is performed when the remainder of the division is not zero.
@psalm-suppress ImpureFunctionCall
Parameters
string $a The dividend.:
string $b The divisor, must not be zero.:
RoundingMode $roundingMode The rounding mode.:
Throws
\InvalidArgumentException If the rounding mode is invalid.
RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary.
File
-
vendor/
brick/ math/ src/ Internal/ Calculator.php, line 442
Class
- Calculator
- Performs basic operations on arbitrary size integers.
Namespace
Brick\Math\InternalCode
public final function divRound(string $a, string $b, RoundingMode $roundingMode) : string {
[
$quotient,
$remainder,
] = $this->divQR($a, $b);
$hasDiscardedFraction = $remainder !== '0';
$isPositiveOrZero = ($a[0] === '-') === ($b[0] === '-');
$discardedFractionSign = function () use ($remainder, $b) : int {
$r = $this->abs($this->mul($remainder, '2'));
$b = $this->abs($b);
return $this->cmp($r, $b);
};
$increment = false;
switch ($roundingMode) {
case RoundingMode::UNNECESSARY:
if ($hasDiscardedFraction) {
throw RoundingNecessaryException::roundingNecessary();
}
break;
case RoundingMode::UP:
$increment = $hasDiscardedFraction;
break;
case RoundingMode::DOWN:
break;
case RoundingMode::CEILING:
$increment = $hasDiscardedFraction && $isPositiveOrZero;
break;
case RoundingMode::FLOOR:
$increment = $hasDiscardedFraction && !$isPositiveOrZero;
break;
case RoundingMode::HALF_UP:
$increment = $discardedFractionSign() >= 0;
break;
case RoundingMode::HALF_DOWN:
$increment = $discardedFractionSign() > 0;
break;
case RoundingMode::HALF_CEILING:
$increment = $isPositiveOrZero ? $discardedFractionSign() >= 0 : $discardedFractionSign() > 0;
break;
case RoundingMode::HALF_FLOOR:
$increment = $isPositiveOrZero ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0;
break;
case RoundingMode::HALF_EVEN:
$lastDigit = (int) $quotient[-1];
$lastDigitIsEven = $lastDigit % 2 === 0;
$increment = $lastDigitIsEven ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0;
break;
default:
throw new \InvalidArgumentException('Invalid rounding mode.');
}
if ($increment) {
return $this->add($quotient, $isPositiveOrZero ? '1' : '-1');
}
return $quotient;
}