@@ -22,12 +22,12 @@ class Ceiling
22
22
* Excel Function:
23
23
* CEILING(number[,significance])
24
24
*
25
- * @param array|float $number the number you want the ceiling
25
+ * @param array<mixed> |float $number the number you want the ceiling
26
26
* Or can be an array of values
27
- * @param array|float $significance the multiple to which you want to round
27
+ * @param array<mixed> |float $significance the multiple to which you want to round
28
28
* Or can be an array of values
29
29
*
30
- * @return array|float|string Rounded Number, or a string containing an error
30
+ * @return array<mixed> |float|string Rounded Number, or a string containing an error
31
31
* If an array of numbers is passed as an argument, then the returned result will also be an array
32
32
* with the same dimensions
33
33
*/
@@ -63,14 +63,14 @@ public static function ceiling($number, $significance = null)
63
63
* Or can be an array of values
64
64
* @param mixed $significance Significance
65
65
* Or can be an array of values
66
- * @param array|int $mode direction to round negative numbers
66
+ * @param array<mixed> |int $mode direction to round negative numbers
67
67
* Or can be an array of values
68
68
*
69
- * @return array|float|string Rounded Number, or a string containing an error
69
+ * @return array<mixed> |float|string Rounded Number, or a string containing an error
70
70
* If an array of numbers is passed as an argument, then the returned result will also be an array
71
71
* with the same dimensions
72
72
*/
73
- public static function math (mixed $ number , mixed $ significance = null , $ mode = 0 ): array |string |float
73
+ public static function math (mixed $ number , mixed $ significance = null , $ mode = 0 , bool $ checkSigns = false ): array |string |float
74
74
{
75
75
if (is_array ($ number ) || is_array ($ significance ) || is_array ($ mode )) {
76
76
return self ::evaluateArrayArguments ([self ::class, __FUNCTION__ ], $ number , $ significance , $ mode );
@@ -87,6 +87,11 @@ public static function math(mixed $number, mixed $significance = null, $mode = 0
87
87
if (empty ($ significance * $ number )) {
88
88
return 0.0 ;
89
89
}
90
+ if ($ checkSigns ) {
91
+ if (($ number > 0 && $ significance < 0 ) || ($ number < 0 && $ significance > 0 )) {
92
+ return ExcelError::NAN ();
93
+ }
94
+ }
90
95
if (self ::ceilingMathTest ((float ) $ significance , (float ) $ number , (int ) $ mode )) {
91
96
return floor ($ number / $ significance ) * $ significance ;
92
97
}
@@ -104,10 +109,10 @@ public static function math(mixed $number, mixed $significance = null, $mode = 0
104
109
*
105
110
* @param mixed $number the number you want to round
106
111
* Or can be an array of values
107
- * @param array|float $significance the multiple to which you want to round
112
+ * @param array<mixed> |float $significance the multiple to which you want to round
108
113
* Or can be an array of values
109
114
*
110
- * @return array|float|string Rounded Number, or a string containing an error
115
+ * @return array<mixed> |float|string Rounded Number, or a string containing an error
111
116
* If an array of numbers is passed as an argument, then the returned result will also be an array
112
117
* with the same dimensions
113
118
*/
@@ -132,6 +137,23 @@ public static function precise(mixed $number, $significance = 1): array|string|f
132
137
return ceil ($ result ) * $ significance * (($ significance < 0 ) ? -1 : 1 );
133
138
}
134
139
140
+ /**
141
+ * CEILING.ODS, pseudo-function - CEILING as implemented in ODS.
142
+ *
143
+ * ODS Function (theoretical):
144
+ * CEILING.ODS(number[,significance[,mode]])
145
+ *
146
+ * @param mixed $number Number to round
147
+ * @param mixed $significance Significance
148
+ * @param array<mixed>|int $mode direction to round negative numbers
149
+ *
150
+ * @return array<mixed>|float|string Rounded Number, or a string containing an error
151
+ */
152
+ public static function mathOds (mixed $ number , mixed $ significance = null , $ mode = 0 ): array |string |float
153
+ {
154
+ return self ::math ($ number , $ significance , $ mode , true );
155
+ }
156
+
135
157
/**
136
158
* Let CEILINGMATH complexity pass Scrutinizer.
137
159
*/
@@ -148,7 +170,12 @@ private static function argumentsOk(float $number, float $significance): float|s
148
170
if (empty ($ number * $ significance )) {
149
171
return 0.0 ;
150
172
}
151
- if (Helpers::returnSign ($ number ) == Helpers::returnSign ($ significance )) {
173
+ $ signSig = Helpers::returnSign ($ significance );
174
+ $ signNum = Helpers::returnSign ($ number );
175
+ if (
176
+ ($ signSig === 1 && ($ signNum === 1 || Functions::getCompatibilityMode () !== Functions::COMPATIBILITY_GNUMERIC ))
177
+ || ($ signSig === -1 && $ signNum === -1 )
178
+ ) {
152
179
return ceil ($ number / $ significance ) * $ significance ;
153
180
}
154
181
0 commit comments