@@ -38,6 +38,64 @@ private static function romanCut($num, $n)
38
38
return ($ num - ($ num % $ n )) / $ n ;
39
39
}
40
40
41
+ /**
42
+ * ARABIC.
43
+ *
44
+ * Converts a Roman numeral to an Arabic numeral.
45
+ *
46
+ * Excel Function:
47
+ * ARABIC(text)
48
+ *
49
+ * @category Mathematical and Trigonometric Functions
50
+ *
51
+ * @param string $roman
52
+ *
53
+ * @return int|string the arabic numberal contrived from the roman numeral
54
+ */
55
+ public static function ARABIC ($ roman )
56
+ {
57
+ // An empty string should return 0
58
+ $ roman = substr (trim (strtoupper ((string ) Functions::flattenSingleValue ($ roman ))), 0 , 255 );
59
+ if ($ roman === '' ) {
60
+ return 0 ;
61
+ }
62
+
63
+ // Convert the roman numeral to an arabic number
64
+ $ lookup = [
65
+ 'M ' => 1000 , 'CM ' => 900 ,
66
+ 'D ' => 500 , 'CD ' => 400 ,
67
+ 'C ' => 100 , 'XC ' => 90 ,
68
+ 'L ' => 50 , 'XL ' => 40 ,
69
+ 'X ' => 10 , 'IX ' => 9 ,
70
+ 'V ' => 5 , 'IV ' => 4 , 'I ' => 1 ,
71
+ ];
72
+
73
+ $ negativeNumber = $ roman [0 ] === '- ' ;
74
+ if ($ negativeNumber ) {
75
+ $ roman = substr ($ roman , 1 );
76
+ }
77
+
78
+ $ arabic = 0 ;
79
+ for ($ i = 0 ; $ i < strlen ($ roman ); ++$ i ) {
80
+ if (!isset ($ lookup [$ roman [$ i ]])) {
81
+ return Functions::VALUE (); // Invalid character detected
82
+ }
83
+
84
+ if ($ i < (strlen ($ roman ) - 1 ) && isset ($ lookup [substr ($ roman , $ i , 2 )])) {
85
+ $ arabic += $ lookup [substr ($ roman , $ i , 2 )]; // Detected a match on the next 2 characters
86
+ ++$ i ;
87
+ } else {
88
+ $ arabic += $ lookup [$ roman [$ i ]]; // Detected a match on one character only
89
+ }
90
+ }
91
+
92
+ if ($ negativeNumber ) {
93
+ $ arabic *= -1 ; // The number should be negative
94
+ }
95
+
96
+ return $ arabic ;
97
+ }
98
+
41
99
/**
42
100
* ATAN2.
43
101
*
0 commit comments