public static function Calculator::round in Commerce Core 8.2
Rounds the given number.
Replicates PHP's support for rounding to the nearest even/odd number even if that number is decimal ($precision > 0).
Parameters
string $number: The number.
int $precision: The number of decimals to round to.
int $mode: The rounding mode. One of the following constants: PHP_ROUND_HALF_UP, PHP_ROUND_HALF_DOWN, PHP_ROUND_HALF_EVEN, PHP_ROUND_HALF_ODD.
Return value
string The rounded number.
Throws
\InvalidArgumentException Thrown when an invalid (non-numeric or negative) precision is given.
2 calls to Calculator::round()
- CalculatorTest::testRounding in modules/price/ tests/ src/ Unit/ CalculatorTest.php 
- @covers ::ceil @covers ::floor @covers ::round
- Rounder::round in modules/price/ src/ Rounder.php 
- Rounds the given price to its currency precision.
File
- modules/price/ src/ Calculator.php, line 158 
Class
- Calculator
- Provides helpers for bcmath-based arithmetic.
Namespace
Drupal\commerce_priceCode
public static function round(string $number, int $precision = 0, int $mode = PHP_ROUND_HALF_UP) : string {
  self::assertNumberFormat($number);
  if (!is_numeric($precision) || $precision < 0) {
    throw new \InvalidArgumentException('The provided precision should be a positive number');
  }
  // Round the number in both directions (up/down) before choosing one.
  $rounding_increment = bcdiv('1', pow(10, $precision), $precision);
  if (self::compare($number, '0') == 1) {
    $rounded_up = bcadd($number, $rounding_increment, $precision);
  }
  else {
    $rounded_up = bcsub($number, $rounding_increment, $precision);
  }
  $rounded_down = bcsub($number, 0, $precision);
  // The rounding direction is based on the first decimal after $precision.
  $number_parts = explode('.', $number);
  $decimals = !empty($number_parts[1]) ? $number_parts[1] : '0';
  $relevant_decimal = isset($decimals[$precision]) ? $decimals[$precision] : 0;
  if ($relevant_decimal < 5) {
    $number = $rounded_down;
  }
  elseif ($relevant_decimal == 5) {
    if ($mode == PHP_ROUND_HALF_UP) {
      $number = $rounded_up;
    }
    elseif ($mode == PHP_ROUND_HALF_DOWN) {
      $number = $rounded_down;
    }
    elseif ($mode == PHP_ROUND_HALF_EVEN) {
      $integer = bcmul($rounded_up, pow(10, $precision), 0);
      $number = bcmod($integer, '2') == 0 ? $rounded_up : $rounded_down;
    }
    elseif ($mode == PHP_ROUND_HALF_ODD) {
      $integer = bcmul($rounded_up, pow(10, $precision), 0);
      $number = bcmod($integer, '2') != 0 ? $rounded_up : $rounded_down;
    }
  }
  elseif ($relevant_decimal > 5) {
    $number = $rounded_up;
  }
  return $number;
}