Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
   4  
   5  use PhpOffice\PhpSpreadsheet\Calculation\Exception;
   6  use PhpOffice\PhpSpreadsheet\Calculation\Functions;
   7  
   8  class Arabic
   9  {
  10      private const ROMAN_LOOKUP = [
  11          'M' => 1000,
  12          'D' => 500,
  13          'C' => 100,
  14          'L' => 50,
  15          'X' => 10,
  16          'V' => 5,
  17          'I' => 1,
  18      ];
  19  
  20      /**
  21       * Recursively calculate the arabic value of a roman numeral.
  22       *
  23       * @param int $sum
  24       * @param int $subtract
  25       *
  26       * @return int
  27       */
  28      private static function calculateArabic(array $roman, &$sum = 0, $subtract = 0)
  29      {
  30          $numeral = array_shift($roman);
  31          if (!isset(self::ROMAN_LOOKUP[$numeral])) {
  32              throw new Exception('Invalid character detected');
  33          }
  34  
  35          $arabic = self::ROMAN_LOOKUP[$numeral];
  36          if (count($roman) > 0 && isset(self::ROMAN_LOOKUP[$roman[0]]) && $arabic < self::ROMAN_LOOKUP[$roman[0]]) {
  37              $subtract += $arabic;
  38          } else {
  39              $sum += ($arabic - $subtract);
  40              $subtract = 0;
  41          }
  42  
  43          if (count($roman) > 0) {
  44              self::calculateArabic($roman, $sum, $subtract);
  45          }
  46  
  47          return $sum;
  48      }
  49  
  50      /**
  51       * @param mixed $value
  52       */
  53      private static function mollifyScrutinizer($value): array
  54      {
  55          return is_array($value) ? $value : [];
  56      }
  57  
  58      private static function strSplit(string $roman): array
  59      {
  60          $rslt = str_split($roman);
  61  
  62          return self::mollifyScrutinizer($rslt);
  63      }
  64  
  65      /**
  66       * ARABIC.
  67       *
  68       * Converts a Roman numeral to an Arabic numeral.
  69       *
  70       * Excel Function:
  71       *        ARABIC(text)
  72       *
  73       * @param string $roman
  74       *
  75       * @return int|string the arabic numberal contrived from the roman numeral
  76       */
  77      public static function evaluate($roman)
  78      {
  79          // An empty string should return 0
  80          $roman = substr(trim(strtoupper((string) Functions::flattenSingleValue($roman))), 0, 255);
  81          if ($roman === '') {
  82              return 0;
  83          }
  84  
  85          // Convert the roman numeral to an arabic number
  86          $negativeNumber = $roman[0] === '-';
  87          if ($negativeNumber) {
  88              $roman = substr($roman, 1);
  89          }
  90  
  91          try {
  92              $arabic = self::calculateArabic(self::strSplit($roman));
  93          } catch (Exception $e) {
  94              return Functions::VALUE(); // Invalid character detected
  95          }
  96  
  97          if ($negativeNumber) {
  98              $arabic *= -1; // The number should be negative
  99          }
 100  
 101          return $arabic;
 102      }
 103  }