See Release Notes
Long Term Support Release
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\Information\ExcelError; 8 9 class Arabic 10 { 11 use ArrayEnabled; 12 13 private const ROMAN_LOOKUP = [ 14 'M' => 1000, 15 'D' => 500, 16 'C' => 100, 17 'L' => 50, 18 'X' => 10, 19 'V' => 5, 20 'I' => 1, 21 ]; 22 23 /** 24 * Recursively calculate the arabic value of a roman numeral. 25 * 26 * @param int $sum 27 * @param int $subtract 28 * 29 * @return int 30 */ 31 private static function calculateArabic(array $roman, &$sum = 0, $subtract = 0) 32 { 33 $numeral = array_shift($roman); 34 if (!isset(self::ROMAN_LOOKUP[$numeral])) { 35 throw new Exception('Invalid character detected'); 36 } 37 38 $arabic = self::ROMAN_LOOKUP[$numeral]; 39 if (count($roman) > 0 && isset(self::ROMAN_LOOKUP[$roman[0]]) && $arabic < self::ROMAN_LOOKUP[$roman[0]]) { 40 $subtract += $arabic; 41 } else { 42 $sum += ($arabic - $subtract); 43 $subtract = 0; 44 } 45 46 if (count($roman) > 0) { 47 self::calculateArabic($roman, $sum, $subtract); 48 } 49 50 return $sum; 51 } 52 53 /** 54 * @param mixed $value 55 */ 56 private static function mollifyScrutinizer($value): array 57 { 58 return is_array($value) ? $value : []; 59 } 60 61 private static function strSplit(string $roman): array 62 { 63 $rslt = str_split($roman); 64 65 return self::mollifyScrutinizer($rslt); 66 } 67 68 /** 69 * ARABIC. 70 * 71 * Converts a Roman numeral to an Arabic numeral. 72 * 73 * Excel Function: 74 * ARABIC(text) 75 * 76 * @param mixed $roman Should be a string, or can be an array of strings 77 * 78 * @return array|int|string the arabic numberal contrived from the roman numeral 79 * If an array of numbers is passed as the argument, then the returned result will also be an array 80 * with the same dimensions 81 */ 82 public static function evaluate($roman) 83 { 84 if (is_array($roman)) { 85 return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $roman); 86 } 87 88 // An empty string should return 0 89 $roman = substr(trim(strtoupper((string) $roman)), 0, 255); 90 if ($roman === '') { 91 return 0; 92 } 93 94 // Convert the roman numeral to an arabic number 95 $negativeNumber = $roman[0] === '-'; 96 if ($negativeNumber) { 97 $roman = substr($roman, 1); 98 } 99 100 try { 101 $arabic = self::calculateArabic(self::strSplit($roman)); 102 } catch (Exception $e) { 103 return ExcelError::VALUE(); // Invalid character detected 104 } 105 106 if ($negativeNumber) { 107 $arabic *= -1; // The number should be negative 108 } 109 110 return $arabic; 111 } 112 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body