Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 400 and 401]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
   4  
   5  use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
   6  use PhpOffice\PhpSpreadsheet\Calculation\Exception;
   7  use PhpOffice\PhpSpreadsheet\Calculation\Functions;
   8  use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
   9  
  10  class Ceiling
  11  {
  12      use ArrayEnabled;
  13  
  14      /**
  15       * CEILING.
  16       *
  17       * Returns number rounded up, away from zero, to the nearest multiple of significance.
  18       *        For example, if you want to avoid using pennies in your prices and your product is
  19       *        priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the
  20       *        nearest nickel.
  21       *
  22       * Excel Function:
  23       *        CEILING(number[,significance])
  24       *
  25       * @param array|float $number the number you want the ceiling
  26       *                      Or can be an array of values
  27       * @param array|float $significance the multiple to which you want to round
  28       *                      Or can be an array of values
  29       *
  30       * @return array|float|string Rounded Number, or a string containing an error
  31       *         If an array of numbers is passed as an argument, then the returned result will also be an array
  32       *            with the same dimensions
  33       */
  34      public static function ceiling($number, $significance = null)
  35      {
  36          if (is_array($number) || is_array($significance)) {
  37              return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance);
  38          }
  39  
  40          if ($significance === null) {
  41              self::floorCheck1Arg();
  42          }
  43  
  44          try {
  45              $number = Helpers::validateNumericNullBool($number);
  46              $significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
  47          } catch (Exception $e) {
  48              return $e->getMessage();
  49          }
  50  
  51          return self::argumentsOk((float) $number, (float) $significance);
  52      }
  53  
  54      /**
  55       * CEILING.MATH.
  56       *
  57       * Round a number down to the nearest integer or to the nearest multiple of significance.
  58       *
  59       * Excel Function:
  60       *        CEILING.MATH(number[,significance[,mode]])
  61       *
  62       * @param mixed $number Number to round
  63       *                      Or can be an array of values
  64       * @param mixed $significance Significance
  65       *                      Or can be an array of values
  66       * @param array|int $mode direction to round negative numbers
  67       *                      Or can be an array of values
  68       *
  69       * @return array|float|string Rounded Number, or a string containing an error
  70       *         If an array of numbers is passed as an argument, then the returned result will also be an array
  71       *            with the same dimensions
  72       */
  73      public static function math($number, $significance = null, $mode = 0)
  74      {
  75          if (is_array($number) || is_array($significance) || is_array($mode)) {
  76              return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance, $mode);
  77          }
  78  
  79          try {
  80              $number = Helpers::validateNumericNullBool($number);
  81              $significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
  82              $mode = Helpers::validateNumericNullSubstitution($mode, null);
  83          } catch (Exception $e) {
  84              return $e->getMessage();
  85          }
  86  
  87          if (empty($significance * $number)) {
  88              return 0.0;
  89          }
  90          if (self::ceilingMathTest((float) $significance, (float) $number, (int) $mode)) {
  91              return floor($number / $significance) * $significance;
  92          }
  93  
  94          return ceil($number / $significance) * $significance;
  95      }
  96  
  97      /**
  98       * CEILING.PRECISE.
  99       *
 100       * Rounds number up, away from zero, to the nearest multiple of significance.
 101       *
 102       * Excel Function:
 103       *        CEILING.PRECISE(number[,significance])
 104       *
 105       * @param mixed $number the number you want to round
 106       *                      Or can be an array of values
 107       * @param array|float $significance the multiple to which you want to round
 108       *                      Or can be an array of values
 109       *
 110       * @return array|float|string Rounded Number, or a string containing an error
 111       *         If an array of numbers is passed as an argument, then the returned result will also be an array
 112       *            with the same dimensions
 113       */
 114      public static function precise($number, $significance = 1)
 115      {
 116          if (is_array($number) || is_array($significance)) {
 117              return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance);
 118          }
 119  
 120          try {
 121              $number = Helpers::validateNumericNullBool($number);
 122              $significance = Helpers::validateNumericNullSubstitution($significance, null);
 123          } catch (Exception $e) {
 124              return $e->getMessage();
 125          }
 126  
 127          if (!$significance) {
 128              return 0.0;
 129          }
 130          $result = $number / abs($significance);
 131  
 132          return ceil($result) * $significance * (($significance < 0) ? -1 : 1);
 133      }
 134  
 135      /**
 136       * Let CEILINGMATH complexity pass Scrutinizer.
 137       */
 138      private static function ceilingMathTest(float $significance, float $number, int $mode): bool
 139      {
 140          return ((float) $significance < 0) || ((float) $number < 0 && !empty($mode));
 141      }
 142  
 143      /**
 144       * Avoid Scrutinizer problems concerning complexity.
 145       *
 146       * @return float|string
 147       */
 148      private static function argumentsOk(float $number, float $significance)
 149      {
 150          if (empty($number * $significance)) {
 151              return 0.0;
 152          }
 153          if (Helpers::returnSign($number) == Helpers::returnSign($significance)) {
 154              return ceil($number / $significance) * $significance;
 155          }
 156  
 157          return ExcelError::NAN();
 158      }
 159  
 160      private static function floorCheck1Arg(): void
 161      {
 162          $compatibility = Functions::getCompatibilityMode();
 163          if ($compatibility === Functions::COMPATIBILITY_EXCEL) {
 164              throw new Exception('Excel requires 2 arguments for CEILING');
 165          }
 166      }
 167  }