commit
message
[Formulas] reserving '...values' for special cases, convering all others to normal arguments
author
Ben Vogt <[email protected]>
date
2017-05-13 22:18:26
stats
16 file(s) changed,
1062 insertions(+),
1017 deletions(-)
files
README.md
src/Formulas/Date.ts
src/Formulas/Engineering.ts
src/Formulas/Financial.ts
src/Formulas/Logical.ts
src/Formulas/Math.ts
src/Formulas/Statistical.ts
src/Formulas/Text.ts
tests/Formulas/DateFormulasTest.ts
tests/Formulas/DateFormulasTestTimeOverride.ts
tests/Formulas/EngineeringTest.ts
tests/Formulas/FinancialTest.ts
tests/Formulas/LogicalTest.ts
tests/Formulas/MathTest.ts
tests/Formulas/StatisticalTest.ts
tests/Formulas/TextTest.ts
1diff --git a/README.md b/README.md
2index a045a04..7d8cde8 100644
3--- a/README.md
4+++ b/README.md
5@@ -68,10 +68,6 @@ TypeConverter.
6 ### Test CriteriaFunctionFactory
7
8
9-### Use `arguments` instead of `...values` for performance reasons.
10-And use `.call()` when testing with weird param numbers.
11-
12-
13 ### Pull static functions outside of formulas, declare once.
14
15
16diff --git a/src/Formulas/Date.ts b/src/Formulas/Date.ts
17index 2835662..f495474 100644
18--- a/src/Formulas/Date.ts
19+++ b/src/Formulas/Date.ts
20@@ -14,18 +14,18 @@ import {
21
22 /**
23 * Converts a provided year, month, and day into a date.
24- * @param values[0] year - The year component of the date.
25- * @param values[1] month - The month component of the date.
26- * @param values[2] day - The day component of the date.
27+ * @param year - The year component of the date.
28+ * @param month - The month component of the date.
29+ * @param day - The day component of the date.
30 * @returns {number} newly created date.
31 * @constructor
32 */
33-var DATE = function (...values) : number {
34+var DATE = function (year, month, day) : number {
35 const FIRST_YEAR = 1900;
36- ArgsChecker.checkLength(values, 3, "DATE");
37- var year = Math.abs(Math.floor(TypeConverter.firstValueAsNumber(values[0]))); // No negative values for year
38- var month = Math.floor(TypeConverter.firstValueAsNumber(values[1])) - 1; // Months are between 0 and 11.
39- var day = Math.floor(TypeConverter.firstValueAsNumber(values[2])) - 1; // Days are also zero-indexed.
40+ ArgsChecker.checkLength(arguments, 3, "DATE");
41+ year = Math.abs(Math.floor(TypeConverter.firstValueAsNumber(year))); // No negative values for year
42+ month = Math.floor(TypeConverter.firstValueAsNumber(month)) - 1; // Months are between 0 and 11.
43+ day = Math.floor(TypeConverter.firstValueAsNumber(day)) - 1; // Days are also zero-indexed.
44 var m = moment.utc(TypeConverter.ORIGIN_MOMENT)
45 .add(2, "days")
46 .add(year < FIRST_YEAR ? year : year - FIRST_YEAR, 'years') // If the value is less than 1900, assume 1900 as start index for year
47@@ -41,15 +41,15 @@ var DATE = function (...values) : number {
48
49 /**
50 * Converts a provided date string in a known format to a date value.
51- * @param values[0] date_string - The string representing the date. Understood formats include any date format which is
52+ * @param dateString - The string representing the date. Understood formats include any date format which is
53 * normally auto-converted when entered, without quotation marks, directly into a cell. Understood formats may depend on
54 * region and language settings.
55 * @returns {number} of days since 1900/1/1, inclusively.
56 * @constructor
57 */
58-var DATEVALUE = function (...values) : number {
59- ArgsChecker.checkLength(values, 1, "DATEVALUE");
60- var dateString = TypeConverter.firstValueAsString(values[0]);
61+var DATEVALUE = function (dateString) : number {
62+ ArgsChecker.checkLength(arguments, 1, "DATEVALUE");
63+ dateString = TypeConverter.firstValueAsString(dateString);
64 var dateAsNumber;
65 try {
66 dateAsNumber = TypeConverter.stringToDateNumber(dateString);
67@@ -64,18 +64,18 @@ var DATEVALUE = function (...values) : number {
68
69 /**
70 * Returns a date a specified number of months before or after another date.
71- * @param values[0] start_date - The date from which to calculate the result.
72- * @param values[1] months - The number of months before (negative) or after (positive) start_date to calculate.
73+ * @param startDate - The date from which to calculate the result.
74+ * @param months - The number of months before (negative) or after (positive) start_date to calculate.
75 * @returns {number} date a specified number of months before or after another date
76 * @constructor
77 */
78-var EDATE = function (...values) : number {
79- ArgsChecker.checkLength(values, 2, "EDATE");
80- var startDateNumber = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
81+var EDATE = function (startDate, months) : number {
82+ ArgsChecker.checkLength(arguments, 2, "EDATE");
83+ var startDateNumber = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
84 if (startDateNumber < 0) {
85 throw new NumError("Function EDATE parameter 1 value is " + startDateNumber+ ". It should be greater than or equal to 0.");
86 }
87- var months = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
88+ months = Math.floor(TypeConverter.firstValueAsNumber(months));
89 // While momentToDayNumber will return an inclusive count of days since 1900/1/1, moment.Moment.add assumes exclusive
90 // count of days.
91 return TypeConverter.momentToDayNumber(moment.utc(TypeConverter.ORIGIN_MOMENT).add(startDateNumber, "days").add(months, "months"));
92@@ -85,19 +85,19 @@ var EDATE = function (...values) : number {
93 /**
94 * Returns a date representing the last day of a month which falls a specified number of months before or after another
95 * date.
96- * @param values[0] start_date - The date from which to calculate the the result.
97- * @param values[1] months - The number of months before (negative) or after (positive) start_date to consider. The last
98+ * @param startDate - The date from which to calculate the the result.
99+ * @param months - The number of months before (negative) or after (positive) start_date to consider. The last
100 * calendar day of the calculated month is returned.
101 * @returns {number} the last day of a month
102 * @constructor
103 */
104-var EOMONTH = function (...values) : number {
105- ArgsChecker.checkLength(values, 2, "EOMONTH");
106- var startDateNumber = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
107+var EOMONTH = function (startDate, months) : number {
108+ ArgsChecker.checkLength(arguments, 2, "EOMONTH");
109+ var startDateNumber = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
110 if (startDateNumber < 0) {
111 throw new NumError("Function EOMONTH parameter 1 value is " + startDateNumber + ". It should be greater than or equal to 0.");
112 }
113- var months = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
114+ months = Math.floor(TypeConverter.firstValueAsNumber(months));
115 return TypeConverter.momentToDayNumber(moment.utc(TypeConverter.ORIGIN_MOMENT)
116 .add(startDateNumber, "days")
117 .add(months, "months")
118@@ -107,43 +107,43 @@ var EOMONTH = function (...values) : number {
119
120 /**
121 * Returns the day of the month that a specific date falls on, in numeric format.
122- * @param values[0] date - The date from which to extract the day. Must be a reference to a cell containing a date, a
123+ * @param date - The date from which to extract the day. Must be a reference to a cell containing a date, a
124 * function returning a date type, or a number.
125 * @returns {number} day of the month
126 * @constructor
127 */
128-var DAY = function (...values) : number {
129- ArgsChecker.checkLength(values, 1, "DAY");
130- var dateNumber = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
131- if (dateNumber < 0) {
132- throw new NumError("Function DAY parameter 1 value is " + dateNumber + ". It should be greater than or equal to 0.");
133+var DAY = function (date) : number {
134+ ArgsChecker.checkLength(arguments, 1, "DAY");
135+ date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
136+ if (date < 0) {
137+ throw new NumError("Function DAY parameter 1 value is " + date + ". It should be greater than or equal to 0.");
138 }
139- return TypeConverter.numberToMoment(dateNumber).date();
140+ return TypeConverter.numberToMoment(date).date();
141 };
142
143
144 /**
145 * Returns the number of days between two dates.
146- * @param values[0] end_date most recently occurring
147- * @param values[1] start_date not most recently occurring
148+ * @param endDate most recently occurring
149+ * @param startDate not most recently occurring
150 * @returns {number} of days between start_date and end_date
151 * @constructor
152 */
153-var DAYS = function (...values) : number {
154- ArgsChecker.checkLength(values, 2, "DAYS");
155- var end = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
156- var start = TypeConverter.firstValueAsDateNumber(values[1], true); // tell firstValueAsDateNumber to coerce boolean
157- return end - start;
158+var DAYS = function (endDate, startDate) : number {
159+ ArgsChecker.checkLength(arguments, 2, "DAYS");
160+ endDate = TypeConverter.firstValueAsDateNumber(endDate, true); // tell firstValueAsDateNumber to coerce boolean
161+ startDate = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
162+ return endDate - startDate;
163 };
164
165
166 /**
167 * Returns the difference between two days based on the 360 day year used in some financial interest calculations.
168- * @param values[0] start_date - The start date to consider in the calculation. Must be a reference to a cell containing
169+ * @param startDate - The start date to consider in the calculation. Must be a reference to a cell containing
170 * a date, a function returning a date type, or a number.
171- * @param values[1] end_date - The end date to consider in the calculation. Must be a reference to a cell containing a
172+ * @param endDate - The end date to consider in the calculation. Must be a reference to a cell containing a
173 * date, a function returning a date type, or a number.
174- * @param values[2] method - [ OPTIONAL - 0 by default ] - An indicator of what day count method to use.
175+ * @param methodToUse - [ OPTIONAL - 0 by default ] - An indicator of what day count method to use.
176 * 0 indicates the US method - Under the US method, if start_date is the last day of a month, the day of month of
177 * start_date is changed to 30 for the purposes of the calculation. Furthermore if end_date is the last day of a month
178 * and the day of the month of start_date is earlier than the 30th, end_date is changed to the first day of the month
179@@ -153,48 +153,45 @@ var DAYS = function (...values) : number {
180 * @returns {number} of days between two dates
181 * @constructor
182 */
183-var DAYS360 = function (...values) : number {
184- ArgsChecker.checkLengthWithin(values, 2, 3, "DAYS360");
185- var start = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(values[0], true)); // tell firstValueAsDateNumber to coerce boolean
186- var end = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(values[1], true)); // tell firstValueAsDateNumber to coerce boolean
187- var methodToUse = false;
188- if (values.length === 3) {
189- methodToUse = TypeConverter.firstValueAsBoolean(values[2]);
190- }
191+var DAYS360 = function (startDate, endDate, methodToUse?) : number {
192+ ArgsChecker.checkLengthWithin(arguments, 2, 3, "DAYS360");
193+ startDate = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(startDate, true)); // tell firstValueAsDateNumber to coerce boolean
194+ endDate = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(endDate, true)); // tell firstValueAsDateNumber to coerce boolean
195+ methodToUse = methodToUse ? TypeConverter.firstValueAsBoolean(methodToUse) : false;
196 var smd = 31;
197 var emd = 31;
198- var sd = start.date();
199- var ed = end.date();
200+ var sd = startDate.date();
201+ var ed = endDate.date();
202 if (methodToUse) {
203 sd = (sd === 31) ? 30 : sd;
204 ed = (ed === 31) ? 30 : ed;
205 }
206 else {
207- if (start.month() === 1) {
208- smd = start.daysInMonth();
209+ if (startDate.month() === 1) {
210+ smd = startDate.daysInMonth();
211 }
212- if (end.month() === 1) {
213- emd = end.daysInMonth();
214+ if (endDate.month() === 1) {
215+ emd = endDate.daysInMonth();
216 }
217 sd = (sd === smd) ? 30 : sd;
218 if (sd === 30 || sd === smd) {
219 ed = (ed === emd) ? 30 : ed;
220 }
221 }
222- return 360 * (end.year() - start.year()) + 30 * (end.month() - start.month()) + (ed - sd);
223+ return 360 * (endDate.year() - startDate.year()) + 30 * (endDate.month() - startDate.month()) + (ed - sd);
224 };
225
226
227 /**
228 * Returns the month of the year a specific date falls in, in numeric format.
229- * @param values[0] date - The date from which to extract the month. Must be a reference to a cell containing a date, a
230+ * @param date - The date from which to extract the month. Must be a reference to a cell containing a date, a
231 * function returning a date type, or a number.
232 * @returns {number} month of the year that the input date falls on.
233 * @constructor
234 */
235-var MONTH = function (...values) : number {
236- ArgsChecker.checkLength(values, 1, "MONTH");
237- var date = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
238+var MONTH = function (date) : number {
239+ ArgsChecker.checkLength(arguments, 1, "MONTH");
240+ date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
241 if (date < 0) {
242 throw new NumError("Function MONTH parameter 1 value is " + date + ". It should be greater than or equal to 0.");
243 }
244@@ -204,14 +201,14 @@ var MONTH = function (...values) : number {
245
246 /**
247 * Returns the year specified by a given date.
248- * @param values[0] date - The date from which to calculate the year. Must be a cell reference to a cell containing a
249+ * @param date - The date from which to calculate the year. Must be a cell reference to a cell containing a
250 * date, a function returning a date type, or a number.
251 * @returns {number} year of the input date
252 * @constructor
253 */
254-var YEAR = function (...values) : number {
255- ArgsChecker.checkLength(values, 1, "YEAR");
256- var date = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
257+var YEAR = function (date) : number {
258+ ArgsChecker.checkLength(arguments, 1, "YEAR");
259+ date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
260 if (date < 0) {
261 throw new NumError("Function YEAR parameter 1 value is " + date + ". It should be greater than or equal to 0.");
262 }
263@@ -221,9 +218,9 @@ var YEAR = function (...values) : number {
264
265 /**
266 * Returns a number representing the day of the week of the date provided.
267- * @param values[0] date - The date for which to determine the day of the week. Must be a reference to a cell containing
268+ * @param date - The date for which to determine the day of the week. Must be a reference to a cell containing
269 * a date, a function returning a date type, or a number.
270- * @param values[1] type - [ OPTIONAL - 1 by default ] - A number indicating which numbering system to use to represent
271+ * @param offsetType - [ OPTIONAL - 1 by default ] - A number indicating which numbering system to use to represent
272 * weekdays. By default counts starting with Sunday = 1. If type is 1, days are counted from Sunday and the value of
273 * Sunday is 1, therefore the value of Saturday is 7. If type is 2, days are counted from Monday and the value of Monday
274 * is 1, therefore the value of Sunday is 7. If type is 3, days are counted from Monday and the value of Monday is 0,
275@@ -231,10 +228,10 @@ var YEAR = function (...values) : number {
276 * @returns {number} day of week
277 * @constructor
278 */
279-var WEEKDAY = function (...values) : number {
280- ArgsChecker.checkLengthWithin(values, 1, 2, "WEEKDAY");
281- var date = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
282- var offsetType = values.length === 2 ? TypeConverter.firstValueAsNumber(values[1]) : 1;
283+var WEEKDAY = function (date, offsetType?) : number {
284+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "WEEKDAY");
285+ date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
286+ offsetType = offsetType ? TypeConverter.firstValueAsNumber(offsetType) : 1;
287 if (date < 0) {
288 throw new NumError("Function WEEKDAY parameter 1 value is " + date + ". It should be greater than or equal to 0.");
289 }
290@@ -283,17 +280,17 @@ function calculateWeekNum(dm : moment.Moment, shifterArray : Array<number>) : nu
291 * year is considered to be the week containing the first Thursday of the year, which is numbered as week 1. System 2 is
292 * the approach specified in ISO 8601, also known as the European system for numbering weeks.
293 *
294- * @param values[0] date - The date for which to determine the week number. Must be a reference to a cell containing a
295+ * @param date - The date for which to determine the week number. Must be a reference to a cell containing a
296 * date, a function returning a date type, or a number.
297- * @param values[1] type - [ OPTIONAL - default is 1 ] - A number representing the day that a week starts on as well as
298+ * @param shiftType - [ OPTIONAL - default is 1 ] - A number representing the day that a week starts on as well as
299 * the system used for determining the first week of the year (1=Sunday, 2=Monday).
300 * @returns {number} representing week number of year.
301 * @constructor
302 */
303-var WEEKNUM = function (...values) : number {
304- ArgsChecker.checkLengthWithin(values, 1, 2, "WEEKNUM");
305- var date = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
306- var shiftType = values.length === 2 ? TypeConverter.firstValueAsNumber(values[1]) : 1;
307+var WEEKNUM = function (date, shiftType?) : number {
308+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "WEEKNUM");
309+ date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
310+ shiftType = shiftType ? TypeConverter.firstValueAsNumber(shiftType) : 1;
311 if (date < 0) {
312 throw new NumError("Function YEAR parameter 1 value is " + date + ". It should be greater than or equal to 0.");
313 }
314@@ -349,11 +346,11 @@ var WEEKNUM = function (...values) : number {
315
316 /**
317 * Calculates the number of days, months, or years between two dates.
318- * @param values[0] start_date - The start date to consider in the calculation. Must be a reference to a cell containing
319+ * @param startDate - The start date to consider in the calculation. Must be a reference to a cell containing
320 * a DATE, a function returning a DATE type, or a number.
321- * @param values[1] end_date - The end date to consider in the calculation. Must be a reference to a cell containing a
322+ * @param endDate - The end date to consider in the calculation. Must be a reference to a cell containing a
323 * DATE, a function returning a DATE type, or a number.
324- * @param values[2] unit - A text abbreviation for unit of time. For example,"M" for month. Accepted values are "Y": the
325+ * @param unit - A text abbreviation for unit of time. For example,"M" for month. Accepted values are "Y": the
326 * number of whole years between start_date and end_date, "M": the number of whole months between start_date and
327 * end_date, "D": the number of days between start_date and end_date, "MD": the number of days between start_date and
328 * end_date after subtracting whole months, "YM": the number of whole months between start_date and end_date after
329@@ -362,18 +359,18 @@ var WEEKNUM = function (...values) : number {
330 * @returns {number} number of days, months, or years between two dates.
331 * @constructor
332 */
333-var DATEDIF = function (...values) : number {
334- ArgsChecker.checkLength(values, 3, "DATEDIF");
335- var start = TypeConverter.firstValueAsDateNumber(values[0], true);
336- var end = TypeConverter.firstValueAsDateNumber(values[1], true);
337- var unit = TypeConverter.firstValueAsString(values[2]);
338+var DATEDIF = function (startDate, endDate, unit) : number {
339+ ArgsChecker.checkLength(arguments, 3, "DATEDIF");
340+ startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
341+ endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
342+ unit = TypeConverter.firstValueAsString(unit);
343 var unitClean = unit.toUpperCase();
344- var startMoment = TypeConverter.numberToMoment(start);
345- var endMoment = TypeConverter.numberToMoment(end);
346+ var startMoment = TypeConverter.numberToMoment(startDate);
347+ var endMoment = TypeConverter.numberToMoment(endDate);
348
349- if (start > end) {
350- throw new NumError("Function DATEDIF parameter 1 (" + start.toString() +
351- ") should be on or before Function DATEDIF parameter 2 (" + end.toString() + ").");
352+ if (startDate > endDate) {
353+ throw new NumError("Function DATEDIF parameter 1 (" + startDate.toString() +
354+ ") should be on or before Function DATEDIF parameter 2 (" + endDate.toString() + ").");
355 }
356
357 if (unitClean === "Y") {
358@@ -381,7 +378,7 @@ var DATEDIF = function (...values) : number {
359 } else if (unitClean === "M") {
360 return Math.floor(endMoment.diff(startMoment, "months"));
361 } else if (unitClean === "D") {
362- return end - start;
363+ return endDate - startDate;
364 } else if (unitClean === "MD") {
365 var s = startMoment;
366 while(s.isBefore(endMoment)) {
367@@ -422,23 +419,23 @@ var DATEDIF = function (...values) : number {
368 *
369 * * http://finmath.net/finmath-lib/
370 *
371- * @param values[0] start_date - The start date to consider in the calculation. Must be a reference to a cell
372+ * @param startDate - The start date to consider in the calculation. Must be a reference to a cell
373 * containing a date, a function returning a date type, or a number.
374- * @param values[1] end_date - The end date to consider in the calculation. Must be a reference to a cell containing
375+ * @param endDate - The end date to consider in the calculation. Must be a reference to a cell containing
376 * a date, a function returning a date type, or a number.
377- * @param values[2] day_count_convention - [ OPTIONAL - 0 by default ] - An indicator of what day count method to
378+ * @param dayCountConvention - [ OPTIONAL - 0 by default ] - An indicator of what day count method to
379 * use.
380 * @returns {number}the number of years, including fractional years, between two dates
381 * @constructor
382 */
383-var YEARFRAC = function (...values) : number {
384- ArgsChecker.checkLengthWithin(values, 2, 3, "YEARFRAC");
385- var start = TypeConverter.firstValueAsDateNumber(values[0], true);
386- var end = TypeConverter.firstValueAsDateNumber(values[1], true);
387- var basis = values.length === 2 ? 0 : TypeConverter.firstValueAsNumber(values[2]);
388-
389- var s = TypeConverter.numberToMoment(start);
390- var e = TypeConverter.numberToMoment(end);
391+var YEARFRAC = function (startDate, endDate, dayCountConvention?) : number {
392+ ArgsChecker.checkLengthWithin(arguments, 2, 3, "YEARFRAC");
393+ startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
394+ endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
395+ dayCountConvention = dayCountConvention ? TypeConverter.firstValueAsNumber(dayCountConvention) : 0;
396+
397+ var s = TypeConverter.numberToMoment(startDate);
398+ var e = TypeConverter.numberToMoment(endDate);
399 if (e.isBefore(s)) {
400 var me = moment.utc(e);
401 e = moment.utc(s);
402@@ -468,7 +465,7 @@ var YEARFRAC = function (...values) : number {
403 return false;
404 };
405
406- switch (basis) {
407+ switch (dayCountConvention) {
408 // US (NASD) 30/360
409 case 0:
410 // Note: if eday == 31, it stays 31 if sday < 30
411@@ -495,12 +492,12 @@ var YEARFRAC = function (...values) : number {
412 } else if (feb29Between(s, e) || (emonth === 1 && eday === 29)) {
413 ylength = 366;
414 }
415- return Math.abs((end - start) / ylength);
416+ return Math.abs((endDate - startDate) / ylength);
417 } else {
418 var years = (eyear - syear) + 1;
419 var days = moment.utc([eyear+1]).startOf("year").diff(moment.utc([syear]).startOf("year"), 'days');
420 var average = days / years;
421- return Math.abs((end - start) / average);
422+ return Math.abs((endDate - startDate) / average);
423 }
424 // Actual/360
425 case 2:
426@@ -515,20 +512,20 @@ var YEARFRAC = function (...values) : number {
427 // Remarkably, do NOT change February 28 or February 29 at ALL
428 return Math.abs(((eday + emonth * 30 + eyear * 360) - (sday + smonth * 30 + syear * 360)) / 360);
429 }
430- throw new NumError("Function YEARFRAC parameter 3 value is " + basis + ". Valid values are between 0 and 4 inclusive.");
431+ throw new NumError("Function YEARFRAC parameter 3 value is " + dayCountConvention + ". Valid values are between 0 and 4 inclusive.");
432 };
433
434
435 /**
436 * Returns the fraction of a 24-hour day the time represents.
437- * @param values[1] time_string - The string that holds the time representation. Eg: "10am", "10:10", "10:10am",
438- * "10:10:11", or "10:10:11am".
439+ * @param timeString - The string that holds the time representation. Eg: "10am", "10:10", "10:10am", "10:10:11",
440+ * or "10:10:11am".
441 * @returns {number} representing the fraction of a 24-hour day
442 * @constructor
443 */
444-var TIMEVALUE = function (...values) : number {
445- ArgsChecker.checkLength(values, 1, "TIMEVALUE");
446- var timeString = TypeConverter.firstValueAsString(values[0]);
447+var TIMEVALUE = function (timeString) : number {
448+ ArgsChecker.checkLength(arguments, 1, "TIMEVALUE");
449+ timeString = TypeConverter.firstValueAsString(timeString);
450 try {
451 return TypeConverter.stringToTimeNumber(timeString);
452 } catch (e) {
453@@ -540,14 +537,14 @@ const MILLISECONDS_IN_DAY = 86400000;
454
455 /**
456 * Returns the hour component of a specific time, in numeric format.
457- * @param values[0] time - The time from which to calculate the hour component. Must be a reference to a cell containing
458+ * @param time - The time from which to calculate the hour component. Must be a reference to a cell containing
459 * a date/time, a function returning a date/time type, or a number.
460 * @returns {number}
461 * @constructor
462 */
463-var HOUR = function (...values) : number {
464- ArgsChecker.checkLength(values, 1, "HOUR");
465- var time = TypeConverter.firstValueAsTimestampNumber(values[0]);
466+var HOUR = function (time) : number {
467+ ArgsChecker.checkLength(arguments, 1, "HOUR");
468+ time = TypeConverter.firstValueAsTimestampNumber(time);
469 if (time % 1 === 0) {
470 return 0;
471 }
472@@ -558,14 +555,14 @@ var HOUR = function (...values) : number {
473
474 /**
475 * Returns the minute component of a specific time, in numeric format.
476- * @param values[0] time - The time from which to calculate the minute component. Must be a reference to a cell
477+ * @param time - The time from which to calculate the minute component. Must be a reference to a cell
478 * containing a date/time, a function returning a date/time type, or a number.
479 * @returns {number} minute of the time passed in.
480 * @constructor
481 */
482-var MINUTE = function (...values) : number {
483- ArgsChecker.checkLength(values, 1, "MINUTE");
484- var time = TypeConverter.firstValueAsTimestampNumber(values[0]);
485+var MINUTE = function (time) : number {
486+ ArgsChecker.checkLength(arguments, 1, "MINUTE");
487+ time = TypeConverter.firstValueAsTimestampNumber(time);
488 if (time % 1 === 0) {
489 return 0;
490 }
491@@ -575,14 +572,14 @@ var MINUTE = function (...values) : number {
492
493 /**
494 * Returns the second component of a specific time, in numeric format.
495- * @param values[0] time - The time from which to calculate the second component. Must be a reference to a cell
496+ * @param time - The time from which to calculate the second component. Must be a reference to a cell
497 * containing a date/time, a function returning a date/time type, or a number.
498 * @returns {number} second component of a specific time.
499 * @constructor
500 */
501-var SECOND = function (...values) : number {
502- ArgsChecker.checkLength(values, 1, "SECOND");
503- var time = TypeConverter.firstValueAsTimestampNumber(values[0]);
504+var SECOND = function (time) : number {
505+ ArgsChecker.checkLength(arguments, 1, "SECOND");
506+ time = TypeConverter.firstValueAsTimestampNumber(time);
507 if (time % 1 === 0) {
508 return 0;
509 }
510@@ -593,28 +590,29 @@ var SECOND = function (...values) : number {
511
512 /**
513 * Returns the number of net working days between two provided days.
514- * @param values[0] start_date - The start date of the period from which to calculate the number of net working days.
515- * @param values[1] end_date - The end date of the period from which to calculate the number of net working days.
516- * @param values[1] holidays - [ OPTIONAL ] - A range or array constant containing the date serial numbers to consider
517+ * @param startDate - The start date of the period from which to calculate the number of net working days.
518+ * @param endDate - The end date of the period from which to calculate the number of net working days.
519+ * @param holidays - [ OPTIONAL ] - A range or array constant containing the date serial numbers to consider
520 * holidays. The values provided within an array for holidays must be date serial number values, as returned by N or
521 * date values, as returned by DATE, DATEVALUE or TO_DATE. Values specified by a range should be standard date values or
522 * date serial numbers.
523 * @returns {number} the number of net working days between two provided dates.
524 * @constructor
525 */
526-var NETWORKDAYS = function (...values) : number {
527- ArgsChecker.checkLengthWithin(values, 2, 3, "NETWORKDAYS");
528- var start = TypeConverter.firstValueAsDateNumber(values[0], true);
529- var end = TypeConverter.firstValueAsDateNumber(values[1], true);
530- var hasHolidays = values.length === 3;
531- var holidays = [];
532+var NETWORKDAYS = function (startDate, endDate, holidays?) : number {
533+ ArgsChecker.checkLengthWithin(arguments, 2, 3, "NETWORKDAYS");
534+ startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
535+ endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
536+ var hasHolidays = (holidays !== undefined);
537+ var cleanHolidays = [];
538 if (hasHolidays) {
539- if (values[2].length === 0) {
540+ holidays = (holidays instanceof Array) ? holidays : [holidays];
541+ if (holidays.length === 0) {
542 throw new RefError("Reference does not exist.");
543 }
544- for (var holidayDateValue of values[2]) {
545+ for (var holidayDateValue of holidays) {
546 if (typeof holidayDateValue === "number") {
547- holidays.push(holidayDateValue);
548+ cleanHolidays.push(holidayDateValue);
549 } else {
550 throw new ValueError("NETWORKDAYS expects number values. But '" + holidayDateValue + "' is a " +
551 (typeof holidayDateValue) + " and cannot be coerced to a number.")
552@@ -622,22 +620,22 @@ var NETWORKDAYS = function (...values) : number {
553 }
554 }
555 // Handle cases in which the start date is not before the end date.
556- var didSwap = start > end;
557+ var didSwap = startDate > endDate;
558 if (didSwap) {
559- var swap = end;
560- end = start;
561- start = swap;
562+ var swap = endDate;
563+ endDate = startDate;
564+ startDate = swap;
565 }
566
567- var countMoment = moment.utc(TypeConverter.numberToMoment(start));
568+ var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
569 var weekendDays = [6, 0]; // Default weekend_days.
570- var days = end - start + 1;
571+ var days = endDate - startDate + 1;
572 var networkDays = days;
573 var j = 0;
574 while (j < days) {
575 if (weekendDays.indexOf(countMoment.day()) >= 0) {
576 networkDays--;
577- } else if (hasHolidays && holidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) > -1) {
578+ } else if (hasHolidays && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) > -1) {
579 networkDays--;
580 }
581 countMoment.add(1, 'days');
582@@ -652,29 +650,29 @@ var NETWORKDAYS = function (...values) : number {
583
584 /**
585 * Returns the number of networking days between two provided days excluding specified weekend days and holidays.
586- * @param values[0] start_date - The start date of the period from which to calculate the number of net working days.
587- * @param values[1] end_date - The end date of the period from which to calculate the number of net working days.
588- * @param values[2] weekend - [ OPTIONAL - 1 by default ] - A number or string representing which days of the week are
589+ * @param startDate - The start date of the period from which to calculate the number of net working days.
590+ * @param endDate - The end date of the period from which to calculate the number of net working days.
591+ * @param weekend - [ OPTIONAL - 1 by default ] - A number or string representing which days of the week are
592 * considered weekends. String method: weekends can be specified using seven 0’s and 1’s, where the first number in the
593 * set represents Monday and the last number is for Sunday. A zero means that the day is a work day, a 1 means that the
594 * day is a weekend. For example, “0000011” would mean Saturday and Sunday are weekends. Number method: instead of using
595 * the string method above, a single number can be used. 1 = Saturday/Sunday are weekends, 2 = Sunday/Monday, and this
596 * pattern repeats until 7 = Friday/Saturday. 11 = Sunday is the only weekend, 12 = Monday is the only weekend, and this
597 * pattern repeats until 17 = Saturday is the only weekend.
598- * @param values[3] holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider as holidays.
599+ * @param holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider as holidays.
600 * The values provided within an array for holidays must be date serial number values, as returned by N or date values,
601 * as returned by DATE, DATEVALUE or TO_DATE. Values specified by a range should be standard date values or date serial
602 * numbers.
603 * @returns {number} of networking days between two provided days
604 * @constructor
605 */
606-var NETWORKDAYS$INTL = function (...values) : number {
607- ArgsChecker.checkLengthWithin(values, 2, 4, "NETWORKDAYS$INTL");
608- var start = TypeConverter.firstValueAsDateNumber(values[0], true);
609- var end = TypeConverter.firstValueAsDateNumber(values[1], true);
610+var NETWORKDAYS$INTL = function (startDate, endDate, weekend?, holidays?) : number {
611+ ArgsChecker.checkLengthWithin(arguments, 2, 4, "NETWORKDAYS$INTL");
612+ startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
613+ endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
614 var weekendDays = [];
615- if (values.length >= 3) {
616- var weekend = TypeConverter.firstValue(values[2]);
617+ if (weekend !== undefined) {
618+ weekend = TypeConverter.firstValue(weekend);
619 if (typeof weekend === "string") {
620 if (!/^[0-1]{6,}$/.test(weekend)) {
621 throw new NumError("Function NETWORKDAYS.INTL parameter 3 requires a number in the format '0000011'. "
622@@ -714,20 +712,20 @@ var NETWORKDAYS$INTL = function (...values) : number {
623 }
624 } else {
625 throw new ValueError("Function NETWORKDAYS.INTL parameter 4 expects number values. But '" + weekend
626- + "' cannot be coerced to a number.")
627+ + "' cannot be coerced to a number.");
628 }
629 } else {
630 weekendDays = [0, 6];
631 }
632- var hasHolidays = values.length === 4;
633- var holidays = [];
634+ var hasHolidays = holidays !== undefined;
635+ var cleanHolidays = [];
636 if (hasHolidays) {
637- if (values[3].length === 0) {
638+ if (holidays === 0) {
639 throw new RefError("Reference does not exist.");
640 }
641- for (var holidayDateValue of values[3]) {
642+ for (var holidayDateValue of holidays) {
643 if (typeof holidayDateValue === "number") {
644- holidays.push(holidayDateValue);
645+ cleanHolidays.push(holidayDateValue);
646 } else {
647 throw new ValueError("NETWORKDAYS.INTL expects number values. But '" + holidayDateValue + "' is a " +
648 (typeof holidayDateValue) + " and cannot be coerced to a number.")
649@@ -735,21 +733,21 @@ var NETWORKDAYS$INTL = function (...values) : number {
650 }
651 }
652 // Handle cases in which the start date is not before the end date.
653- var didSwap = start > end;
654+ var didSwap = startDate > endDate;
655 if (didSwap) {
656- var swap = end;
657- end = start;
658- start = swap;
659+ var swap = endDate;
660+ endDate = startDate;
661+ startDate = swap;
662 }
663
664- var countMoment = moment.utc(TypeConverter.numberToMoment(start));
665- var days = end - start + 1;
666+ var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
667+ var days = endDate - startDate + 1;
668 var networkDays = days;
669 var j = 0;
670 while (j < days) {
671 if (weekendDays.indexOf(countMoment.day()) >= 0) {
672 networkDays--;
673- } else if (hasHolidays && holidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) > -1) {
674+ } else if (hasHolidays && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) > -1) {
675 networkDays--;
676 }
677 countMoment.add(1, 'days');
678@@ -767,8 +765,8 @@ var NETWORKDAYS$INTL = function (...values) : number {
679 * @returns {number} representing the current date and time.
680 * @constructor
681 */
682-var NOW = function (...values) : number {
683- ArgsChecker.checkLength(values, 0, "NOW");
684+var NOW = function () : number {
685+ ArgsChecker.checkLength(arguments, 0, "NOW");
686 return TypeConverter.momentToNumber(moment.utc());
687 };
688
689@@ -777,8 +775,8 @@ var NOW = function (...values) : number {
690 * @returns {number} today
691 * @constructor
692 */
693-var TODAY = function (...values) : number {
694- ArgsChecker.checkLength(values, 0, "TODAY");
695+var TODAY = function () : number {
696+ ArgsChecker.checkLength(arguments, 0, "TODAY");
697 return TypeConverter.momentToNumber(moment.utc().startOf("day"));
698 };
699
700@@ -786,17 +784,17 @@ var TODAY = function (...values) : number {
701 /**
702 * Converts a provided hour, minute, and second into a time. Will silently recalculate numeric time values which fall
703 * outside of valid ranges. Eg: TIME(24, 0, 0) is the same as TIME(0, 0, 0).
704- * @param values[0] hour - The hour component of the time.
705- * @param values[1] minute - The minute component of the time.
706- * @param values[2] second - The second component of the time.
707+ * @param hours - The hour component of the time.
708+ * @param minutes - The minute component of the time.
709+ * @param seconds - The second component of the time.
710 * @returns {number} time of day
711 * @constructor
712 */
713-var TIME = function (...values) : number {
714- ArgsChecker.checkLength(values, 3, "TIME");
715- var hours = Math.floor(TypeConverter.firstValueAsNumber(values[0]));
716- var minutes = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
717- var seconds = Math.floor(TypeConverter.firstValueAsNumber(values[2]));
718+var TIME = function (hours, minutes, seconds) : number {
719+ ArgsChecker.checkLength(arguments, 3, "TIME");
720+ hours = Math.floor(TypeConverter.firstValueAsNumber(hours));
721+ minutes = Math.floor(TypeConverter.firstValueAsNumber(minutes));
722+ seconds = Math.floor(TypeConverter.firstValueAsNumber(seconds));
723 var e = TypeConverter.unitsToTimeNumber(hours, minutes, seconds);
724 if (e < 0) {
725 throw new NumError("TIME evaluates to an out of range value " + e + ". It should be greater than or equal to 0.");
726@@ -807,46 +805,46 @@ var TIME = function (...values) : number {
727
728 /**
729 * Calculates the end date after a specified number of working days.
730- * @param values[0] start_date - The date from which to begin counting.
731- * @param values[1] num_days - The number of working days to advance from start_date. If negative, counts backwards. If
732+ * @param startDate - The date from which to begin counting.
733+ * @param numberOfDays - The number of working days to advance from start_date. If negative, counts backwards. If
734 * not an integer, truncate.
735- * @param values[2] holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays. The
736+ * @param holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays. The
737 * values provided within an array for holidays must be date serial number values, as returned by N or date values, as
738 * returned by DATE, DATEVALUE or TO_DATE. Values specified by a range should be standard date values or date serial
739 * numbers.
740 * @returns {number} end date after a specified number of working days.
741 * @constructor
742 */
743-var WORKDAY = function (...values) : number {
744- ArgsChecker.checkLengthWithin(values, 2, 3, "WORKDAY");
745- var start = TypeConverter.firstValueAsDateNumber(values[0], true);
746- var days = TypeConverter.firstValueAsNumber(values[1]);
747- var hasHolidays = values.length === 3;
748- var holidays = [];
749- if (hasHolidays) {
750- if (values[2] instanceof Array) {
751- if (values[2].length === 0) {
752+var WORKDAY = function (startDate, numberOfDays, holidays?) : number {
753+ ArgsChecker.checkLengthWithin(arguments, 2, 3, "WORKDAY");
754+ startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
755+ numberOfDays = TypeConverter.firstValueAsNumber(numberOfDays);
756+ var hasHolidays = (cleanHolidays !== undefined);
757+ var cleanHolidays = [];
758+ if (hasHolidays !== undefined) {
759+ if (holidays instanceof Array) {
760+ if (holidays.length === 0) {
761 throw new RefError("Reference does not exist.");
762 }
763- for (var holidayDateValue of values[2]) {
764+ for (var holidayDateValue of holidays) {
765 if (typeof holidayDateValue === "number") {
766- holidays.push(holidayDateValue);
767+ cleanHolidays.push(holidayDateValue);
768 } else {
769 throw new ValueError("WORKDAY expects number values. But '" + holidayDateValue + "' is a " +
770 (typeof holidayDateValue) + " and cannot be coerced to a number.")
771 }
772 }
773 } else {
774- holidays.push(TypeConverter.valueToNumber(values[2]));
775+ cleanHolidays.push(TypeConverter.valueToNumber(holidays));
776 }
777 }
778
779 var weekendDays = [0, 6];
780- var countMoment = moment.utc(TypeConverter.numberToMoment(start));
781+ var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
782 var j = 0;
783- while (j < days) {
784+ while (j < numberOfDays) {
785 countMoment.add(1, 'days');
786- if (weekendDays.indexOf(countMoment.day()) < 0 && holidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
787+ if (weekendDays.indexOf(countMoment.day()) < 0 && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
788 j++;
789 }
790 }
791@@ -856,26 +854,26 @@ var WORKDAY = function (...values) : number {
792
793 /**
794 * Calculates the date after a specified number of workdays excluding specified weekend days and holidays.
795- * @param values[0] start_date - The date from which to begin counting.
796- * @param values[1] num_days - The number of working days to advance from start_date. If negative, counts backwards.
797- * @param values[2] weekend - [ OPTIONAL - 1 by default ] - A number or string representing which days of the week are
798+ * @param startDate - The date from which to begin counting.
799+ * @param numberOfDays - The number of working days to advance from start_date. If negative, counts backwards.
800+ * @param weekend - [ OPTIONAL - 1 by default ] - A number or string representing which days of the week are
801 * considered weekends. String method: weekends can be specified using seven 0’s and 1’s, where the first number in the
802 * set represents Monday and the last number is for Sunday. A zero means that the day is a work day, a 1 means that the
803 * day is a weekend. For example, “0000011” would mean Saturday and Sunday are weekends. Number method: instead of using
804 * the string method above, a single number can be used. 1 = Saturday/Sunday are weekends, 2 = Sunday/Monday, and this
805 * pattern repeats until 7 = Friday/Saturday. 11 = Sunday is the only weekend, 12 = Monday is the only weekend, and this
806 * pattern repeats until 17 = Saturday is the only weekend.
807- * @param values[3] holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays.
808+ * @param holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays.
809 * @returns {number}
810 * @constructor
811 */
812-var WORKDAY$INTL = function (...values) : number {
813- ArgsChecker.checkLengthWithin(values, 2, 3, "WORKDAY$INTL");
814- var start = TypeConverter.firstValueAsDateNumber(values[0], true);
815- var days = TypeConverter.firstValueAsNumber(values[1]);
816+var WORKDAY$INTL = function (startDate, numberOfDays, weekend?, holidays?) : number {
817+ ArgsChecker.checkLengthWithin(arguments, 2, 3, "WORKDAY$INTL");
818+ startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
819+ numberOfDays = TypeConverter.firstValueAsNumber(numberOfDays);
820 var weekendDays = [];
821- if (values.length >= 3) {
822- var weekend = TypeConverter.firstValue(values[2]);
823+ if (weekend !== undefined) {
824+ weekend = TypeConverter.firstValue(weekend);
825 if (typeof weekend === "string") {
826 if (!/^[0-1]{6,}$/.test(weekend)) {
827 throw new NumError("Function WORKDAY.INTL parameter 3 requires a number in the format '0000011'. "
828@@ -915,35 +913,35 @@ var WORKDAY$INTL = function (...values) : number {
829 }
830 } else {
831 throw new ValueError("Function WORKDAY.INTL parameter 4 expects number values. But '" + weekend
832- + "' cannot be coerced to a number.")
833+ + "' cannot be coerced to a number.");
834 }
835 } else {
836 weekendDays = [0, 6];
837 }
838- var hasHolidays = values.length === 3;
839- var holidays = [];
840+ var hasHolidays = (holidays !== undefined);
841+ var cleanHolidays = [];
842 if (hasHolidays) {
843- if (values[3] instanceof Array) {
844- if (values[3].length === 0) {
845+ if (holidays instanceof Array) {
846+ if (holidays.length === 0) {
847 throw new RefError("Reference does not exist.");
848 }
849- for (var holidayDateValue of values[3]) {
850+ for (var holidayDateValue of holidays) {
851 if (typeof holidayDateValue === "number") {
852- holidays.push(holidayDateValue);
853+ cleanHolidays.push(holidayDateValue);
854 } else {
855 throw new ValueError("WORKDAY expects number values. But '" + holidayDateValue + "' is a " +
856 (typeof holidayDateValue) + " and cannot be coerced to a number.")
857 }
858 }
859 } else {
860- holidays.push(TypeConverter.valueToNumber(values[3]));
861+ cleanHolidays.push(TypeConverter.valueToNumber(holidays));
862 }
863 }
864- var countMoment = moment.utc(TypeConverter.numberToMoment(start));
865+ var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
866 var j = 0;
867- while (j < days) {
868+ while (j < numberOfDays) {
869 countMoment.add(1, 'days');
870- if (weekendDays.indexOf(countMoment.day()) < 0 && holidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
871+ if (weekendDays.indexOf(countMoment.day()) < 0 && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
872 j++;
873 }
874 }
875diff --git a/src/Formulas/Engineering.ts b/src/Formulas/Engineering.ts
876index b7e52d8..3c3e226 100644
877--- a/src/Formulas/Engineering.ts
878+++ b/src/Formulas/Engineering.ts
879@@ -7,22 +7,22 @@ import {
880 import {
881 ValueError,
882 NumError
883-} from "../Errors"
884+} from "../Errors";
885
886 /**
887 * Converts a signed binary number to decimal format.
888- * @param values[0] signed_binary_number - The signed 10-bit binary value to be converted to decimal, provided as a
889+ * @param signedBinaryNumber - The signed 10-bit binary value to be converted to decimal, provided as a
890 * string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are represented
891 * in two's complement format.
892 * @returns {number}
893 * @constructor
894 */
895-var BIN2DEC = function (...values) : number {
896- ArgsChecker.checkLength(values, 1, "BIN2DEC");
897- if (typeof TypeConverter.firstValue(values[0]) === "boolean") {
898- throw new ValueError("Function BIN2DEC parameter 1 expects text values. But '" + values[0] + "' is a boolean and cannot be coerced to a text.");
899+var BIN2DEC = function (signedBinaryNumber) : number {
900+ ArgsChecker.checkLength(arguments, 1, "BIN2DEC");
901+ if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
902+ throw new ValueError("Function BIN2DEC parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
903 }
904- var n = TypeConverter.firstValueAsString(values[0]);
905+ var n = TypeConverter.firstValueAsString(signedBinaryNumber);
906 if (!(/^[01]{1,10}$/).test(n)) {
907 throw new NumError("Input for BIN2DEC ('" + n + "') is not a valid binary representation.");
908 }
909@@ -36,22 +36,22 @@ var BIN2DEC = function (...values) : number {
910
911 /**
912 * Converts a signed binary number to signed hexadecimal format.
913- * @param values[0] signed_binary_number - The signed 10-bit binary value to be converted to signed hexadecimal,
914+ * @param signedBinaryNumber - The signed 10-bit binary value to be converted to signed hexadecimal,
915 * provided as a string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are
916 * represented in two's complement format.
917- * @param values[1] significant_digits - [ OPTIONAL ] - The number of significant digits to ensure in the result.
918+ * @param significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result.
919 * @returns {string} string representation of a signed hexadecimal
920 * @constructor
921 */
922-var BIN2HEX = function (...values) : string {
923- ArgsChecker.checkLengthWithin(values, 1, 2, "BIN2HEX");
924- if (typeof TypeConverter.firstValue(values[0]) === "boolean") {
925- throw new ValueError("Function BIN2HEX parameter 1 expects text values. But '" + values[0] + "' is a boolean and cannot be coerced to a text.");
926+var BIN2HEX = function (signedBinaryNumber, significantDigits?) : string {
927+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "BIN2HEX");
928+ if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
929+ throw new ValueError("Function BIN2HEX parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
930 }
931- var n = TypeConverter.firstValueAsString(values[0]);
932+ var n = TypeConverter.firstValueAsString(signedBinaryNumber);
933 var p = 10;
934- if (values.length === 2) {
935- p = TypeConverter.firstValueAsNumber(values[1]);
936+ if (significantDigits !== undefined) {
937+ p = TypeConverter.firstValueAsNumber(significantDigits);
938 }
939 if (!(/^[01]{1,10}$/).test(n)) {
940 throw new NumError("Input for BIN2HEX ('"+n+"') is not a valid binary representation.");
941@@ -80,24 +80,24 @@ var BIN2HEX = function (...values) : string {
942
943 /**
944 * Converts a signed binary number to signed octal format.
945- * @param values[0] signed_binary_number - The signed 10-bit binary value to be converted to signed octal, provided as a
946+ * @param signedBinaryNumber - The signed 10-bit binary value to be converted to signed octal, provided as a
947 * string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are represented
948 * in two's complement format.
949- * @param values[1] significant_digits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
950+ * @param significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
951 * this is greater than the number of significant digits in the result, the result is left-padded with zeros until the
952 * total number of digits reaches significant_digits.
953 * @returns {string} number in octal format
954 * @constructor
955 */
956-var BIN2OCT = function (...values) : string {
957- ArgsChecker.checkLengthWithin(values, 1, 2, "BIN2OCT");
958- if (typeof TypeConverter.firstValue(values[0]) === "boolean") {
959- throw new ValueError("Function BIN2OCT parameter 1 expects text values. But '" + values[0] + "' is a boolean and cannot be coerced to a text.");
960+var BIN2OCT = function (signedBinaryNumber, significantDigits?) : string {
961+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "BIN2OCT");
962+ if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
963+ throw new ValueError("Function BIN2OCT parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
964 }
965- var n = TypeConverter.firstValueAsString(values[0]);
966+ var n = TypeConverter.firstValueAsString(signedBinaryNumber);
967 var p = 10;
968- if (values.length === 2) {
969- p = TypeConverter.firstValueAsNumber(values[1]);
970+ if (significantDigits !== undefined) {
971+ p = TypeConverter.firstValueAsNumber(significantDigits);
972 }
973 if (!(/^[01]{1,10}$/).test(n)) {
974 throw new NumError("Input for BIN2OCT ('"+n+"') is not a valid binary representation.");
975@@ -126,17 +126,17 @@ var BIN2OCT = function (...values) : string {
976
977 /**
978 * Converts a decimal number to signed octal format.
979- * @param values[0] decimal_number - The decimal value to be converted to signed octal,provided as a string. For this
980+ * @param decimalDumber - The decimal value to be converted to signed octal,provided as a string. For this
981 * function, this value has a maximum of 536870911 if positive, and a minimum of -53687092 if negative.
982- * @param values[1] significant_digits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
983+ * @param significantDigits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
984 * is greater than the number of significant digits in the result, the result is left-padded with zeros until the total
985 * number of digits reaches significant_digits.
986 * @returns {string} octal string representation of the decimal number
987 * @constructor
988 */
989-var DEC2OCT = function (...values) : string {
990- ArgsChecker.checkLengthWithin(values, 1, 2, "DEC2OCT");
991- var n = TypeConverter.firstValueAsNumber(values[0]);
992+var DEC2OCT = function (decimalDumber, significantDigits?) : string {
993+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2OCT");
994+ var n = TypeConverter.firstValueAsNumber(decimalDumber);
995 if (n < 0) {
996 n = Math.ceil(n);
997 }
998@@ -145,8 +145,8 @@ var DEC2OCT = function (...values) : string {
999 }
1000 var p = 10;
1001 var placesPresent = false;
1002- if (values.length === 2) {
1003- p = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1004+ if (significantDigits !== undefined) {
1005+ p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1006 placesPresent = true;
1007 }
1008 if (n < -53687092 || n > 536870911) {
1009@@ -174,17 +174,17 @@ var DEC2OCT = function (...values) : string {
1010
1011 /**
1012 * Converts a decimal number to signed hexadecimal format.
1013- * @param values[0] decimal_number - The decimal value to be converted to signed hexadecimal, provided as a string. This
1014+ * @param decimalDumber - The decimal value to be converted to signed hexadecimal, provided as a string. This
1015 * value has a maximum of 549755813887 if positive, and a minimum of -549755814888 if negative.
1016- * @param values[1] significant_digits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
1017+ * @param significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
1018 * this is greater than the number of significant digits in the result, the result is left-padded with zeros until the
1019 * total number of digits reaches significant_digits. This value is ignored if decimal_number is negative.
1020 * @returns {string} hexadecimal string representation of the decimal number
1021 * @constructor
1022 */
1023-var DEC2HEX = function (...values) : string {
1024- ArgsChecker.checkLengthWithin(values, 1, 2, "DEC2HEX");
1025- var n = TypeConverter.firstValueAsNumber(values[0]);
1026+var DEC2HEX = function (decimalDumber, significantDigits?) : string {
1027+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2HEX");
1028+ var n = TypeConverter.firstValueAsNumber(decimalDumber);
1029 if (n < 0) {
1030 n = Math.ceil(n);
1031 }
1032@@ -193,8 +193,8 @@ var DEC2HEX = function (...values) : string {
1033 }
1034 var p = 10;
1035 var placesPresent = false;
1036- if (values.length === 2) {
1037- p = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1038+ if (significantDigits !== undefined) {
1039+ p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1040 placesPresent = true;
1041 }
1042 if (n < -549755813888 || n > 549755813887) {
1043@@ -222,17 +222,17 @@ var DEC2HEX = function (...values) : string {
1044
1045 /**
1046 * Converts a decimal number to signed binary format.
1047- * @param values[0] decimal_number - The decimal value to be converted to signed binary, provided as a string. For this
1048+ * @param decimalDumber - The decimal value to be converted to signed binary, provided as a string. For this
1049 * function, this value has a maximum of 511 if positive, and a minimum of -512 if negative.
1050- * @param values[1] significant_digits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
1051+ * @param significantDigits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
1052 * is greater than the number of significant digits in the result, the result is left-padded with zeros until the total
1053 * number of digits reaches significant_digits.
1054 * @returns {string} signed binary string representation of the input decimal number.
1055 * @constructor
1056 */
1057-var DEC2BIN = function (...values) : string {
1058- ArgsChecker.checkLengthWithin(values, 1, 2, "DEC2BIN");
1059- var n = TypeConverter.firstValueAsNumber(values[0]);
1060+var DEC2BIN = function (decimalDumber, significantDigits?) : string {
1061+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2BIN");
1062+ var n = TypeConverter.firstValueAsNumber(decimalDumber);
1063 if (n < 0) {
1064 n = Math.ceil(n);
1065 }
1066@@ -244,8 +244,8 @@ var DEC2BIN = function (...values) : string {
1067 }
1068 var p = 10;
1069 var placesPresent = false;
1070- if (values.length === 2) {
1071- p = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1072+ if (significantDigits !== undefined) {
1073+ p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1074 placesPresent = true;
1075 }
1076
1077@@ -293,17 +293,17 @@ var DEC2BIN = function (...values) : string {
1078
1079 /**
1080 * Compare two numeric values, returning 1 if they're equal.
1081- * @param values[0] The first number to compare.
1082- * @param values[1] The second number to compare.
1083+ * @param one - The first number to compare.
1084+ * @param two - The second number to compare.
1085 * @returns {number} 1 if they're equal, 0 if they're not equal.
1086 * @constructor
1087 */
1088-var DELTA = function (...values) : number {
1089- ArgsChecker.checkLengthWithin(values, 1, 2, "DELTA");
1090- if (values.length === 1) {
1091- return TypeConverter.valueToNumber(values[0]) === 0 ? 1 : 0;
1092+var DELTA = function (one, two?) : number {
1093+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "DELTA");
1094+ if (two === undefined) {
1095+ return TypeConverter.valueToNumber(one) === 0 ? 1 : 0;
1096 }
1097- return TypeConverter.valueToNumber(values[0]) === TypeConverter.valueToNumber(values[1]) ? 1 : 0;
1098+ return TypeConverter.valueToNumber(one) === TypeConverter.valueToNumber(two) ? 1 : 0;
1099 };
1100
1101 export {
1102diff --git a/src/Formulas/Financial.ts b/src/Formulas/Financial.ts
1103index c78b892..9ec430e 100644
1104--- a/src/Formulas/Financial.ts
1105+++ b/src/Formulas/Financial.ts
1106@@ -16,21 +16,21 @@ import {
1107
1108 /**
1109 * Calculates the depreciation of an asset for a specified period using the double-declining balance method.
1110- * @param values[0] cost - The initial cost of the asset.
1111- * @param values[1] salvage - The value of the asset at the end of depreciation.
1112- * @param values[2] life - The number of periods over which the asset is depreciated.
1113- * @param values[3] period - The single period within life for which to calculate depreciation.
1114- * @param values[4] factor - [ OPTIONAL - 2 by default ] - The factor by which depreciation decreases.
1115+ * @param cost - The initial cost of the asset.
1116+ * @param salvage - The value of the asset at the end of depreciation.
1117+ * @param life - The number of periods over which the asset is depreciated.
1118+ * @param period - The single period within life for which to calculate depreciation.
1119+ * @param factor - [ OPTIONAL - 2 by default ] - The factor by which depreciation decreases.
1120 * @returns {number} depreciation of an asset for a specified period
1121 * @constructor
1122 */
1123-var DDB = function (...values) : number {
1124- ArgsChecker.checkLengthWithin(values, 4, 5, "DDB");
1125- var cost = TypeConverter.firstValueAsNumber(values[0]);
1126- var salvage = TypeConverter.firstValueAsNumber(values[1]);
1127- var life = TypeConverter.firstValueAsNumber(values[2]);
1128- var period = TypeConverter.firstValueAsNumber(values[3]);
1129- var factor = values.length === 5 ? TypeConverter.firstValueAsNumber(values[4]) : 2;
1130+var DDB = function (cost, salvage, life, period, factor?) : number {
1131+ ArgsChecker.checkLengthWithin(arguments, 4, 5, "DDB");
1132+ cost = TypeConverter.firstValueAsNumber(cost);
1133+ salvage = TypeConverter.firstValueAsNumber(salvage);
1134+ life = TypeConverter.firstValueAsNumber(life);
1135+ period = TypeConverter.firstValueAsNumber(period);
1136+ factor = factor === undefined ? 2 : TypeConverter.firstValueAsNumber(factor);
1137
1138 if (cost < 0) {
1139 throw new NumError("Function DDB parameter 1 value is "
1140@@ -68,21 +68,21 @@ var DDB = function (...values) : number {
1141
1142 /**
1143 * Calculates the depreciation of an asset for a specified period using the arithmetic declining balance method.
1144- * @param values[0] cost - The initial cost of the asset.
1145- * @param values[1] salvage - The value of the asset at the end of depreciation.
1146- * @param values[2] life - The number of periods over which the asset is depreciated.
1147- * @param values[3] period - The single period within life for which to calculate depreciation.
1148- * @param values[4] month - [ OPTIONAL - 12 by default ] - The number of months in the first year of depreciation.
1149+ * @param cost - The initial cost of the asset.
1150+ * @param salvage - The value of the asset at the end of depreciation.
1151+ * @param life - The number of periods over which the asset is depreciated.
1152+ * @param period - The single period within life for which to calculate depreciation.
1153+ * @param month - [ OPTIONAL - 12 by default ] - The number of months in the first year of depreciation.
1154 * @returns {number} depreciated value
1155 * @constructor
1156 */
1157-var DB = function (...values) : number {
1158- ArgsChecker.checkLengthWithin(values, 4, 5, "DB");
1159- var cost = TypeConverter.firstValueAsNumber(values[0]);
1160- var salvage = TypeConverter.firstValueAsNumber(values[1]);
1161- var life = TypeConverter.firstValueAsNumber(values[2]);
1162- var period = TypeConverter.firstValueAsNumber(values[3]);
1163- var month = values.length === 5 ? Math.floor(TypeConverter.firstValueAsNumber(values[4])) : 12;
1164+var DB = function (cost, salvage, life, period, month) : number {
1165+ ArgsChecker.checkLengthWithin(arguments, 4, 5, "DB");
1166+ cost = TypeConverter.firstValueAsNumber(cost);
1167+ salvage = TypeConverter.firstValueAsNumber(salvage);
1168+ life = TypeConverter.firstValueAsNumber(life);
1169+ period = TypeConverter.firstValueAsNumber(period);
1170+ month = month !== undefined ? Math.floor(TypeConverter.firstValueAsNumber(month)) : 12;
1171 if (cost < 0) {
1172 throw new NumError("Function DB parameter 1 value is "
1173 + cost + ". It should be greater than or equal to 0.");
1174@@ -134,15 +134,15 @@ var DB = function (...values) : number {
1175 /**
1176 * Formats a number into the locale-specific currency format. WARNING: Currently the equivalent of TRUNC, since this
1177 * returns numbers
1178- * @param values[0] number - The value to be formatted.
1179- * @param values[1] places - [ OPTIONAL - 2 by default ] - The number of decimal places to display.
1180+ * @param number - The value to be formatted.
1181+ * @param places - [ OPTIONAL - 2 by default ] - The number of decimal places to display.
1182 * @returns {number} dollars
1183 * @constructor
1184 */
1185-var DOLLAR = function (...values) : number {
1186- ArgsChecker.checkLengthWithin(values, 1, 2, "DOLLAR");
1187- var v = TypeConverter.firstValueAsNumber(values[0]);
1188- var places = values.length === 2 ? TypeConverter.firstValueAsNumber(values[1]) : 2;
1189+var DOLLAR = function (number, places?) : number {
1190+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "DOLLAR");
1191+ var v = TypeConverter.firstValueAsNumber(number);
1192+ places = places !== undefined ? TypeConverter.firstValueAsNumber(places) : 2;
1193 var sign = (v > 0) ? 1 : -1;
1194 var divisor = sign * (Math.floor(Math.abs(v) * Math.pow(10, places)));
1195 var pow = Math.pow(10, places);
1196@@ -155,15 +155,15 @@ var DOLLAR = function (...values) : number {
1197
1198 /**
1199 * Converts a price quotation given as a decimal fraction into a decimal value.
1200- * @param values[0] fractional_price - The price quotation given using fractional decimal conventions.
1201- * @param values[1] unit - The units of the fraction, e.g. 8 for 1/8ths or 32 for 1/32nds.
1202+ * @param fractionalPrice - The price quotation given using fractional decimal conventions.
1203+ * @param unit - The units of the fraction, e.g. 8 for 1/8ths or 32 for 1/32nds.
1204 * @returns {number} decimal value.
1205 * @constructor
1206 */
1207-var DOLLARDE = function (...values) : number {
1208- ArgsChecker.checkLength(values, 2, "DOLLARDE");
1209- var dollar = TypeConverter.firstValueAsNumber(values[0]);
1210- var fraction = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1211+var DOLLARDE = function (fractionalPrice, unit) : number {
1212+ ArgsChecker.checkLength(arguments, 2, "DOLLARDE");
1213+ var dollar = TypeConverter.firstValueAsNumber(fractionalPrice);
1214+ var fraction = Math.floor(TypeConverter.firstValueAsNumber(unit));
1215 if (fraction === 0) {
1216 throw new DivZeroError("Function DOLLARDE parameter 2 cannot be zero.");
1217 }
1218@@ -180,35 +180,35 @@ var DOLLARDE = function (...values) : number {
1219
1220 /**
1221 * Converts a price quotation given as a decimal value into a decimal fraction.
1222- * @param values[0] decimal_price - The price quotation given as a decimal value.
1223- * @param values[1] unit - The units of the desired fraction, e.g. 8 for 1/8ths or 32 for 1/32nds
1224+ * @param decimalPrice - The price quotation given as a decimal value.
1225+ * @param unit - The units of the desired fraction, e.g. 8 for 1/8ths or 32 for 1/32nds
1226 * @returns {number} price quotation as decimal fraction.
1227 * @constructor
1228 */
1229-var DOLLARFR = function (...values) : number {
1230- ArgsChecker.checkLength(values, 2, "DOLLARFR");
1231- var dollar = TypeConverter.firstValueAsNumber(values[0]);
1232- var unit = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1233+var DOLLARFR = function (decimalPrice, unit) : number {
1234+ ArgsChecker.checkLength(arguments, 2, "DOLLARFR");
1235+ decimalPrice = TypeConverter.firstValueAsNumber(decimalPrice);
1236+ unit = Math.floor(TypeConverter.firstValueAsNumber(unit));
1237 if (unit === 0) {
1238 throw new DivZeroError("Function DOLLARFR parameter 2 cannot be zero.");
1239 }
1240- var result = parseInt(dollar.toString(), 10);
1241- result += (dollar % 1) * Math.pow(10, -Math.ceil(Math.log(unit) / Math.LN10)) * unit;
1242+ var result = parseInt(decimalPrice.toString(), 10);
1243+ result += (decimalPrice % 1) * Math.pow(10, -Math.ceil(Math.log(unit) / Math.LN10)) * unit;
1244 return result;
1245 };
1246
1247
1248 /**
1249 * Calculates the annual effective interest rate given the nominal rate and number of compounding periods per year.
1250- * @param values[0] nominal_rate - The nominal interest rate per year.
1251- * @param values[1] periods_per_year - The number of compounding periods per year.
1252+ * @param nominalRate - The nominal interest rate per year.
1253+ * @param periodsPerYear - The number of compounding periods per year.
1254 * @returns {number} annual effective interest rate
1255 * @constructor
1256 */
1257-var EFFECT = function (...values) : number {
1258- ArgsChecker.checkLength(values, 2, "EFFECT");
1259- var rate = TypeConverter.firstValueAsNumber(values[0]);
1260- var periods = TypeConverter.firstValueAsNumber(values[1]);
1261+var EFFECT = function (nominalRate, periodsPerYear) : number {
1262+ ArgsChecker.checkLength(arguments, 2, "EFFECT");
1263+ var rate = TypeConverter.firstValueAsNumber(nominalRate);
1264+ var periods = TypeConverter.firstValueAsNumber(periodsPerYear);
1265 if (rate <= 0) {
1266 throw new NumError("Function EFFECT parameter 1 value is " + rate + ". It should be greater than to 0");
1267 }
1268@@ -272,34 +272,34 @@ function fv(rate, periods, payment, value, type) {
1269 /**
1270 * Calculates the cumulative principal paid over a range of payment periods for an investment based on constant-amount
1271 * periodic payments and a constant interest rate.
1272- * @param values[0] rate - The interest rate.
1273- * @param values[1] number_of_periods - The number of payments to be made.
1274- * @param values[2] present_value - The current value of the annuity.
1275- * @param values[3] first_period - The number of the payment period to begin the cumulative calculation. must be greater
1276+ * @param rate - The interest rate.
1277+ * @param numberOfPeriods - The number of payments to be made.
1278+ * @param presentValue - The current value of the annuity.
1279+ * @param firstPeriod - The number of the payment period to begin the cumulative calculation. must be greater
1280 * than or equal to 1.
1281- * @param values[4] last_period - The number of the payment period to end the cumulative calculation, must be greater
1282+ * @param lastPeriod - The number of the payment period to end the cumulative calculation, must be greater
1283 * than first_period.
1284- * @param values[5] end_or_beginning - Whether payments are due at the end (0) or beginning (1) of each period
1285+ * @param endOrBeginning - Whether payments are due at the end (0) or beginning (1) of each period
1286 * @returns {number} cumulative principal
1287 * @constructor
1288 */
1289-var CUMPRINC = function (...values) : number {
1290- ArgsChecker.checkLength(values, 6, "CUMPRINC");
1291- var rate = TypeConverter.firstValueAsNumber(values[0]);
1292- var periods = TypeConverter.firstValueAsNumber(values[1]);
1293- var value = TypeConverter.firstValueAsNumber(values[2]);
1294- var start = TypeConverter.firstValueAsNumber(values[3]);
1295+var CUMPRINC = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPeriod, endOrBeginning) : number {
1296+ ArgsChecker.checkLength(arguments, 6, "CUMPRINC");
1297+ rate = TypeConverter.firstValueAsNumber(rate);
1298+ var periods = TypeConverter.firstValueAsNumber(numberOfPeriods);
1299+ var value = TypeConverter.firstValueAsNumber(presentValue);
1300+ var start = TypeConverter.firstValueAsNumber(firstPeriod);
1301 if (start < 1) {
1302 throw new NumError("Function CUMPRINC parameter 4 value is " + start + ". It should be greater than or equal to 1.");
1303 }
1304- var end = TypeConverter.firstValueAsNumber(values[4]);
1305+ var end = TypeConverter.firstValueAsNumber(lastPeriod);
1306 if (end < 1) {
1307 throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to 1.");
1308 }
1309 if (end < start) {
1310 throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to " + start + ".");
1311 }
1312- var type = TypeConverter.firstValueAsBoolean(values[5]);
1313+ var type = TypeConverter.firstValueAsBoolean(endOrBeginning);
1314
1315 var payment = PMT(rate, periods, value, 0, type);
1316 var principal = 0;
1317@@ -324,34 +324,34 @@ var CUMPRINC = function (...values) : number {
1318 /**
1319 * Calculates the cumulative interest over a range of payment periods for an investment based on constant-amount
1320 * periodic payments and a constant interest rate.
1321- * @param values[0] rate - The interest rate.
1322- * @param values[1] number_of_periods - The number of payments to be made.
1323- * @param values[2] present_value - The current value of the annuity.
1324- * @param values[3] first_period - The number of the payment period to begin the cumulative calculation, must be greater
1325+ * @param rate - The interest rate.
1326+ * @param numberOfPeriods - The number of payments to be made.
1327+ * @param presentValue - The current value of the annuity.
1328+ * @param firstPeriod - The number of the payment period to begin the cumulative calculation, must be greater
1329 * than or equal to 1.
1330- * @param values[4] last_period - The number of the payment period to end the cumulative calculation, must be greater
1331+ * @param lastPeriod - The number of the payment period to end the cumulative calculation, must be greater
1332 * than first_period.
1333- * @param values[5] end_or_beginning - Whether payments are due at the end (0) or beginning (1) of each period.
1334+ * @param endOrBeginning - Whether payments are due at the end (0) or beginning (1) of each period.
1335 * @returns {number} cumulative interest
1336 * @constructor
1337 */
1338-var CUMIPMT = function (...values) : number {
1339- ArgsChecker.checkLength(values, 6, "CUMIPMT");
1340- var rate = TypeConverter.firstValueAsNumber(values[0]);
1341- var periods = TypeConverter.firstValueAsNumber(values[1]);
1342- var value = TypeConverter.firstValueAsNumber(values[2]);
1343- var start = TypeConverter.firstValueAsNumber(values[3]);
1344+var CUMIPMT = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPeriod, endOrBeginning) : number {
1345+ ArgsChecker.checkLength(arguments, 6, "CUMIPMT");
1346+ rate = TypeConverter.firstValueAsNumber(rate);
1347+ var periods = TypeConverter.firstValueAsNumber(numberOfPeriods);
1348+ var value = TypeConverter.firstValueAsNumber(presentValue);
1349+ var start = TypeConverter.firstValueAsNumber(firstPeriod);
1350 if (start < 1) {
1351 throw new NumError("Function CUMPRINC parameter 4 value is " + start + ". It should be greater than or equal to 1.");
1352 }
1353- var end = TypeConverter.firstValueAsNumber(values[4]);
1354+ var end = TypeConverter.firstValueAsNumber(lastPeriod);
1355 if (end < 1) {
1356 throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to 1.");
1357 }
1358 if (end < start) {
1359 throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to " + start + ".");
1360 }
1361- var type = TypeConverter.firstValueAsBoolean(values[5]);
1362+ var type = TypeConverter.firstValueAsBoolean(endOrBeginning);
1363
1364 var payment = PMT(rate, periods, value, 0, type);
1365 var interest = 0;
1366@@ -388,45 +388,47 @@ var CUMIPMT = function (...values) : number {
1367 * * https://quant.stackexchange.com/questions/7040/whats-the-algorithm-behind-excels-accrint
1368 *
1369 * * https://support.google.com/docs/answer/3093200
1370- * @param values[0] issue - The date the security was initially issued.
1371- * @param values[1] first_payment - The first date interest will be paid.
1372- * @param values[2] settlement - The settlement date of the security, the date after issuance when the security is
1373+ * @param issue - The date the security was initially issued.
1374+ * @param firstPayment - The first date interest will be paid.
1375+ * @param settlement - The settlement date of the security, the date after issuance when the security is
1376 * delivered to the buyer. Is the maturity date of the security if it is held until maturity rather than sold.
1377- * @param values[3] rate - The annualized rate of interest.
1378- * @param values[4] redemption - The redemption amount per 100 face value, or par.
1379- * @param values[5] frequency - The number of coupon payments per year. For annual payments, frequency = 1; for
1380+ * @param rate - The annualized rate of interest.
1381+ * @param redemption - The redemption amount per 100 face value, or par.
1382+ * @param frequency - The number of coupon payments per year. For annual payments, frequency = 1; for
1383 * semiannual, frequency = 2; for quarterly, frequency = 4.
1384- * @param values[6] day_count_convention - [ OPTIONAL - 0 by default ] - An indicator of what day count method to use.
1385+ * @param dayCountConvention - [ OPTIONAL - 0 by default ] - An indicator of what day count method to use.
1386 * 0 or omitted = US (NASD) 30/360, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 = European 30/360.
1387 * @returns {number}
1388 * @constructor
1389 * TODO: This function is based off of the open-source versions I was able to dig up online. We should implement a
1390 * TODO: second version that is closer to what MSExcel does and is named something like `ACCRINT.MS`.
1391 */
1392-var ACCRINT = function (...values) {
1393- ArgsChecker.checkLengthWithin(values, 6, 7, "ACCRINT");
1394- var issue = TypeConverter.firstValueAsDateNumber(values[0]);
1395+var ACCRINT = function (issue, firstPayment, settlement, rate, redemption, frequency, dayCountConvention?) {
1396+ ArgsChecker.checkLengthWithin(arguments, 6, 7, "ACCRINT");
1397+ issue = TypeConverter.firstValueAsDateNumber(issue);
1398 // "firstPayment" param is only here to check for errors for GS implementation.
1399 // In MSE, there is a 7th (zero-indexed-6th) param that indicates the calculation-method to use, which indicates
1400 // weather the total accrued interest starting at the first_intrest date, instead of the issue date.
1401- var firstPayment = TypeConverter.firstValueAsDateNumber(values[1]);
1402+ firstPayment = TypeConverter.firstValueAsDateNumber(firstPayment);
1403 if (firstPayment < 0) {
1404 throw new NumError("Function ACCRINT parameter 2 value is " + firstPayment
1405 + ". It should be greater than 0.");
1406 }
1407- var settlement = TypeConverter.firstValueAsDateNumber(values[2]);
1408+ settlement = TypeConverter.firstValueAsDateNumber(settlement);
1409 if (issue > settlement) {
1410 throw new NumError("Function ACCRINT parameter 1 (" + issue.toString()
1411 + ") should be on or before Function ACCRINT parameter 3 (" + settlement.toString() + ").")
1412 }
1413- var rate = TypeConverter.firstValueAsNumber(values[3]);
1414- var redemption = TypeConverter.firstValueAsNumber(values[4]);// "par"
1415+ rate = TypeConverter.firstValueAsNumber(rate);
1416+ // redemption, aka "par"
1417+ redemption = TypeConverter.firstValueAsNumber(redemption);
1418 // The frequency parameter also does not affect the resulting value of the formula in the GS implementation.
1419 // In MSE, frequency is used to calculate a more accurate value, by breaking apart the year, and computing interest
1420 // on an on-going basis. In this implementation, we use YEARFRAC to get a numerical value that encompasses the
1421 // functionality of "frequency".
1422- var frequency = TypeConverter.firstValueAsNumber(values[5]);
1423- var dayCountConvention = values.length === 7 ? TypeConverter.firstValueAsNumber(values[6]) : 1;// "basis"
1424+ frequency = TypeConverter.firstValueAsNumber(frequency);
1425+ // dayCountConvention, aka "basis"
1426+ dayCountConvention = dayCountConvention !== undefined ? TypeConverter.firstValueAsNumber(dayCountConvention) : 1;
1427 var factor = YEARFRAC(issue, settlement, dayCountConvention);
1428 return redemption * rate * factor;
1429 };
1430diff --git a/src/Formulas/Logical.ts b/src/Formulas/Logical.ts
1431index 479b596..38aec2b 100644
1432--- a/src/Formulas/Logical.ts
1433+++ b/src/Formulas/Logical.ts
1434@@ -39,15 +39,15 @@ var AND = function (...values) {
1435
1436 /**
1437 * Tests whether two strings are identical, returning true if they are.
1438- * @param values[0] The first string to compare
1439- * @param values[1] The second string to compare
1440+ * @param one - The first string to compare
1441+ * @param two - The second string to compare
1442 * @returns {boolean}
1443 * @constructor
1444 */
1445-var EXACT = function (...values) {
1446- ArgsChecker.checkLength(values, 2, "EXACT");
1447- var one = TypeConverter.firstValue(values[0]);
1448- var two = TypeConverter.firstValue(values[1]);
1449+var EXACT = function (one, two) {
1450+ ArgsChecker.checkLength(arguments, 2, "EXACT");
1451+ one = TypeConverter.firstValue(one);
1452+ two = TypeConverter.firstValue(two);
1453 return one.toString() === two.toString();
1454 };
1455
1456@@ -73,31 +73,30 @@ var FALSE = function () : boolean {
1457
1458 /**
1459 * Returns the opposite of a logical value - NOT(TRUE) returns FALSE; NOT(FALSE) returns TRUE.
1460- * @param values[0] An expression or reference to a cell holding an expression that represents some logical value.
1461+ * @param value - An expression or reference to a cell holding an expression that represents some logical value.
1462 * @returns {boolean} opposite of a logical value input
1463 * @constructor
1464 */
1465-var NOT = function (...values) : boolean {
1466- ArgsChecker.checkLength(values, 1, "NOT");
1467- var X = values[0];
1468- if (typeof(X) === "boolean") {
1469- return !X;
1470+var NOT = function (value) : boolean {
1471+ ArgsChecker.checkLength(arguments, 1, "NOT");
1472+ if (typeof(value) === "boolean") {
1473+ return !value;
1474 }
1475- if (typeof(X) === "string") {
1476- if (X === "") {
1477+ if (typeof(value) === "string") {
1478+ if (value === "") {
1479 return true;
1480 }
1481- throw new ValueError("Function NOT parameter 1 expects boolean values. But '" + X
1482+ throw new ValueError("Function NOT parameter 1 expects boolean values. But '" + value
1483 + "' is a text and cannot be coerced to a boolean.")
1484 }
1485- if (typeof(X) === "number") {
1486- return X === 0;
1487+ if (typeof(value) === "number") {
1488+ return value === 0;
1489 }
1490- if (X instanceof Array) {
1491- if (X.length === 0) {
1492+ if (value instanceof Array) {
1493+ if (value.length === 0) {
1494 throw new RefError("Reference does not exist.");
1495 }
1496- return NOT(X[0]);
1497+ return NOT(value[0]);
1498 }
1499 };
1500
1501diff --git a/src/Formulas/Math.ts b/src/Formulas/Math.ts
1502index 91deaaf..3528743 100644
1503--- a/src/Formulas/Math.ts
1504+++ b/src/Formulas/Math.ts
1505@@ -23,13 +23,13 @@ import {
1506
1507 /**
1508 * Returns the absolute value of a number.
1509- * @param values[0] to get the absolute value of.
1510+ * @param value to get the absolute value of.
1511 * @returns {number} absolute value
1512 * @constructor
1513 */
1514-var ABS = function (...values) {
1515- ArgsChecker.checkLength(values, 1, "ABS");
1516- var v = TypeConverter.valueToNumber(values[0]);
1517+var ABS = function (value) {
1518+ ArgsChecker.checkLength(arguments, 1, "ABS");
1519+ var v = TypeConverter.valueToNumber(value);
1520 return Math.abs(v);
1521 };
1522
1523@@ -39,7 +39,7 @@ var ABS = function (...values) {
1524 * @returns {number} inverse cosine of value
1525 * @constructor
1526 */
1527-var ACOS = function (value?) {
1528+var ACOS = function (value) {
1529 ArgsChecker.checkLength(arguments, 1, "ACOS");
1530 value = TypeConverter.valueToNumber(value);
1531 if (value === -1) {
1532@@ -56,7 +56,7 @@ var ACOS = function (value?) {
1533 * @returns {number} to find the inverse hyperbolic cosine for.
1534 * @constructor
1535 */
1536-var ACOSH = function (value?) {
1537+var ACOSH = function (value) {
1538 ArgsChecker.checkLength(arguments, 1, "ACOSH");
1539 value = TypeConverter.valueToNumber(value);
1540 if (value < 1) {
1541@@ -71,7 +71,7 @@ var ACOSH = function (value?) {
1542 * @returns {number} hyperbolic arc-cotangent
1543 * @constructor
1544 */
1545-var ACOTH = function (value?) {
1546+var ACOTH = function (value) {
1547 ArgsChecker.checkLength(arguments, 1, "ACOTH");
1548 value = TypeConverter.valueToNumber(value);
1549 if (value <= 1 && value >= -1) {
1550@@ -86,7 +86,7 @@ var ACOTH = function (value?) {
1551 * @returns {number} inverse sine of input value
1552 * @constructor
1553 */
1554-var ASIN = function (value?) {
1555+var ASIN = function (value) {
1556 ArgsChecker.checkLength(arguments, 1, "ASIN");
1557 value = TypeConverter.valueToNumber(value);
1558 if (value === -1) {
1559@@ -103,7 +103,7 @@ var ASIN = function (value?) {
1560 * @returns {number} inverse hyperbolic sine of input
1561 * @constructor
1562 */
1563-var ASINH = function (value?) {
1564+var ASINH = function (value) {
1565 ArgsChecker.checkLength(arguments, 1, "ASINH");
1566 value = TypeConverter.valueToNumber(value);
1567 return Math.log(value + Math.sqrt(value * value + 1));
1568@@ -116,7 +116,7 @@ var ASINH = function (value?) {
1569 * @returns {number} inverse tangent of input value
1570 * @constructor
1571 */
1572-var ATAN = function (value?) {
1573+var ATAN = function (value) {
1574 ArgsChecker.checkLength(arguments, 1, "ATAN");
1575 value = TypeConverter.valueToNumber(value);
1576 if (value === -1) {
1577@@ -152,7 +152,7 @@ var ATAN2 = function (x, y) {
1578 * @returns {number} inverse hyperbolic tangent of input
1579 * @constructor
1580 */
1581-var ATANH = function (value?) : number {
1582+var ATANH = function (value) : number {
1583 ArgsChecker.checkLength(arguments, 1, "ATANH");
1584 value = TypeConverter.valueToNumber(value);
1585 if (value >= 1 || value <= -1) {
1586@@ -166,33 +166,27 @@ var ATANH = function (value?) : number {
1587
1588 /**
1589 * Rounds a number up to the nearest even integer.
1590- * @param values[0] The value to round to the next greatest even number.
1591+ * @param value The value to round to the next greatest even number.
1592 * @returns {number} next greatest even number
1593 * @constructor
1594 */
1595-var EVEN = function (...values) : number {
1596- ArgsChecker.checkLength(values, 1, "EVEN");
1597- if (values[0] instanceof Array) {
1598- if (values[0].length === 0) {
1599- throw new RefError("Reference does not exist.");
1600- }
1601- return EVEN(values[0][0]);
1602- }
1603- var X = TypeConverter.valueToNumber(values[0]);
1604+var EVEN = function (value) : number {
1605+ ArgsChecker.checkLength(arguments, 1, "EVEN");
1606+ var X = TypeConverter.firstValueAsNumber(value);
1607 return X % 2 === 1 ? X + 1 : X;
1608 };
1609
1610 /**
1611 * Returns the result of the modulo operator, the remainder after a division operation.
1612- * @param values[0] The number to be divided to find the remainder.
1613- * @param values[1] The number to divide by.
1614+ * @param dividend The number to be divided to find the remainder.
1615+ * @param divisor The number to divide by.
1616 * @returns {number}
1617 * @constructor
1618 */
1619-var MOD = function (...values) : number {
1620- ArgsChecker.checkLength(values, 2, "MOD");
1621- var oneN = TypeConverter.valueToNumber(values[0]);
1622- var twoN = TypeConverter.valueToNumber(values[1]);
1623+var MOD = function (dividend, divisor) : number {
1624+ ArgsChecker.checkLength(arguments, 2, "MOD");
1625+ var oneN = TypeConverter.valueToNumber(dividend);
1626+ var twoN = TypeConverter.valueToNumber(divisor);
1627 if (twoN === 0) {
1628 throw new DivZeroError("Function MOD parameter 2 cannot be zero.");
1629 }
1630@@ -202,33 +196,27 @@ var MOD = function (...values) : number {
1631
1632 /**
1633 * Rounds a number up to the nearest odd integer.
1634- * @param values[0] The value to round to the next greatest odd number.
1635+ * @param value The value to round to the next greatest odd number.
1636 * @returns {number} value to round up to next greatest odd number.
1637 * @constructor
1638 */
1639-var ODD = function (...values) : number {
1640- ArgsChecker.checkLength(values, 1, "ODD");
1641- if (values[0] instanceof Array) {
1642- if (values[0].length === 0) {
1643- throw new RefError("Reference does not exist.");
1644- }
1645- return ODD(values[0][0]);
1646- }
1647- var X = TypeConverter.valueToNumber(values[0]);
1648+var ODD = function (value) : number {
1649+ ArgsChecker.checkLength(arguments, 1, "ODD");
1650+ var X = TypeConverter.firstValueAsNumber(value);
1651 return X % 2 === 1 ? X : X + 1;
1652 };
1653
1654 /**
1655 * Returns a number raised to a power.
1656- * @param values[0] The number to raise to the exponent power.
1657- * @param values[1] The exponent to raise base to.
1658+ * @param base - The number to raise to the exponent power.
1659+ * @param exponent - The exponent to raise base to.
1660 * @returns {number} resulting number
1661 * @constructor
1662 */
1663-var POWER = function (...values) : number {
1664- ArgsChecker.checkLength(values, 2, "POWER");
1665- var n = TypeConverter.firstValueAsNumber(values[0]);
1666- var p = TypeConverter.firstValueAsNumber(values[1]);
1667+var POWER = function (base, exponent) : number {
1668+ ArgsChecker.checkLength(arguments, 2, "POWER");
1669+ var n = TypeConverter.firstValueAsNumber(base);
1670+ var p = TypeConverter.firstValueAsNumber(exponent);
1671 return Math.pow(n, p);
1672 };
1673
1674@@ -256,28 +244,28 @@ var SUM = function (...values) : number {
1675
1676 /**
1677 * Returns the positive square root of a positive number.
1678- * @param values[0] The number for which to calculate the positive square root.
1679+ * @param value - The number for which to calculate the positive square root.
1680 * @returns {number} square root
1681 * @constructor
1682 */
1683-var SQRT = function (...values) : number {
1684- ArgsChecker.checkLength(values, 1, "SQRT");
1685- var x = TypeConverter.firstValueAsNumber(values[0]);
1686+var SQRT = function (value) : number {
1687+ ArgsChecker.checkLength(arguments, 1, "SQRT");
1688+ var x = TypeConverter.firstValueAsNumber(value);
1689 if (x < 0) {
1690- throw new ValueError("Function SQRT parameter 1 expects number values. But '" + values[0] + "' is a text and cannot be coerced to a number.");
1691+ throw new ValueError("Function SQRT parameter 1 value is " + x + ". It should be greater than or equal to 0.");
1692 }
1693 return Math.sqrt(x);
1694 };
1695
1696 /**
1697 * Returns the positive square root of the product of Pi and the given positive number.
1698- * @param values[0] value - The number which will be multiplied by Pi and have the product's square root returned
1699+ * @param value - The number which will be multiplied by Pi and have the product's square root returned
1700 * @returns {number} the positive square root of the product of Pi and the given positive number.
1701 * @constructor
1702 */
1703-var SQRTPI = function (...values) : number{
1704- ArgsChecker.checkLength(values, 1, "SQRTPI");
1705- var n = TypeConverter.firstValueAsNumber(values[0]);
1706+var SQRTPI = function (value) : number{
1707+ ArgsChecker.checkLength(arguments, 1, "SQRTPI");
1708+ var n = TypeConverter.firstValueAsNumber(value);
1709 if (n < 0) {
1710 throw new NumError("Function SQRTPI parameter 1 value is " + n + ". It should be greater than or equal to 0.");
1711 }
1712@@ -286,37 +274,37 @@ var SQRTPI = function (...values) : number{
1713
1714 /**
1715 * Returns the cosine of an angle provided in radians.
1716- * @param values[0] The angle to find the cosine of, in radians.
1717+ * @param value - The angle to find the cosine of, in radians.
1718 * @returns {number} cosine of angle
1719 * @constructor
1720 */
1721-var COS = function (...values) : number {
1722- ArgsChecker.checkLength(values, 1, "COS");
1723- var r = TypeConverter.firstValueAsNumber(values[0]);
1724+var COS = function (value) : number {
1725+ ArgsChecker.checkLength(arguments, 1, "COS");
1726+ var r = TypeConverter.firstValueAsNumber(value);
1727 return Math.cos(r);
1728 };
1729
1730 /**
1731 * Returns the hyperbolic cosine of any real number.
1732- * @param values[0] Any real value to calculate the hyperbolic cosine of.
1733+ * @param value - Any real value to calculate the hyperbolic cosine of.
1734 * @returns {number} the hyperbolic cosine of the input
1735 * @constructor
1736 */
1737-var COSH = function (...values) : number {
1738- ArgsChecker.checkLength(values, 1, "COSH");
1739- var r = TypeConverter.firstValueAsNumber(values[0]);
1740+var COSH = function (value) : number {
1741+ ArgsChecker.checkLength(arguments, 1, "COSH");
1742+ var r = TypeConverter.firstValueAsNumber(value);
1743 return Math["cosh"](r);
1744 };
1745
1746 /**
1747 * Returns the cotangent of any real number. Defined as cot(x) = 1 / tan(x).
1748- * @param values[0] number to calculate the cotangent for
1749+ * @param value - number to calculate the cotangent for
1750 * @returns {number} cotangent
1751 * @constructor
1752 */
1753-var COT = function (...values) : number {
1754- ArgsChecker.checkLength(values, 1, "COT");
1755- var x = TypeConverter.firstValueAsNumber(values[0]);
1756+var COT = function (value) : number {
1757+ ArgsChecker.checkLength(arguments, 1, "COT");
1758+ var x = TypeConverter.firstValueAsNumber(value);
1759 if (x === 0) {
1760 throw new DivZeroError("Evaluation of function COT caused a divide by zero error.");
1761 }
1762@@ -325,13 +313,13 @@ var COT = function (...values) : number {
1763
1764 /**
1765 * Return the hyperbolic cotangent of a value, defined as coth(x) = 1 / tanh(x).
1766- * @param values[0] value to calculate the hyperbolic cotangent value of
1767+ * @param value - value to calculate the hyperbolic cotangent value of
1768 * @returns {number} hyperbolic cotangent
1769 * @constructor
1770 */
1771-var COTH = function (...values) : number {
1772- ArgsChecker.checkLength(values, 1, "COTH");
1773- var x = TypeConverter.firstValueAsNumber(values[0]);
1774+var COTH = function (value) : number {
1775+ ArgsChecker.checkLength(arguments, 1, "COTH");
1776+ var x = TypeConverter.firstValueAsNumber(value);
1777 if (x === 0) {
1778 throw new DivZeroError("Evaluation of function COTH caused a divide by zero error.");
1779 }
1780@@ -340,69 +328,69 @@ var COTH = function (...values) : number {
1781
1782 /**
1783 * Rounds a number down to the nearest integer that is less than or equal to it.
1784- * @param values[0] The value to round down to the nearest integer.
1785+ * @param value - The value to round down to the nearest integer.
1786 * @returns {number} Rounded number
1787 * @constructor
1788 */
1789-var INT = function (...values) : number {
1790- ArgsChecker.checkLength(values, 1, "INT");
1791- var x = TypeConverter.firstValueAsNumber(values[0]);
1792+var INT = function (value) : number {
1793+ ArgsChecker.checkLength(arguments, 1, "INT");
1794+ var x = TypeConverter.firstValueAsNumber(value);
1795 return Math.floor(x);
1796 };
1797
1798
1799 /**
1800 * Checks whether the provided value is even.
1801- * @param values[0] The value to be verified as even.
1802+ * @param value - The value to be verified as even.
1803 * @returns {boolean} whether this value is even or not
1804 * @constructor
1805 */
1806-var ISEVEN = function (...values) : boolean {
1807- ArgsChecker.checkLength(values, 1, "ISEVEN");
1808- if (values[0] === "") {
1809- throw new ValueError("Function ISEVEN parameter 1 expects boolean values. But '" + values[0] + "' is a text and cannot be coerced to a boolean.");
1810+var ISEVEN = function (value) : boolean {
1811+ ArgsChecker.checkLength(arguments, 1, "ISEVEN");
1812+ if (value === "") {
1813+ throw new ValueError("Function ISEVEN parameter 1 expects boolean values. But '" + value + "' is a text and cannot be coerced to a boolean.");
1814 }
1815- var x = TypeConverter.firstValueAsNumber(values[0]);
1816+ var x = TypeConverter.firstValueAsNumber(value);
1817 return Math.floor(x) % 2 === 0;
1818 };
1819
1820
1821 /**
1822 * Checks whether the provided value is odd.
1823- * @param values[0] The value to be verified as odd.
1824+ * @param value - The value to be verified as odd.
1825 * @returns {boolean} whether this value is odd or not
1826 * @constructor
1827 */
1828-var ISODD = function (...values) : boolean {
1829- ArgsChecker.checkLength(values, 1, "ISODD");
1830- if (values[0] === "") {
1831- throw new ValueError("Function ISODD parameter 1 expects boolean values. But '" + values[0] + "' is a text and cannot be coerced to a boolean.");
1832+var ISODD = function (value) : boolean {
1833+ ArgsChecker.checkLength(arguments, 1, "ISODD");
1834+ if (value === "") {
1835+ throw new ValueError("Function ISODD parameter 1 expects boolean values. But '" + value + "' is a text and cannot be coerced to a boolean.");
1836 }
1837- var x = TypeConverter.firstValueAsNumber(values[0]);
1838+ var x = TypeConverter.firstValueAsNumber(value);
1839 return Math.floor(x) % 2 === 1;
1840 };
1841
1842 /**
1843 * Returns the sine of an angle provided in radians.
1844- * @param values[0] The angle to find the sine of, in radians.
1845+ * @param value - The angle to find the sine of, in radians.
1846 * @returns {number} Sine of angle.
1847 * @constructor
1848 */
1849-var SIN = function (...values) {
1850- ArgsChecker.checkLength(values, 1, "SIN");
1851- var rad = TypeConverter.firstValueAsNumber(values[0]);
1852+var SIN = function (value) {
1853+ ArgsChecker.checkLength(arguments, 1, "SIN");
1854+ var rad = TypeConverter.firstValueAsNumber(value);
1855 return rad === Math.PI ? 0 : Math.sin(rad);
1856 };
1857
1858 /**
1859 * Returns the hyperbolic sine of any real number.
1860- * @param values[0] real number to find the hyperbolic sine of
1861+ * @param value - real number to find the hyperbolic sine of
1862 * @returns {number} hyperbolic sine
1863 * @constructor
1864 */
1865-var SINH = function (...values) : number {
1866- ArgsChecker.checkLength(values, 1, "SINH");
1867- var rad = TypeConverter.firstValueAsNumber(values[0]);
1868+var SINH = function (value) : number {
1869+ ArgsChecker.checkLength(arguments, 1, "SINH");
1870+ var rad = TypeConverter.firstValueAsNumber(value);
1871 return Math["sinh"](rad);
1872 };
1873
1874@@ -418,13 +406,13 @@ var PI = function () {
1875
1876 /**
1877 * Returns the the logarithm of a number, base 10.
1878- * @param values[0] The value for which to calculate the logarithm, base 10.
1879+ * @param value - The value for which to calculate the logarithm, base 10.
1880 * @returns {number} logarithm of the number, in base 10.
1881 * @constructor
1882 */
1883-var LOG10 = function (...values) : number {
1884- ArgsChecker.checkLength(values, 1, "LOG10");
1885- var n = TypeConverter.firstValueAsNumber(values[0]);
1886+var LOG10 = function (value) : number {
1887+ ArgsChecker.checkLength(arguments, 1, "LOG10");
1888+ var n = TypeConverter.firstValueAsNumber(value);
1889 if (n < 1) {
1890 throw new NumError("Function LOG10 parameter 1 value is " + n + ". It should be greater than 0.");
1891 }
1892@@ -435,20 +423,17 @@ var LOG10 = function (...values) : number {
1893
1894 /**
1895 * Returns the the logarithm of a number given a base.
1896- * @param values[0] The value for which to calculate the logarithm given base.
1897- * @param values[1] The base to use for calculation of the logarithm. Defaults to 10.
1898+ * @param value - The value for which to calculate the logarithm given base.
1899+ * @param base - The base to use for calculation of the logarithm. Defaults to 10.
1900 * @returns {number}
1901 * @constructor
1902 */
1903-var LOG = function (...values) : number {
1904- ArgsChecker.checkAtLeastLength(values, 1, "LOG");
1905- var n = TypeConverter.firstValueAsNumber(values[0]);
1906- var b = 10;
1907- if (values.length > 1) {
1908- b = TypeConverter.firstValueAsNumber(values[1]);
1909- if (b < 1) {
1910- throw new NumError("Function LOG parameter 2 value is " + b + ". It should be greater than 0.");
1911- }
1912+var LOG = function (value, base) : number {
1913+ ArgsChecker.checkAtLeastLength(arguments, 2, "LOG");
1914+ var n = TypeConverter.firstValueAsNumber(value);
1915+ var b = TypeConverter.firstValueAsNumber(base);
1916+ if (b < 1) {
1917+ throw new NumError("Function LOG parameter 2 value is " + b + ". It should be greater than 0.");
1918 }
1919 if (b < 2) {
1920 throw new DivZeroError("Evaluation of function LOG caused a divide by zero error.");
1921@@ -463,13 +448,13 @@ var LOG = function (...values) : number {
1922
1923 /**
1924 * Returns the logarithm of a number, base e (Euler's number).
1925- * @param values[0] The value for which to calculate the logarithm, base e.
1926+ * @param value - The value for which to calculate the logarithm, base e.
1927 * @returns {number} logarithm calculated
1928 * @constructor
1929 */
1930-var LN = function (...values) : number {
1931- ArgsChecker.checkLength(values, 1, "LN");
1932- var n = TypeConverter.firstValueAsNumber(values[0]);
1933+var LN = function (value) : number {
1934+ ArgsChecker.checkLength(arguments, 1, "LN");
1935+ var n = TypeConverter.firstValueAsNumber(value);
1936 if (n < 1) {
1937 throw new NumError("Function LN parameter 1 value is " + n + ". It should be greater than 0.");
1938 }
1939@@ -478,42 +463,42 @@ var LN = function (...values) : number {
1940
1941 /**
1942 * Returns the tangent of an angle provided in radians.
1943- * @param values The angle to find the tangent of, in radians.
1944+ * @param value - The angle to find the tangent of, in radians.
1945 * @returns {number} tangent in radians
1946 * @constructor
1947 */
1948-var TAN = function (...values) : number {
1949- ArgsChecker.checkLength(values, 1, "TAN");
1950- var rad = TypeConverter.firstValueAsNumber(values[0]);
1951+var TAN = function (value) : number {
1952+ ArgsChecker.checkLength(arguments, 1, "TAN");
1953+ var rad = TypeConverter.firstValueAsNumber(value);
1954 return rad === Math.PI ? 0 : Math.tan(rad);
1955 };
1956
1957 /**
1958 * Returns the hyperbolic tangent of any real number.
1959- * @param values[0] Any real value to calculate the hyperbolic tangent of.
1960+ * @param value - Any real value to calculate the hyperbolic tangent of.
1961 * @returns {number} hyperbolic tangent
1962 * @constructor
1963 */
1964-var TANH = function (...values) : number {
1965- ArgsChecker.checkLength(values, 1, "TANH");
1966- var rad = TypeConverter.firstValueAsNumber(values[0]);
1967+var TANH = function (value) : number {
1968+ ArgsChecker.checkLength(arguments, 1, "TANH");
1969+ var rad = TypeConverter.firstValueAsNumber(value);
1970 return Math["tanh"](rad);
1971 };
1972
1973 /**
1974 * Rounds a number up to the nearest integer multiple of specified significance.
1975- * @param values[0] The value to round up to the nearest integer multiple of factor.
1976- * @param values[1] The number to whose multiples value will be rounded.
1977+ * @param value The value to round up to the nearest integer multiple of factor.
1978+ * @param factor - [ OPTIONAL ] The number to whose multiples value will be rounded.
1979 * @returns {number}
1980 * @constructor
1981 */
1982-var CEILING = function (...values) : number {
1983- ArgsChecker.checkLengthWithin(values, 1, 2, "CEILING");
1984- var num = TypeConverter.firstValueAsNumber(values[0]);
1985- if (values.length === 1) {
1986+var CEILING = function (value, factor?) : number {
1987+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "CEILING");
1988+ var num = TypeConverter.firstValueAsNumber(value);
1989+ if (factor === undefined) {
1990 return Math.ceil(num);
1991 }
1992- var significance = TypeConverter.firstValueAsNumber(values[1]);
1993+ var significance = TypeConverter.firstValueAsNumber(factor);
1994 if (significance === 0) {
1995 throw new DivZeroError("Function CEILING parameter 2 cannot be zero.");
1996 }
1997@@ -527,18 +512,18 @@ var CEILING = function (...values) : number {
1998
1999 /**
2000 * Rounds a number down to the nearest integer multiple of specified significance.
2001- * @param values[0] The value to round down to the nearest integer multiple of factor.
2002- * @param values[1] The number to whose multiples value will be rounded.
2003+ * @param value - The value to round down to the nearest integer multiple of factor.
2004+ * @param factor - The number to whose multiples value will be rounded.
2005 * @returns {number}
2006 * @constructor
2007 */
2008-var FLOOR = function (...values) : number {
2009- ArgsChecker.checkLengthWithin(values, 1, 2, "FLOOR");
2010- var num = TypeConverter.firstValueAsNumber(values[0]);
2011- if (values.length === 1) {
2012+var FLOOR = function (value, factor?) : number {
2013+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "FLOOR");
2014+ var num = TypeConverter.firstValueAsNumber(value);
2015+ if (factor === undefined) {
2016 return Math.floor(num);
2017 }
2018- var significance = TypeConverter.firstValueAsNumber(values[1]);
2019+ var significance = TypeConverter.firstValueAsNumber(factor);
2020 if (significance === 0) {
2021 throw new DivZeroError("Function FLOOR parameter 2 cannot be zero.");
2022 }
2023@@ -552,43 +537,41 @@ var FLOOR = function (...values) : number {
2024
2025 /**
2026 * Returns one value if a logical expression is TRUE and another if it is FALSE.
2027- * @param values[0] An expression or reference to a cell containing an expression that represents some logical value, i.e. TRUE or FALSE.
2028- * @param values[1] The value the function returns if logical_expression is TRUE
2029- * @param values[2] The value the function returns if logical_expression is FALSE.
2030+ * @param logicalExpression - An expression or reference to a cell containing an expression that represents some logical value, i.e. TRUE or FALSE.
2031+ * @param valueIfTrue - The value the function returns if logical_expression is TRUE
2032+ * @param valueIfFalse - The value the function returns if logical_expression is FALSE.
2033 * @returns one value if a logical expression is TRUE and another if it is FALSE.
2034 * @constructor
2035 */
2036-var IF = function (...values) : any {
2037- ArgsChecker.checkLength(values, 3, "IF");
2038- if (values[0] instanceof Array) {
2039- if (values[0].length === 0) {
2040+var IF = function (logicalExpression, valueIfTrue, valueIfFalse) : any {
2041+ ArgsChecker.checkLength(arguments, 3, "IF");
2042+ if (logicalExpression instanceof Array) {
2043+ if (logicalExpression.length === 0) {
2044 throw new RefError("Reference does not exist.");
2045 }
2046- return IF(values[0][0], values[1], values[2]);
2047- } else if (values[0] === "") {
2048- return values[2];
2049+ return IF(logicalExpression[0], valueIfTrue, valueIfFalse);
2050+ } else if (logicalExpression === "") {
2051+ return valueIfFalse;
2052 }
2053- return (TypeConverter.valueToBoolean(values[0])) ? values[1] : values[2];
2054+ return (TypeConverter.valueToBoolean(logicalExpression)) ? valueIfTrue : valueIfFalse;
2055 };
2056
2057
2058 /**
2059 * Returns a conditional count across a range.
2060- * @param values[0] range - The range that is tested against criterion., value[1];
2061- * @param values[1] criterion - The pattern or test to apply to range. If the range to check against contains text,
2062+ * @param range - The range that is tested against criterion., value[1];
2063+ * @param criteria - The pattern or test to apply to range. If the range to check against contains text,
2064 * this must be a string. It can be a comparison based string (e.g. "=1", "<1", ">=1") or it can be a wild-card string,
2065 * in which * matches any number of characters, and ? matches the next character. Both ? and * can be escaped by placing
2066 * a ~ in front of them. If it is neither, it will compared with values in the range using equality comparison.
2067 * @returns {number}
2068 * @constructor
2069 */
2070-var COUNTIF = function (...values) {
2071- ArgsChecker.checkLength(values, 2, "COUNTIF");
2072- var range = values[0];
2073+var COUNTIF = function (range, criteria) {
2074+ ArgsChecker.checkLength(arguments, 2, "COUNTIF");
2075 if (!(range instanceof Array)) {
2076 range = [range];
2077 }
2078- var criteria = values[1];
2079 var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criteria);
2080
2081 var count = 0;
2082@@ -656,74 +639,65 @@ var COUNTIFS = function (...values) {
2083
2084 /**
2085 * Rounds a number to a certain number of decimal places according to standard rules.
2086- * @param values[0] The value to round to places number of places.
2087- * @param values[1] The number of decimal places to which to round.
2088+ * @param value - The value to round to places number of places.
2089+ * @param places - The number of decimal places to which to round.
2090 * @returns {number}
2091 * @constructor
2092 */
2093-var ROUND = function (...values) {
2094- ArgsChecker.checkLengthWithin(values, 1, 2, "ROUND");
2095- var n = TypeConverter.firstValueAsNumber(values[0]);
2096- if (values.length === 1) {
2097- return Math.round(n);
2098- }
2099- var d = TypeConverter.firstValueAsNumber(values[1]);
2100+var ROUND = function (value, places) {
2101+ ArgsChecker.checkLength(arguments, 2, "ROUND");
2102+ var n = TypeConverter.firstValueAsNumber(value);
2103+ var d = TypeConverter.firstValueAsNumber(places);
2104 return Math.round(n * Math.pow(10, d)) / Math.pow(10, d);
2105 };
2106
2107 /**
2108 * Rounds a number to a certain number of decimal places, always rounding down to the next valid increment.
2109- * @param values[0] The value to round to places number of places, always rounding down.
2110- * @param values[1] (optional) The number of decimal places to which to round.
2111+ * @param value - The value to round to places number of places, always rounding down.
2112+ * @param places - (optional) The number of decimal places to which to round.
2113 * @returns {number}
2114 * @constructor
2115 */
2116-var ROUNDDOWN = function (...values) {
2117- ArgsChecker.checkLengthWithin(values, 1, 2, "ROUNDDOWN");
2118- var n = TypeConverter.firstValueAsNumber(values[0]);
2119- if (values.length === 1) {
2120+var ROUNDDOWN = function (value, places?) {
2121+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "ROUNDDOWN");
2122+ var n = TypeConverter.firstValueAsNumber(value);
2123+ if (places === undefined) {
2124 return Math.floor(n);
2125 }
2126- var d = TypeConverter.firstValueAsNumber(values[1]);
2127+ var d = TypeConverter.firstValueAsNumber(places);
2128 return Math.floor(n * Math.pow(10, d)) / Math.pow(10, d);
2129 };
2130
2131 /**
2132 * Rounds a number to a certain number of decimal places, always rounding up to the next valid increment.
2133- * @param values[0] The value to round to places number of places, always rounding up.
2134- * @param values[1] (optional) The number of decimal places to which to round.
2135+ * @param value - The value to round to places number of places, always rounding up.
2136+ * @param places - (optional) The number of decimal places to which to round.
2137 * @returns {number}
2138 * @constructor
2139 */
2140-var ROUNDUP = function (...values) {
2141- ArgsChecker.checkLengthWithin(values, 1, 2, "ROUNDUP");
2142- var n = TypeConverter.firstValueAsNumber(values[0]);
2143- if (values.length === 1) {
2144+var ROUNDUP = function (value, places?) {
2145+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "ROUNDUP");
2146+ var n = TypeConverter.firstValueAsNumber(value);
2147+ if (places === undefined) {
2148 return Math.ceil(n);
2149 }
2150- var d = TypeConverter.firstValueAsNumber(values[1]);
2151+ var d = TypeConverter.firstValueAsNumber(places);
2152 return Math.ceil(n * Math.pow(10, d)) / Math.pow(10, d);
2153 };
2154
2155 /**
2156 * Returns a conditional sum across a range.
2157- * @param values[0] The range which is tested against criterion.
2158- * @param values[1] The pattern or test to apply to range. If the range to check against contains text, this must be a
2159+ * @param range - The range which is tested against criterion.
2160+ * @param criteria - The pattern or test to apply to range. If the range to check against contains text, this must be a
2161 * string. It can be a comparison based string (e.g. "=1", "<1", ">=1") or it can be a wild-card string, in which *
2162 * matches any number of characters, and ? matches the next character. Both ? and * can be escaped by placing a ~ in
2163 * front of them.
2164- * @param values[2] (optional) The range to be summed, if different from range.
2165+ * @param sumRange - (optional) The range to be summed, if different from range.
2166 * @returns {number}
2167 * @constructor
2168 */
2169-var SUMIF = function (...values) {
2170- ArgsChecker.checkLengthWithin(values, 2, 3, "SUMIF");
2171- var range = values[0];
2172- var criteria = values[1];
2173- var sumRange = null;
2174- if (values.length === 3) {
2175- sumRange = values[2];
2176- }
2177+var SUMIF = function (range, criteria, sumRange?) {
2178+ ArgsChecker.checkLengthWithin(arguments, 2, 3, "SUMIF");
2179
2180 var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criteria);
2181
2182@@ -736,9 +710,9 @@ var SUMIF = function (...values) {
2183 if (sumRange && i > sumRange.length-1) {
2184 continue;
2185 }
2186- if (values.length === 2 && TypeConverter.canCoerceToNumber(x) && criteriaEvaluation(x)) {
2187+ if (arguments.length === 2 && TypeConverter.canCoerceToNumber(x) && criteriaEvaluation(x)) {
2188 sum = sum + TypeConverter.valueToNumber(x);
2189- } else if (values.length === 3 && TypeConverter.canCoerceToNumber(sumRange[i]) && criteriaEvaluation(x)) {
2190+ } else if (arguments.length === 3 && TypeConverter.canCoerceToNumber(sumRange[i]) && criteriaEvaluation(x)) {
2191 sum = sum + TypeConverter.valueToNumber(sumRange[i]);
2192 }
2193 }
2194@@ -772,8 +746,8 @@ var SUMSQ = function (...values) {
2195
2196 /**
2197 * Truncates a number to a certain number of significant digits by omitting less significant digits.
2198- * @param values[0] The value to be truncated.
2199- * @param values[1] [ OPTIONAL - 0 by default ] - The number of significant digits to the right of the decimal point to
2200+ * @param value - The value to be truncated.
2201+ * @param places - [ OPTIONAL - 0 by default ] - The number of significant digits to the right of the decimal point to
2202 * retain. If places is greater than the number of significant digits in value, value is returned without modification.
2203 * places may be negative, in which case the specified number of digits to the left of the decimal place are changed to
2204 * zero. All digits to the right of the decimal place are discarded. If all digits of value are changed to zero, TRUNC
2205@@ -781,12 +755,12 @@ var SUMSQ = function (...values) {
2206 * @returns {number} after truncation
2207 * @constructor
2208 */
2209-var TRUNC = function (...values) : number {
2210- ArgsChecker.checkLengthWithin(values, 1, 2, "TRUNC");
2211- var n = TypeConverter.firstValueAsNumber(values[0]);
2212+var TRUNC = function (value, places?) : number {
2213+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "TRUNC");
2214+ var n = TypeConverter.firstValueAsNumber(value);
2215 var digits = 0;
2216- if (values.length === 2) {
2217- digits = TypeConverter.firstValueAsNumber(values[1]);
2218+ if (places !== undefined) {
2219+ digits = TypeConverter.firstValueAsNumber(places);
2220 }
2221 var sign = (n > 0) ? 1 : -1;
2222 return sign * (Math.floor(Math.abs(n) * Math.pow(10, digits))) / Math.pow(10, digits);
2223@@ -795,55 +769,55 @@ var TRUNC = function (...values) : number {
2224
2225 /**
2226 * Converts an angle value in degrees to radians.
2227- * @param values[0] angle - The angle to convert from degrees to radians.
2228+ * @param angle - The angle to convert from degrees to radians.
2229 * @returns {number} radians
2230 * @constructor
2231 */
2232-var RADIANS = function (...values) {
2233- ArgsChecker.checkLength(values, 1, "RADIANS");
2234- var d = TypeConverter.firstValueAsNumber(values[0]);
2235+var RADIANS = function (angle) {
2236+ ArgsChecker.checkLength(arguments, 1, "RADIANS");
2237+ var d = TypeConverter.firstValueAsNumber(angle);
2238 return d * Math.PI / 180;
2239 };
2240
2241 /**
2242 * Converts an angle value in radians to degrees.
2243- * @param values[0] angle - The angle to convert from radians to degrees.
2244+ * @param angle - The angle to convert from radians to degrees.
2245 * @returns {number} degrees
2246 * @constructor
2247 */
2248-var DEGREES = function (...values) {
2249- ArgsChecker.checkLength(values, 1, "DEGREES");
2250- var r = TypeConverter.firstValueAsNumber(values[0]);
2251+var DEGREES = function (angle) {
2252+ ArgsChecker.checkLength(arguments, 1, "DEGREES");
2253+ var r = TypeConverter.firstValueAsNumber(angle);
2254 return r * 180 / Math.PI;
2255 };
2256
2257
2258 /**
2259 * Returns the complementary Gauss error function of a value.
2260- * @param values[0] The number for which to calculate the complementary Gauss error function.
2261+ * @param value - The number for which to calculate the complementary Gauss error function.
2262 * @returns {number} complementary Gauss error function of a value
2263 * @constructor
2264 */
2265-var ERFC = function (...values) {
2266- ArgsChecker.checkLength(values, 1, "ERFC");
2267- var v = TypeConverter.firstValueAsNumber(values[0]);
2268+var ERFC = function (value) {
2269+ ArgsChecker.checkLength(arguments, 1, "ERFC");
2270+ var v = TypeConverter.firstValueAsNumber(value);
2271 return v === 0 ? 1 : 1 - erf(v);
2272 };
2273
2274
2275 /**
2276 * Returns the error function integrated between lower_limit and upper_limit.
2277- * @param values[0] lower_limit - The lower bound for integrating ERF.
2278- * @param values[1] upper_limit - [Optional]. The upper bound for integrating ERF. If omitted, ERF integrates between
2279+ * @param lowerLimit - The lower bound for integrating ERF.
2280+ * @param upperLimit - [Optional]. The upper bound for integrating ERF. If omitted, ERF integrates between
2281 * zero and lower_limit.
2282 * @returns {number} error function integrated between lower_limit and upper_limit
2283 * @constructor
2284 */
2285-var ERF = function (...values) : number {
2286- ArgsChecker.checkLengthWithin(values, 1, 2, "ERF");
2287- var lower = TypeConverter.firstValueAsNumber(values[0]);
2288- var upper = values.length === 2 ? TypeConverter.firstValueAsNumber(values[1]) : 0;
2289- return values.length === 1 ? erf(lower) : erf(upper) - erf(lower);
2290+var ERF = function (lowerLimit, upperLimit?) : number {
2291+ ArgsChecker.checkLengthWithin(arguments, 1, 2, "ERF");
2292+ var lower = TypeConverter.firstValueAsNumber(lowerLimit);
2293+ var upper = upperLimit !== undefined ? TypeConverter.firstValueAsNumber(upperLimit) : 0;
2294+ return upperLimit === undefined ? erf(lower) : erf(upper) - erf(lower);
2295 };
2296
2297
2298@@ -895,17 +869,17 @@ function erf(x) {
2299
2300 /**
2301 * Calculates the sum of the sums of the squares of values in two arrays.
2302- * @param values[0] array_x - The array or range of values whose squares will be added to the squares of corresponding
2303- * entries in array_y and added together.
2304- * @param values[1] array_y - The array or range of values whose squares will be added to the squares of corresponding
2305- * entries in array_x and added together.
2306+ * @param arrayX - The array or range of values whose squares will be added to the squares of corresponding
2307+ * entries in arrayY and added together.
2308+ * @param arrayY - The array or range of values whose squares will be added to the squares of corresponding
2309+ * entries in arrayX and added together.
2310 * @returns {number} sum of the sums of the squares
2311 * @constructor
2312 */
2313-var SUMX2PY2 = function (...values) : number {
2314- ArgsChecker.checkLength(values, 2, "SUMX2PY2");
2315- var arrOne = Filter.flattenAndThrow(values[0]);
2316- var arrTwo = Filter.flattenAndThrow(values[1]);
2317+var SUMX2PY2 = function (arrayX, arrayY) : number {
2318+ ArgsChecker.checkLength(arguments, 2, "SUMX2PY2");
2319+ var arrOne = Filter.flattenAndThrow(arrayX);
2320+ var arrTwo = Filter.flattenAndThrow(arrayY);
2321 if (arrOne.length !== arrTwo.length) {
2322 throw new NAError("Array arguments to SUMX2PY2 are of different size.");
2323 }
2324@@ -921,17 +895,17 @@ var SUMX2PY2 = function (...values) : number {
2325
2326 /**
2327 * Calculates the sum of the differences of the squares of values in two arrays.
2328- * @param values[0] array_x - The array or range of values whose squares will be reduced by the squares of corresponding
2329+ * @param arrayX - The array or range of values whose squares will be reduced by the squares of corresponding
2330 * entries in array_y and added together.
2331- * @param values[1] array_y - The array or range of values whose squares will be subtracted from the squares of
2332+ * @param arrayY - The array or range of values whose squares will be subtracted from the squares of
2333 * corresponding entries in array_x and added together.
2334 * @returns {number} sum of the differences of the squares
2335 * @constructor
2336 */
2337-var SUMX2MY2 = function (...values) : number {
2338- ArgsChecker.checkLength(values, 2, "SUMX2MY2");
2339- var arrOne = Filter.flattenAndThrow(values[0]);
2340- var arrTwo = Filter.flattenAndThrow(values[1]);
2341+var SUMX2MY2 = function (arrayX, arrayY) : number {
2342+ ArgsChecker.checkLength(arguments, 2, "SUMX2MY2");
2343+ var arrOne = Filter.flattenAndThrow(arrayX);
2344+ var arrTwo = Filter.flattenAndThrow(arrayY);
2345 if (arrOne.length !== arrTwo.length) {
2346 throw new NAError("Array arguments to SUMX2MY2 are of different size.");
2347 }
2348@@ -1022,13 +996,13 @@ var SUMPRODUCT = function (...values) : number {
2349
2350 /**
2351 * Returns the number of ways to choose some number of objects from a pool of a given size of objects.
2352- * @param values[0] n - The size of the pool of objects to choose from.
2353- * @param values[1] k - The number of objects to choose.
2354+ * @param m - The size of the pool of objects to choose from.
2355+ * @param k - The number of objects to choose.
2356 * @returns {number} number of ways
2357 * @constructor
2358 */
2359-var COMBIN = function (...values) : number {
2360- ArgsChecker.checkLength(values, 2, "COMBIN");
2361+var COMBIN = function (m, k) : number {
2362+ ArgsChecker.checkLength(arguments, 2, "COMBIN");
2363
2364 var MEMOIZED_FACT = [];
2365 function fact(number) {
2366@@ -1042,8 +1016,8 @@ var COMBIN = function (...values) : number {
2367 return MEMOIZED_FACT[n];
2368 }
2369 }
2370- var n = TypeConverter.firstValueAsNumber(values[0]);
2371- var c = TypeConverter.firstValueAsNumber(values[1]);
2372+ var n = TypeConverter.firstValueAsNumber(m);
2373+ var c = TypeConverter.firstValueAsNumber(k);
2374 if (n < c) {
2375 throw new NumError("Function COMBIN parameter 2 value is "
2376 + c + ". It should be less than or equal to value of Function COMBIN parameter 1 with " + n + ".");
2377diff --git a/src/Formulas/Statistical.ts b/src/Formulas/Statistical.ts
2378index 840d42b..7e0a894 100644
2379--- a/src/Formulas/Statistical.ts
2380+++ b/src/Formulas/Statistical.ts
2381@@ -21,7 +21,7 @@ import {
2382
2383 /**
2384 * Calculates the sum of squares of deviations based on a sample.
2385- * @param values The values or ranges of the sample.
2386+ * @param values - The values or ranges of the sample.
2387 * @returns {number} sum of squares of deviations
2388 * @constructor
2389 */
2390@@ -44,7 +44,7 @@ var DEVSQ = function (...values) : number {
2391
2392 /**
2393 * Returns the median value in a numeric dataset.
2394- * @param values The value(s) or range(s) to consider when calculating the median value.
2395+ * @param values - The value(s) or range(s) to consider when calculating the median value.
2396 * @returns {number} the median value of the dataset
2397 * @constructor
2398 */
2399@@ -89,7 +89,7 @@ var MEDIAN = function (...values) : number {
2400
2401 /**
2402 * Returns the numerical average value in a dataset, ignoring text.
2403- * @param values The values or ranges to consider when calculating the average value.
2404+ * @param values - The values or ranges to consider when calculating the average value.
2405 * @returns {number} the average value of this dataset.
2406 * @constructor
2407 */
2408@@ -115,7 +115,7 @@ var AVERAGE = function (...values) : number {
2409
2410 /**
2411 * Calculates the average of the magnitudes of deviations of data from a dataset's mean.
2412- * @param values The value(s) or range(s)
2413+ * @param values - The value(s) or range(s)
2414 * @returns {number} average of the magnitudes of deviations of data from a dataset's mean
2415 * @constructor
2416 */
2417@@ -162,7 +162,7 @@ var AVEDEV = function (...values) {
2418
2419 /**
2420 * Returns the numerical average value in a dataset, coercing text values in ranges to 0 values.
2421- * @param values value(s) or range(s) to consider when calculating the average value.
2422+ * @param values - value(s) or range(s) to consider when calculating the average value.
2423 * @returns {number} the numerical average value in a dataset
2424 * @constructor
2425 */
2426@@ -192,12 +192,12 @@ var AVERAGEA = function (...values) {
2427 /**
2428 * Calculates r, the Pearson product-moment correlation coefficient of a dataset. Any text encountered in the arguments
2429 * will be ignored. CORREL is synonymous with PEARSON.
2430- * @param values[0] data_y - The range representing the array or matrix of dependent data.
2431- * @param values[1] data_x - The range representing the array or matrix of independent data.
2432+ * @param dataY - The range representing the array or matrix of dependent data.
2433+ * @param dataX - The range representing the array or matrix of independent data.
2434 * @returns {number} the Pearson product-moment correlation coefficient.
2435 * @constructor
2436 */
2437-var CORREL = function (...values) : number {
2438+var CORREL = function (dataY, dataX) : number {
2439 /**
2440 * Return the standard deviation of a vector. By defaut, the population standard deviation is returned. Passing true
2441 * for the flag parameter returns the sample standard deviation. See http://jstat.github.io/vector.html#stdev for
2442@@ -272,18 +272,18 @@ var CORREL = function (...values) : number {
2443 }
2444 return sum(sq_dev) / (arr1Len - 1);
2445 }
2446- ArgsChecker.checkLength(values, 2, "CORREL");
2447- if (!Array.isArray(values[0])) {
2448- values[0] = [values[0]];
2449+ ArgsChecker.checkLength(arguments, 2, "CORREL");
2450+ if (!Array.isArray(dataY)) {
2451+ dataY = [dataY];
2452 }
2453- if (!Array.isArray(values[1])) {
2454- values[1] = [values[1]];
2455+ if (!Array.isArray(dataX)) {
2456+ dataX = [dataX];
2457 }
2458- if (values[0].length !== values[1].length) {
2459- throw new NAError("CORREL has mismatched argument count " + values[0] + " vs " + values[1] + ".");
2460+ if (dataY.length !== dataX.length) {
2461+ throw new NAError("CORREL has mismatched argument count " + dataY + " vs " + dataX + ".");
2462 }
2463- var arr1 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(values[0]));
2464- var arr2 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(values[1]));
2465+ var arr1 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(dataY));
2466+ var arr2 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(dataX));
2467 var stdevArr1 = stdev(arr1, 1);
2468 var stdevArr2 = stdev(arr2, 1);
2469 if (stdevArr1 === 0 || stdevArr2 === 0) {
2470@@ -295,54 +295,54 @@ var CORREL = function (...values) : number {
2471 /**
2472 * Calculates r, the Pearson product-moment correlation coefficient of a dataset. Any text encountered in the arguments
2473 * will be ignored. PEARSON is synonymous with CORREL.
2474- * @param values[0] data_y - The range representing the array or matrix of dependent data.
2475- * @param values[1] data_x - The range representing the array or matrix of independent data.
2476+ * @param dataY - The range representing the array or matrix of dependent data.
2477+ * @param dataX - The range representing the array or matrix of independent data.
2478 * @returns {number} the Pearson product-moment correlation coefficient.
2479 * @constructor
2480 */
2481-var PEARSON = function (...values) {
2482- ArgsChecker.checkLength(values, 2, "PEARSON");
2483- return CORREL.apply(this, values);
2484+var PEARSON = function (dataY, dataX) {
2485+ ArgsChecker.checkLength(arguments, 2, "PEARSON");
2486+ return CORREL.apply(this, [dataY, dataX]);
2487 };
2488
2489 /**
2490 * Returns the value of the exponential distribution function with a specified lambda at a specified value.
2491- * @param values[0] x - The input to the exponential distribution function. If cumulative is TRUE then EXPONDIST returns
2492+ * @param x - The input to the exponential distribution function. If cumulative is TRUE then EXPONDIST returns
2493 * the cumulative probability of all values up to x.
2494- * @param values[1] lambda - The lambda to specify the exponential distribution function.
2495- * @param values[2] cumulative - Whether to use the exponential cumulative distribution.
2496+ * @param lambda - The lambda to specify the exponential distribution function.
2497+ * @param cumulative - Whether to use the exponential cumulative distribution.
2498 * @returns {number} value of the exponential distribution function.
2499 * @constructor
2500 */
2501-var EXPONDIST = function (...values) : number {
2502- ArgsChecker.checkLength(values, 3, "EXPONDIST");
2503+var EXPONDIST = function (x, lambda, cumulative) : number {
2504+ ArgsChecker.checkLength(arguments, 3, "EXPONDIST");
2505 function cdf(x, rate) {
2506 return x < 0 ? 0 : 1 - Math.exp(-rate * x);
2507 }
2508 function pdf(x, rate) {
2509 return x < 0 ? 0 : rate * Math.exp(-rate * x);
2510 }
2511- var x = TypeConverter.firstValueAsNumber(values[0]);
2512- var lambda = TypeConverter.firstValueAsNumber(values[1]);
2513- var cumulative = TypeConverter.firstValueAsBoolean(values[2]);
2514+ x = TypeConverter.firstValueAsNumber(x);
2515+ lambda = TypeConverter.firstValueAsNumber(lambda);
2516+ cumulative = TypeConverter.firstValueAsBoolean(cumulative);
2517 return (cumulative) ? cdf(x, lambda) : pdf(x, lambda);
2518 };
2519
2520 /**
2521 * Calculates the left-tailed F probability distribution (degree of diversity) for two data sets with given input x.
2522 * Alternately called Fisher-Snedecor distribution or Snecdor's F distribution.
2523- * @param values[0] x - The input to the F probability distribution function. The value at which to evaluate the function.
2524+ * @param x - The input to the F probability distribution function. The value at which to evaluate the function.
2525 * Must be a positive number.
2526- * @param values[1] degrees_freedom1 - The numerator degrees of freedom.
2527- * @param values[2] degrees_freedom2 - The denominator degrees of freedom.
2528- * @param values[3] cumulative - Logical value that determines the form of the function. If true returns the cumulative
2529+ * @param degreesFreedom1 - The numerator degrees of freedom.
2530+ * @param degreesFreedom2 - The denominator degrees of freedom.
2531+ * @param cumulative - Logical value that determines the form of the function. If true returns the cumulative
2532 * distribution function. If false returns the probability density function.
2533- * @returns {number|undefined|boolean} left-tailed F probability distribution
2534+ * @returns {number|boolean} left-tailed F probability distribution
2535 * @constructor
2536 * TODO: This function should be stricter in its return type.
2537 */
2538-var FDIST$LEFTTAILED = function (...values) : number|undefined|boolean {
2539- ArgsChecker.checkLength(values, 4, "FDIST$LEFTTAILED");
2540+var FDIST$LEFTTAILED = function (x, degreesFreedom1, degreesFreedom2, cumulative) : number|undefined|boolean {
2541+ ArgsChecker.checkLength(arguments, 4, "FDIST$LEFTTAILED");
2542 /**
2543 * Returns the Log-Gamma function evaluated at x. See http://jstat.github.io/special-functions.html#gammaln for more
2544 * information.
2545@@ -515,27 +515,27 @@ var FDIST$LEFTTAILED = function (...values) : number|undefined|boolean {
2546 // make sure x + y doesn't exceed the upper limit of usable values
2547 return (x + y > 170) ? Math.exp(betaln(x, y)) : gammafn(x) * gammafn(y) / gammafn(x + y);
2548 }
2549- var x = TypeConverter.firstValueAsNumber(values[0]);
2550+ x = TypeConverter.firstValueAsNumber(x);
2551 if (x < 0) {
2552 throw new NumError("Function F.DIST parameter 1 value is " + x + ". It should be greater than or equal to 0.");
2553 }
2554- var d1 = TypeConverter.firstValueAsNumber(values[1]);
2555- var d2 = TypeConverter.firstValueAsNumber(values[2]);
2556- var cumulative = TypeConverter.firstValueAsBoolean(values[3]);
2557- return (cumulative) ? cdf(x, d1, d2) : pdf(x, d1, d2);
2558+ var d1 = TypeConverter.firstValueAsNumber(degreesFreedom1);
2559+ var d2 = TypeConverter.firstValueAsNumber(degreesFreedom2);
2560+ var cum = TypeConverter.firstValueAsBoolean(cumulative);
2561+ return (cum) ? cdf(x, d1, d2) : pdf(x, d1, d2);
2562 };
2563
2564 /**
2565 * Returns the inverse of the (right-tailed) F probability distribution. If p = FDIST(x,...), then FINV(p,...) = x. The
2566 * F distribution can be used in an F-test that compares the degree of variability in two data sets.
2567- * @param values[0] probability - A probability associated with the F cumulative distribution.
2568- * @param values[1] deg_freedom1 - Required. The numerator degrees of freedom.
2569- * @param values[2] deg_freedom2 - Required. The denominator degrees of freedom.
2570+ * @param probability - A probability associated with the F cumulative distribution.
2571+ * @param degFreedom1 - Required. The numerator degrees of freedom.
2572+ * @param degFreedom2 - Required. The denominator degrees of freedom.
2573 * @returns {number} inverse of the (right-tailed) F probability distribution
2574 * @constructor
2575 */
2576-var FINV = function (...values) : number {
2577- ArgsChecker.checkLength(values, 3, "FINV");
2578+var FINV = function (probability, degFreedom1, degFreedom2) : number {
2579+ ArgsChecker.checkLength(arguments, 3, "FINV");
2580 /**
2581 * Returns the continued fraction for the incomplete Beta function with parameters a and b modified by Lentz's method
2582 * evaluated at x. For more information see http://jstat.github.io/special-functions.html#betacf
2583@@ -686,25 +686,25 @@ var FINV = function (...values) : number {
2584 function inv(x, df1, df2) {
2585 return df2 / (df1 * (1 / ibetainv(x, df1 / 2, df2 / 2) - 1));
2586 }
2587- var probability = TypeConverter.firstValueAsNumber(values[0]);
2588+ probability = TypeConverter.firstValueAsNumber(probability);
2589 if (probability <= 0.0 || probability > 1.0) {
2590 throw new NumError("Function FINV parameter 1 value is " + probability
2591 + ". It should be greater than or equal to 0, and less than 1.")
2592 }
2593- var d1 = TypeConverter.firstValueAsNumber(values[1]);
2594- var d2 = TypeConverter.firstValueAsNumber(values[2]);
2595+ var d1 = TypeConverter.firstValueAsNumber(degFreedom1);
2596+ var d2 = TypeConverter.firstValueAsNumber(degFreedom2);
2597 return inv(1.0 - probability, d1, d2);
2598 };
2599
2600 /**
2601 * Returns the Fisher transformation of a specified value.
2602- * @param values[0] value - The value for which to calculate the Fisher transformation.
2603+ * @param value - The value for which to calculate the Fisher transformation.
2604 * @returns {number} Fisher transformation
2605 * @constructor
2606 */
2607-var FISHER = function (...values) : number {
2608- ArgsChecker.checkLength(values, 1, "FISHER");
2609- var x = TypeConverter.firstValueAsNumber(values[0]);
2610+var FISHER = function (value) : number {
2611+ ArgsChecker.checkLength(arguments, 1, "FISHER");
2612+ var x = TypeConverter.firstValueAsNumber(value);
2613 if (x <= -1 || x >= 1) {
2614 throw new NumError("Function FISHER parameter 1 value is " + x + ". Valid values are between -1 and 1 exclusive.");
2615 }
2616@@ -713,20 +713,20 @@ var FISHER = function (...values) : number {
2617
2618 /**
2619 * Returns the inverse Fisher transformation of a specified value.
2620- * @param values[0] value - The value for which to calculate the inverse Fisher transformation.
2621+ * @param value - The value for which to calculate the inverse Fisher transformation.
2622 * @returns {number} inverse Fisher transformation
2623 * @constructor
2624 */
2625-var FISHERINV = function (...values) : number {
2626- ArgsChecker.checkLength(values, 1, "FISHERINV");
2627- var y = TypeConverter.firstValueAsNumber(values[0]);
2628+var FISHERINV = function (value) : number {
2629+ ArgsChecker.checkLength(arguments, 1, "FISHERINV");
2630+ var y = TypeConverter.firstValueAsNumber(value);
2631 var e2y = Math.exp(2 * y);
2632 return (e2y - 1) / (e2y + 1);
2633 };
2634
2635 /**
2636 * Returns the maximum value in a numeric dataset.
2637- * @param values The values or range(s) to consider when calculating the maximum value.
2638+ * @param values - The values or range(s) to consider when calculating the maximum value.
2639 * @returns {number} the maximum value of the dataset
2640 * @constructor
2641 */
2642@@ -751,7 +751,7 @@ var MAX = function (...values) {
2643
2644 /**
2645 * Returns the maximum numeric value in a dataset.
2646- * @param values The value(s) or range(s) to consider when calculating the maximum value.
2647+ * @param values - The value(s) or range(s) to consider when calculating the maximum value.
2648 * @returns {number} maximum value of the dataset
2649 * @constructor
2650 */
2651@@ -763,7 +763,7 @@ var MAXA = function (...values) : number {
2652
2653 /**
2654 * Returns the minimum value in a numeric dataset.
2655- * @param values The value(s) or range(s) to consider when calculating the minimum value.
2656+ * @param values - The value(s) or range(s) to consider when calculating the minimum value.
2657 * @returns {number} the minimum value of the dataset
2658 * @constructor
2659 */
2660@@ -789,7 +789,7 @@ var MIN = function (...values) {
2661
2662 /**
2663 * Returns the minimum numeric value in a dataset.
2664- * @param values The value(s) or range(s) to consider when calculating the minimum value.
2665+ * @param values - The value(s) or range(s) to consider when calculating the minimum value.
2666 * @returns {number} the minimum value in the dataset
2667 * @constructor
2668 */
2669@@ -801,18 +801,18 @@ var MINA = function (...values) : number {
2670
2671 /**
2672 * Returns the average of a range depending on criteria.
2673- * @param values[0] criteria_range - The range to check against criterion.
2674- * @param values[1] criterion - The pattern or test to apply to criteria_range.
2675- * @param values[2] average_range - [optional] The range to average. If not included, criteria_range is used for the
2676+ * @param criteriaRange - The range to check against criterion.
2677+ * @param criterion - The pattern or test to apply to criteria_range.
2678+ * @param averageRange - [optional] The range to average. If not included, criteria_range is used for the
2679 * average instead.
2680 * @returns {number}
2681 * @constructor
2682 * TODO: This needs to also accept a third parameter "average_range"
2683 */
2684-var AVERAGEIF = function (...values) {
2685- ArgsChecker.checkLength(values, 2, "AVERAGEIF");
2686- var range = Filter.flatten(values[0]);
2687- var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(values[1]);
2688+var AVERAGEIF = function (criteriaRange, criterion, averageRange?) {
2689+ ArgsChecker.checkLength(arguments, 2, "AVERAGEIF");
2690+ var range = Filter.flatten(criteriaRange);
2691+ var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criterion);
2692
2693 var result = 0;
2694 var count = 0;
2695@@ -832,7 +832,7 @@ var AVERAGEIF = function (...values) {
2696
2697 /**
2698 * Returns the a count of the number of numeric values in a dataset.
2699- * @param values The values or ranges to consider when counting.
2700+ * @param values - The values or ranges to consider when counting.
2701 * @returns {number} number of numeric values in a dataset.
2702 * @constructor
2703 */
2704@@ -853,7 +853,7 @@ var COUNT = function (...values) : number {
2705
2706 /**
2707 * Returns the a count of the number of values in a dataset.
2708- * @param values The values or ranges to consider when counting.
2709+ * @param values - The values or ranges to consider when counting.
2710 * @returns {number} number of values in a dataset.
2711 * @constructor
2712 */
2713diff --git a/src/Formulas/Text.ts b/src/Formulas/Text.ts
2714index 01f99f6..93aef44 100644
2715--- a/src/Formulas/Text.ts
2716+++ b/src/Formulas/Text.ts
2717@@ -13,7 +13,7 @@ import {
2718
2719 /**
2720 * Computes the value of a Roman numeral.
2721- * @param text The Roman numeral to format, whose value must be between 1 and 3999, inclusive.
2722+ * @param text - The Roman numeral to format, whose value must be between 1 and 3999, inclusive.
2723 * @returns {number} value in integer format
2724 * @constructor
2725 */
2726@@ -43,13 +43,13 @@ var ARABIC = function (text?) {
2727
2728 /**
2729 * Convert a number into a character according to the current Unicode table.
2730- * @param values[0] The number of the character to look up from the current Unicode table in decimal format.
2731+ * @param value - The number of the character to look up from the current Unicode table in decimal format.
2732 * @returns {string} character corresponding to Unicode number
2733 * @constructor
2734 */
2735-var CHAR = function (...values) : string {
2736- ArgsChecker.checkLength(values, 1, "CHAR");
2737- var n = TypeConverter.firstValueAsNumber(values[0]);
2738+var CHAR = function (value) : string {
2739+ ArgsChecker.checkLength(arguments, 1, "CHAR");
2740+ var n = TypeConverter.firstValueAsNumber(value);
2741 if (n < 1 || n > 1114112) { //limit
2742 throw new NumError("Function CHAR parameter 1 value " + n + " is out of range.");
2743 }
2744@@ -58,13 +58,13 @@ var CHAR = function (...values) : string {
2745
2746 /**
2747 * Returns the numeric Unicode map value of the first character in the string provided.
2748- * @param values[0] The string whose first character's Unicode map value will be returned.
2749+ * @param value - The string whose first character's Unicode map value will be returned.
2750 * @returns {number} number of the first character's Unicode value
2751 * @constructor
2752 */
2753-var CODE = function (...values) : number {
2754- ArgsChecker.checkLength(values, 1, "CODE");
2755- var text = TypeConverter.firstValueAsString(values[0]);
2756+var CODE = function (value) : number {
2757+ ArgsChecker.checkLength(arguments, 1, "CODE");
2758+ var text = TypeConverter.firstValueAsString(value);
2759 if (text === "") {
2760 throw new ValueError("Function CODE parameter 1 value should be non-empty.");
2761 }
2762@@ -73,22 +73,19 @@ var CODE = function (...values) : number {
2763
2764 /**
2765 * Divides text around a specified character or string, and puts each fragment into a separate cell in the row.
2766- * @param values[0] text - The text to divide.
2767- * @param values[1] delimiter - The character or characters to use to split text.
2768- * @param values[2] split_by_each - [optional] Whether or not to divide text around each character contained in
2769+ * @param text - The text to divide.
2770+ * @param delimiter - The character or characters to use to split text.
2771+ * @param splitByEach - [optional] Whether or not to divide text around each character contained in
2772 * delimiter.
2773 * @returns {Array<string>} containing the split
2774 * @constructor
2775 * TODO: At some point this needs to return a more complex type than Array. Needs to return a type that has a dimension.
2776 */
2777-var SPLIT = function (...values) : Array<string> {
2778- ArgsChecker.checkLengthWithin(values, 2, 3, "SPLIT");
2779- var text = TypeConverter.firstValueAsString(values[0]);
2780- var delimiter = TypeConverter.firstValueAsString(values[1]);
2781- var splitByEach = false;
2782- if (values.length === 3) {
2783- splitByEach = TypeConverter.firstValueAsBoolean(values[2]);
2784- }
2785+var SPLIT = function (text, delimiter, splitByEach?) : Array<string> {
2786+ ArgsChecker.checkLengthWithin(arguments, 2, 3, "SPLIT");
2787+ text = TypeConverter.firstValueAsString(text);
2788+ delimiter = TypeConverter.firstValueAsString(delimiter);
2789+ splitByEach = splitByEach === undefined ? false : TypeConverter.firstValueAsBoolean(splitByEach);
2790 if (splitByEach) {
2791 var result = [text];
2792 for (var i = 0; i < delimiter.length; i++) {
2793@@ -109,7 +106,7 @@ var SPLIT = function (...values) : Array<string> {
2794
2795 /**
2796 * Appends strings to one another.
2797- * @param values to append to one another. Must contain at least one value
2798+ * @param values - to append to one another. Must contain at least one value
2799 * @returns {string} concatenated string
2800 * @constructor
2801 */
2802@@ -131,18 +128,18 @@ var CONCATENATE = function (...values) : string {
2803
2804 /**
2805 * Converts a numeric value to a different unit of measure.
2806- * @param values[0] value - the numeric value in start_unit to convert to end_unit.
2807- * @param values[1] start_unit - The starting unit, the unit currently assigned to value.
2808- * @param values[2] end_unit - The unit of measure into which to convert value.
2809+ * @param value - the numeric value in start_unit to convert to end_unit.
2810+ * @param startUnit - The starting unit, the unit currently assigned to value.
2811+ * @param endUnit - The unit of measure into which to convert value.
2812 * @returns {number}
2813 * @constructor
2814 * TODO: Looking up units is not efficient at all. We should use an object instead of iterating through an array.
2815 */
2816-var CONVERT = function (...values) {
2817- ArgsChecker.checkLength(values, 3, "CONVERT");
2818- var n = TypeConverter.firstValueAsNumber(values[0]);
2819- var fromUnit = TypeConverter.firstValueAsString(values[1]);
2820- var toUnit = TypeConverter.firstValueAsString(values[2]);
2821+var CONVERT = function (value, startUnit, endUnit) {
2822+ ArgsChecker.checkLength(arguments, 3, "CONVERT");
2823+ var n = TypeConverter.firstValueAsNumber(value);
2824+ var fromUnit = TypeConverter.firstValueAsString(startUnit);
2825+ var toUnit = TypeConverter.firstValueAsString(endUnit);
2826
2827 // NOTE: A lot of the code for this method is from https://github.com/sutoiku/formula.js. I'm relying on them to have
2828 // gotten it right, but I'm spot checking some of their work against GS, MSE, LibreOffice, OpenOffice.
2829diff --git a/tests/Formulas/DateFormulasTest.ts b/tests/Formulas/DateFormulasTest.ts
2830index b6e84e5..9b6bf39 100644
2831--- a/tests/Formulas/DateFormulasTest.ts
2832+++ b/tests/Formulas/DateFormulasTest.ts
2833@@ -43,10 +43,10 @@ test("WORKDAY.INTL", function () {
2834 assertEquals(WORKDAY$INTL(DATE(1945, 1, 14), 6000, "1110001"), DATE(1983, 5, 14));
2835 assertEquals(WORKDAY$INTL(DATE(1945, 1, 14), 6000, 6), DATE(1968, 1, 14));
2836 catchAndAssertEquals(function() {
2837- WORKDAY$INTL(12, 12, [12], false, 1);
2838+ WORKDAY$INTL.apply(this, [12, 12, [12], false, 1]);
2839 }, ERRORS.NA_ERROR);
2840 catchAndAssertEquals(function() {
2841- WORKDAY$INTL(12);
2842+ WORKDAY$INTL.apply(this, [12]);
2843 }, ERRORS.NA_ERROR);
2844 catchAndAssertEquals(function() {
2845 WORKDAY$INTL("1992-1-1", "str");
2846@@ -77,10 +77,10 @@ test("WORKDAY", function () {
2847 assertEquals(WORKDAY(DATE(2012, 5, 29), 1000, [41058, 41059, 41060, 41061, 41062]), DATE(2016, 4, 1));
2848 assertEquals(WORKDAY([DATE(1999, 2, 2)], [10]), DATE(1999, 2, 16));
2849 catchAndAssertEquals(function() {
2850- WORKDAY();
2851+ WORKDAY.apply(this, []);
2852 }, ERRORS.NA_ERROR);
2853 catchAndAssertEquals(function() {
2854- WORKDAY(DATE(2012, 5, 29), 1000, [10], 11);
2855+ WORKDAY.apply(this, [DATE(2012, 5, 29), 1000, [10], 11]);
2856 }, ERRORS.NA_ERROR);
2857 });
2858
2859@@ -101,13 +101,13 @@ test("TIME", function () {
2860 assertEquals(TIME(3, 0, 0), 0.125);
2861 assertEquals(TIME("3", ["0"], false), 0.125);
2862 catchAndAssertEquals(function() {
2863- TIME();
2864+ TIME.apply(this, []);
2865 }, ERRORS.NA_ERROR);
2866 catchAndAssertEquals(function() {
2867- TIME(1, 1);
2868+ TIME.apply(this, [1, 1]);
2869 }, ERRORS.NA_ERROR);
2870 catchAndAssertEquals(function() {
2871- TIME(1, 1, 1, 1);
2872+ TIME.apply(this, [1, 1, 1, 1]);
2873 }, ERRORS.NA_ERROR);
2874 catchAndAssertEquals(function() {
2875 TIME(-29, 10, 10);
2876@@ -160,10 +160,10 @@ test("NETWORKDAYS$INTL", function () {
2877 assertEquals(NETWORKDAYS$INTL(900, 12004), 7933);
2878 assertEquals(NETWORKDAYS$INTL(900, 12005), 7933);
2879 catchAndAssertEquals(function() {
2880- NETWORKDAYS$INTL(12, 12, [12], false, 1);
2881+ NETWORKDAYS$INTL.apply(this, [12, 12, [12], false, 1]);
2882 }, ERRORS.NA_ERROR);
2883 catchAndAssertEquals(function() {
2884- NETWORKDAYS$INTL(12);
2885+ NETWORKDAYS$INTL.apply(this, [12]);
2886 }, ERRORS.NA_ERROR);
2887 catchAndAssertEquals(function() {
2888 NETWORKDAYS$INTL("1992-1-1", "str");
2889@@ -219,10 +219,10 @@ test("NETWORKDAYS", function(){
2890 assertEquals(NETWORKDAYS(12, 12, [12]), 0);
2891 assertEquals(NETWORKDAYS(DATE(1998, 1, 1), DATE(1999, 1, 22), [DATE(1999, 1, 20)]), 276);
2892 catchAndAssertEquals(function() {
2893- NETWORKDAYS(12, 12, [12], false);
2894+ NETWORKDAYS.apply(this, [12, 12, [12], false]);
2895 }, ERRORS.NA_ERROR);
2896 catchAndAssertEquals(function() {
2897- NETWORKDAYS(12);
2898+ NETWORKDAYS.apply(this, [12]);
2899 }, ERRORS.NA_ERROR);
2900 catchAndAssertEquals(function() {
2901 NETWORKDAYS("1992-1-1", "str");
2902@@ -251,10 +251,10 @@ test("SECOND", function() {
2903 assertEquals(SECOND("1992-1-1 8:120:104"), 44);
2904 assertEquals(SECOND(0.511111111111), 0);
2905 catchAndAssertEquals(function() {
2906- SECOND("8:10", 5);
2907+ SECOND.apply(this, ["8:10", 5]);
2908 }, ERRORS.NA_ERROR);
2909 catchAndAssertEquals(function() {
2910- SECOND();
2911+ SECOND.apply(this, []);
2912 }, ERRORS.NA_ERROR);
2913 catchAndAssertEquals(function() {
2914 SECOND("str");
2915@@ -294,10 +294,10 @@ test("MINUTE", function() {
2916 assertEquals(MINUTE(99.5), 0);
2917 assertEquals(MINUTE("1969-7-6 5:05am"), 5);
2918 catchAndAssertEquals(function() {
2919- MINUTE("8:10", 5);
2920+ MINUTE.apply(this, ["8:10", 5]);
2921 }, ERRORS.NA_ERROR);
2922 catchAndAssertEquals(function() {
2923- MINUTE();
2924+ MINUTE.apply(this, []);
2925 }, ERRORS.NA_ERROR);
2926 catchAndAssertEquals(function() {
2927 MINUTE("str");
2928@@ -340,10 +340,10 @@ test("HOUR", function() {
2929 assertEquals(HOUR("0.0625"), 1);
2930 assertEquals(HOUR("1969-7-6 5am"), 5);
2931 catchAndAssertEquals(function() {
2932- HOUR("8:10", 5);
2933+ HOUR.apply(this, ["8:10", 5]);
2934 }, ERRORS.NA_ERROR);
2935 catchAndAssertEquals(function() {
2936- HOUR();
2937+ HOUR.apply(this, []);
2938 }, ERRORS.NA_ERROR);
2939 catchAndAssertEquals(function() {
2940 HOUR("str");
2941@@ -378,10 +378,10 @@ test("TIMEVALUE", function() {
2942 assertEquals(TIMEVALUE("11:21222:2111pm"), 0.7202662037037038);
2943 assertEquals(TIMEVALUE("11:21222:2111am"), 0.2202662037037037);
2944 catchAndAssertEquals(function() {
2945- TIMEVALUE("8:10", 5);
2946+ TIMEVALUE.apply(this, ["8:10", 5]);
2947 }, ERRORS.NA_ERROR);
2948 catchAndAssertEquals(function() {
2949- TIMEVALUE();
2950+ TIMEVALUE.apply(this, []);
2951 }, ERRORS.NA_ERROR);
2952 catchAndAssertEquals(function() {
2953 TIMEVALUE("str");
2954@@ -463,10 +463,10 @@ test("YEARFRAC", function(){
2955 YEARFRAC("1996-6-19", "1992-6-19", 5);
2956 }, ERRORS.NUM_ERROR);
2957 catchAndAssertEquals(function() {
2958- YEARFRAC();
2959+ YEARFRAC.apply(this, []);
2960 }, ERRORS.NA_ERROR);
2961 catchAndAssertEquals(function() {
2962- YEARFRAC("1992-6-19", "1995-6-19", 1, 0);
2963+ YEARFRAC.apply(this, ["1992-6-19", "1995-6-19", 1, 0]);
2964 }, ERRORS.NA_ERROR);
2965 catchAndAssertEquals(function() {
2966 YEARFRAC("str", "1995-6-19", 1);
2967@@ -542,10 +542,10 @@ test("DATEDIF", function(){
2968 DATEDIF("1992-6-19", "1995-6-19", "mm");
2969 }, ERRORS.NUM_ERROR);
2970 catchAndAssertEquals(function() {
2971- DATEDIF();
2972+ DATEDIF.apply(this, []);
2973 }, ERRORS.NA_ERROR);
2974 catchAndAssertEquals(function() {
2975- DATEDIF("1992-6-19", "1995-6-19", "mm", 0);
2976+ DATEDIF.apply(this, ["1992-6-19", "1995-6-19", "mm", 0]);
2977 }, ERRORS.NA_ERROR);
2978 catchAndAssertEquals(function() {
2979 DATEDIF("str", "1995-6-19", "mm");
2980@@ -1077,10 +1077,10 @@ test("WEEKNUM", function(){
2981 assertEquals(WEEKNUM(745, 21), 3);
2982 assertEquals(WEEKNUM(746, 21), 3);
2983 catchAndAssertEquals(function() {
2984- WEEKNUM();
2985+ WEEKNUM.apply(this, []);
2986 }, ERRORS.NA_ERROR);
2987 catchAndAssertEquals(function() {
2988- WEEKNUM(213123, 1, 1);
2989+ WEEKNUM.apply(this, [213123, 1, 1]);
2990 }, ERRORS.NA_ERROR);
2991 catchAndAssertEquals(function() {
2992 WEEKNUM("str");
2993@@ -1143,10 +1143,10 @@ test("WEEKDAY", function(){
2994 assertEquals(WEEKDAY(40915, 3), 5);
2995 assertEquals(WEEKDAY(40916, 3), 6);
2996 catchAndAssertEquals(function() {
2997- WEEKDAY();
2998+ WEEKDAY.apply(this, []);
2999 }, ERRORS.NA_ERROR);
3000 catchAndAssertEquals(function() {
3001- WEEKDAY(213123, 1, 1);
3002+ WEEKDAY.apply(this, [213123, 1, 1]);
3003 }, ERRORS.NA_ERROR);
3004 catchAndAssertEquals(function() {
3005 WEEKDAY("str");
3006@@ -1176,10 +1176,10 @@ test("YEAR", function(){
3007 assertEquals(YEAR(true), 1899);
3008 assertEquals(YEAR([1, "str"]), 1899);
3009 catchAndAssertEquals(function() {
3010- YEAR();
3011+ YEAR.apply(this, []);
3012 }, ERRORS.NA_ERROR);
3013 catchAndAssertEquals(function() {
3014- YEAR(213123, 123123);
3015+ YEAR.apply(this, [213123, 123123]);
3016 }, ERRORS.NA_ERROR);
3017 catchAndAssertEquals(function() {
3018 YEAR("str");
3019@@ -1198,10 +1198,10 @@ test("MONTH", function(){
3020 assertEquals(MONTH(1312212), 9);
3021 assertEquals(MONTH(13122121), 2);
3022 catchAndAssertEquals(function() {
3023- MONTH();
3024+ MONTH.apply(this, []);
3025 }, ERRORS.NA_ERROR);
3026 catchAndAssertEquals(function() {
3027- MONTH(213123, 123123);
3028+ MONTH.apply(this, [213123, 123123]);
3029 }, ERRORS.NA_ERROR);
3030 catchAndAssertEquals(function() {
3031 MONTH("str");
3032@@ -1232,13 +1232,13 @@ test("DAYS360", function(){
3033 assertEquals(DAYS360(33779, 33780), 1);
3034 assertEquals(DAYS360([1, "str"], [390, "str"]), 384);
3035 catchAndAssertEquals(function() {
3036- DAYS360();
3037+ DAYS360.apply(this, []);
3038 }, ERRORS.NA_ERROR);
3039 catchAndAssertEquals(function() {
3040- DAYS360(100);
3041+ DAYS360.apply(this, [100]);
3042 }, ERRORS.NA_ERROR);
3043 catchAndAssertEquals(function() {
3044- DAYS360(100, 200, true, "str");
3045+ DAYS360.apply(this, [100, 200, true, "str"]);
3046 }, ERRORS.NA_ERROR);
3047 catchAndAssertEquals(function() {
3048 DAYS360("str", 100);
3049@@ -1268,13 +1268,13 @@ test("DAYS", function(){
3050 assertEquals(DAYS([0, "str"], [100, "str"]), -100);
3051 assertEquals(DAYS("1992, 6, 25", "1992, 6, 24"), 1);
3052 catchAndAssertEquals(function() {
3053- DAYS();
3054+ DAYS.apply(this, []);
3055 }, ERRORS.NA_ERROR);
3056 catchAndAssertEquals(function() {
3057- DAYS(100);
3058+ DAYS.apply(this, [100]);
3059 }, ERRORS.NA_ERROR);
3060 catchAndAssertEquals(function() {
3061- DAYS(100, 200, 300);
3062+ DAYS.apply(this, [100, 200, 300]);
3063 }, ERRORS.NA_ERROR);
3064 catchAndAssertEquals(function() {
3065 DAYS([[], 100], 22);
3066@@ -1307,10 +1307,10 @@ test("DAY", function(){
3067 DAY("str");
3068 }, ERRORS.VALUE_ERROR);
3069 catchAndAssertEquals(function() {
3070- DAY();
3071+ DAY.apply(this, []);
3072 }, ERRORS.NA_ERROR);
3073 catchAndAssertEquals(function() {
3074- DAY(DATE(1992, 6, 24), 4);
3075+ DAY.apply(this, [DATE(1992, 6, 24), 4]);
3076 }, ERRORS.NA_ERROR);
3077 catchAndAssertEquals(function() {
3078 DAY(-1);
3079@@ -1333,10 +1333,10 @@ test("EDATE", function(){
3080 EDATE("str", 2);
3081 }, ERRORS.VALUE_ERROR);
3082 catchAndAssertEquals(function() {
3083- EDATE(DATE(1992, 6, 24));
3084+ EDATE.apply(this, [DATE(1992, 6, 24)]);
3085 }, ERRORS.NA_ERROR);
3086 catchAndAssertEquals(function() {
3087- EDATE(DATE(1992, 6, 24), 4, 4);
3088+ EDATE.apply(this, [DATE(1992, 6, 24), 4, 4]);
3089 }, ERRORS.NA_ERROR);
3090 catchAndAssertEquals(function() {
3091 EDATE(-1, 1);
3092@@ -1365,6 +1365,12 @@ test("EOMONTH", function(){
3093 assertEquals(EOMONTH(false, 1), DATE(1900, 1, 31));
3094 assertEquals(EOMONTH(1, 1), DATE(1900, 1, 31));
3095 assertEquals(EOMONTH(true, 1), DATE(1900, 1, 31));
3096+ catchAndAssertEquals(function() {
3097+ EOMONTH.apply(this, []);
3098+ }, ERRORS.NA_ERROR);
3099+ catchAndAssertEquals(function() {
3100+ EOMONTH.apply(this, [true, 1, 1]);
3101+ }, ERRORS.NA_ERROR);
3102 catchAndAssertEquals(function() {
3103 EOMONTH("str", 2);
3104 }, ERRORS.VALUE_ERROR);
3105@@ -1382,10 +1388,10 @@ test("DATE", function(){
3106 DATE(1900, 0, 5);
3107 }, ERRORS.NUM_ERROR);
3108 catchAndAssertEquals(function() {
3109- DATE(1900, 0, 5, 22);
3110+ DATE.apply(this, [1900, 0, 5, 22]);
3111 }, ERRORS.NA_ERROR);
3112 catchAndAssertEquals(function() {
3113- DATE(1900, 0);
3114+ DATE.apply(this, [1900, 0]);
3115 }, ERRORS.NA_ERROR);
3116 assertEquals(DATE(1992, 6, 24), 33779);
3117 assertEquals(DATE(2017, 2, 26), 42792);
3118@@ -1451,10 +1457,10 @@ test("DATEVALUE", function(){
3119 assertEquals(DATEVALUE("January-2017 10:10:10"), 42736);
3120 assertEquals(DATEVALUE("January-2017 10:10:10am"), 42736);
3121 catchAndAssertEquals(function() {
3122- DATEVALUE("6/24/92", 10);
3123+ DATEVALUE.apply(this, ["6/24/92", 10]);
3124 }, ERRORS.NA_ERROR);
3125 catchAndAssertEquals(function() {
3126- DATEVALUE();
3127+ DATEVALUE.apply(this, []);
3128 }, ERRORS.NA_ERROR);
3129 catchAndAssertEquals(function() {
3130 DATEVALUE(false);
3131diff --git a/tests/Formulas/DateFormulasTestTimeOverride.ts b/tests/Formulas/DateFormulasTestTimeOverride.ts
3132index b5c2ba9..0b27752 100644
3133--- a/tests/Formulas/DateFormulasTestTimeOverride.ts
3134+++ b/tests/Formulas/DateFormulasTestTimeOverride.ts
3135@@ -32,7 +32,7 @@ test("NOW", function(){
3136 lockDate(1944, 1, 2, 1, 11, 55);
3137 assertEquals(NOW(), 16104.29994212963);
3138 catchAndAssertEquals(function() {
3139- NOW(12);
3140+ NOW.apply(this, [12]);
3141 }, ERRORS.NA_ERROR);
3142 });
3143
3144@@ -47,6 +47,6 @@ test("TODAY", function(){
3145 lockDate(1944, 1, 2, 1, 11, 55);
3146 assertEquals(TODAY(), DATEVALUE("Feb 2 1944"));
3147 catchAndAssertEquals(function() {
3148- TODAY(12);
3149+ TODAY.apply(this, [12]);
3150 }, ERRORS.NA_ERROR);
3151 });
3152diff --git a/tests/Formulas/EngineeringTest.ts b/tests/Formulas/EngineeringTest.ts
3153index 521513d..b425b07 100644
3154--- a/tests/Formulas/EngineeringTest.ts
3155+++ b/tests/Formulas/EngineeringTest.ts
3156@@ -26,10 +26,10 @@ test("BIN2DEC", function(){
3157 BIN2DEC("str");
3158 }, ERRORS.NUM_ERROR);
3159 catchAndAssertEquals(function() {
3160- BIN2DEC();
3161+ BIN2DEC.apply(this, []);
3162 }, ERRORS.NA_ERROR);
3163 catchAndAssertEquals(function() {
3164- BIN2DEC("10", "10");
3165+ BIN2DEC.apply(this, ["10", "10"]);
3166 }, ERRORS.NA_ERROR);
3167 });
3168
3169@@ -53,10 +53,10 @@ test("BIN2HEX", function(){
3170 BIN2DEC("str");
3171 }, ERRORS.NUM_ERROR);
3172 catchAndAssertEquals(function() {
3173- BIN2DEC();
3174+ BIN2DEC.apply(this, []);
3175 }, ERRORS.NA_ERROR);
3176 catchAndAssertEquals(function() {
3177- BIN2DEC("10", 4, 4);
3178+ BIN2DEC.apply(this, ["10", 4, 4]);
3179 }, ERRORS.NA_ERROR);
3180
3181 });
3182@@ -82,10 +82,10 @@ test("BIN2OCT", function(){
3183 BIN2OCT("str");
3184 }, ERRORS.NUM_ERROR);
3185 catchAndAssertEquals(function() {
3186- BIN2OCT();
3187+ BIN2OCT.apply(this, []);
3188 }, ERRORS.NA_ERROR);
3189 catchAndAssertEquals(function() {
3190- BIN2OCT("10", 4, 4);
3191+ BIN2OCT.apply(this, ["10", 4, 4]);
3192 }, ERRORS.NA_ERROR);
3193 });
3194
3195@@ -114,10 +114,10 @@ test("DEC2BIN", function(){
3196 DEC2BIN(513, 10);
3197 }, ERRORS.NUM_ERROR);
3198 catchAndAssertEquals(function() {
3199- DEC2BIN(100, 100, 10);
3200+ DEC2BIN.apply(this, [100, 100, 10]);
3201 }, ERRORS.NA_ERROR);
3202 catchAndAssertEquals(function() {
3203- DEC2BIN();
3204+ DEC2BIN.apply(this, []);
3205 }, ERRORS.NA_ERROR);
3206 catchAndAssertEquals(function() {
3207 DEC2BIN("str");
3208@@ -152,10 +152,10 @@ test("DEC2HEX", function(){
3209 DEC2HEX(54975581, -10);
3210 }, ERRORS.NUM_ERROR);
3211 catchAndAssertEquals(function() {
3212- DEC2HEX(100, 100, 10);
3213+ DEC2HEX.apply(this, [100, 100, 10]);
3214 }, ERRORS.NA_ERROR);
3215 catchAndAssertEquals(function() {
3216- DEC2HEX();
3217+ DEC2HEX.apply(this, []);
3218 }, ERRORS.NA_ERROR);
3219 catchAndAssertEquals(function() {
3220 DEC2HEX("str");
3221@@ -190,10 +190,10 @@ test("DEC2OCT", function(){
3222 DEC2OCT(536870910, -10);
3223 }, ERRORS.NUM_ERROR);
3224 catchAndAssertEquals(function() {
3225- DEC2OCT(100, 100, 10);
3226+ DEC2OCT.apply(this, [100, 100, 10]);
3227 }, ERRORS.NA_ERROR);
3228 catchAndAssertEquals(function() {
3229- DEC2OCT();
3230+ DEC2OCT.apply(this, []);
3231 }, ERRORS.NA_ERROR);
3232 catchAndAssertEquals(function() {
3233 DEC2OCT("str");
3234@@ -219,9 +219,9 @@ test("DELTA", function(){
3235 DELTA("n", "n");
3236 }, ERRORS.VALUE_ERROR);
3237 catchAndAssertEquals(function() {
3238- DELTA();
3239+ DELTA.apply(this, []);
3240 }, ERRORS.NA_ERROR);
3241 catchAndAssertEquals(function() {
3242- DELTA(1, 2, 3);
3243+ DELTA.apply(this, [1, 2, 3]);
3244 }, ERRORS.NA_ERROR);
3245 });
3246diff --git a/tests/Formulas/FinancialTest.ts b/tests/Formulas/FinancialTest.ts
3247index 06ca457..c0cec49 100644
3248--- a/tests/Formulas/FinancialTest.ts
3249+++ b/tests/Formulas/FinancialTest.ts
3250@@ -48,10 +48,10 @@ test("ACCRINT", function(){
3251 ACCRINT(100, 2, 1, 0.1, 1000, 1, 4);
3252 }, ERRORS.NUM_ERROR);
3253 catchAndAssertEquals(function() {
3254- ACCRINT(100, 2, 1, 0.1, 1000);
3255+ ACCRINT.apply(this, [100, 2, 1, 0.1, 1000]);
3256 }, ERRORS.NA_ERROR);
3257 catchAndAssertEquals(function() {
3258- ACCRINT(1, 2, 1461, 0.1, 1000, 1, 1, 1);
3259+ ACCRINT.apply(this, [1, 2, 1461, 0.1, 1000, 1, 1, 1]);
3260 }, ERRORS.NA_ERROR);
3261 });
3262
3263@@ -71,13 +71,13 @@ test("CUMPRINC", function(){
3264 CUMPRINC(0.12, 12, 100, 3, 1, false);
3265 }, ERRORS.NUM_ERROR);
3266 catchAndAssertEquals(function() {
3267- CUMPRINC();
3268+ CUMPRINC.apply(this, []);
3269 }, ERRORS.NA_ERROR);
3270 catchAndAssertEquals(function() {
3271- CUMPRINC(0.12, 12, 100, 1, 5, true, 55);
3272+ CUMPRINC.apply(this, [0.12, 12, 100, 1, 5, true, 55]);
3273 }, ERRORS.NA_ERROR);
3274 catchAndAssertEquals(function() {
3275- CUMPRINC(0.12, 12, 100, 1, 5);
3276+ CUMPRINC.apply(this, [0.12, 12, 100, 1, 5]);
3277 }, ERRORS.NA_ERROR);
3278 });
3279
3280@@ -100,13 +100,13 @@ test("CUMIPMT", function(){
3281 CUMIPMT(0.12, 12, 100, 3, 1, false);
3282 }, ERRORS.NUM_ERROR);
3283 catchAndAssertEquals(function() {
3284- CUMIPMT();
3285+ CUMIPMT.apply(this, []);
3286 }, ERRORS.NA_ERROR);
3287 catchAndAssertEquals(function() {
3288- CUMIPMT(0.12, 12, 100, 1, 5, true, 55);
3289+ CUMIPMT.apply(this, [0.12, 12, 100, 1, 5, true, 55]);
3290 }, ERRORS.NA_ERROR);
3291 catchAndAssertEquals(function() {
3292- CUMIPMT(0.12, 12, 100, 1, 5);
3293+ CUMIPMT.apply(this, [0.12, 12, 100, 1, 5]);
3294 }, ERRORS.NA_ERROR);
3295 });
3296
3297@@ -131,10 +131,10 @@ test("DDB", function(){
3298 assertEquals(DDB(100, 50, 10, 2, 2.25), 17.4375);
3299 assertEquals(DDB(100, [50], 10, 2, "2.25"), 17.4375);
3300 catchAndAssertEquals(function() {
3301- DDB(100, 50, 10, 12, 2.25);
3302+ DDB.apply(this, [100, 50, 10, 12, 2.25]);
3303 }, ERRORS.NUM_ERROR);
3304 catchAndAssertEquals(function() {
3305- DDB(100, -50, 10, 2, 12);
3306+ DDB.apply(this, [100, -50, 10, 2, 12]);
3307 }, ERRORS.NUM_ERROR);
3308 });
3309
3310@@ -154,10 +154,10 @@ test("DOLLAR", function(){
3311 assertEquals(DOLLAR(31111.41592653589793, -4), 30000);
3312 assertEquals(DOLLAR(31111.41592653589793, -2), 31100);
3313 catchAndAssertEquals(function() {
3314- DOLLAR();
3315+ DOLLAR.apply(this, []);
3316 }, ERRORS.NA_ERROR);
3317 catchAndAssertEquals(function() {
3318- DOLLAR(3.1, 1, 1);
3319+ DOLLAR.apply(this, [3.1, 1, 1]);
3320 }, ERRORS.NA_ERROR);
3321 });
3322
3323@@ -180,13 +180,13 @@ test("DOLLARDE", function(){
3324 DOLLARDE(100, 0.99);
3325 }, ERRORS.DIV_ZERO_ERROR);
3326 catchAndAssertEquals(function() {
3327- DOLLARDE();
3328+ DOLLARDE.apply(this, []);
3329 }, ERRORS.NA_ERROR);
3330 catchAndAssertEquals(function() {
3331- DOLLARDE(3.1);
3332+ DOLLARDE.apply(this, [3.1]);
3333 }, ERRORS.NA_ERROR);
3334 catchAndAssertEquals(function() {
3335- DOLLARDE(3.1, 32, 22);
3336+ DOLLARDE.apply(this, [3.1, 32, 22]);
3337 }, ERRORS.NA_ERROR);
3338 });
3339
3340@@ -209,13 +209,13 @@ test("DOLLARFR", function(){
3341 DOLLARFR(100, 0.99);
3342 }, ERRORS.DIV_ZERO_ERROR);
3343 catchAndAssertEquals(function() {
3344- DOLLARFR();
3345+ DOLLARFR.apply(this, []);
3346 }, ERRORS.NA_ERROR);
3347 catchAndAssertEquals(function() {
3348- DOLLARFR(3.1);
3349+ DOLLARFR.apply(this, [3.1]);
3350 }, ERRORS.NA_ERROR);
3351 catchAndAssertEquals(function() {
3352- DOLLARFR(3.1, 32, 22);
3353+ DOLLARFR.apply(this, [3.1, 32, 22]);
3354 }, ERRORS.NA_ERROR);
3355 });
3356
3357@@ -227,10 +227,10 @@ test("EFFECT", function(){
3358 assertEquals(EFFECT("100000", 12.999), 1.123182670038387e+47);
3359 assertEquals(EFFECT([100000], [12.999]), 1.123182670038387e+47);
3360 catchAndAssertEquals(function() {
3361- EFFECT();
3362+ EFFECT.apply(this, []);
3363 }, ERRORS.NA_ERROR);
3364 catchAndAssertEquals(function() {
3365- EFFECT(0.99);
3366+ EFFECT.apply(this, [0.99]);
3367 }, ERRORS.NA_ERROR);
3368 catchAndAssertEquals(function() {
3369 EFFECT(-0.99, 12);
3370diff --git a/tests/Formulas/LogicalTest.ts b/tests/Formulas/LogicalTest.ts
3371index 37e47c8..672266f 100644
3372--- a/tests/Formulas/LogicalTest.ts
3373+++ b/tests/Formulas/LogicalTest.ts
3374@@ -25,7 +25,7 @@ test("AND", function(){
3375 AND(1, "");
3376 }, ERRORS.VALUE_ERROR);
3377 catchAndAssertEquals(function() {
3378- AND();
3379+ AND.apply(this, []);
3380 }, ERRORS.NA_ERROR);
3381 catchAndAssertEquals(function() {
3382 AND(1, "str");
3383@@ -49,21 +49,20 @@ test("EXACT", function(){
3384 assertEquals(EXACT([10], [10]), true);
3385 assertEquals(EXACT(["str"], [10, 22]), false);
3386 catchAndAssertEquals(function() {
3387- EXACT([], []);
3388+ EXACT.apply(this, [[], []]);
3389 }, ERRORS.REF_ERROR);
3390 catchAndAssertEquals(function() {
3391- EXACT([]);
3392+ EXACT.apply(this, [[]]);
3393 }, ERRORS.NA_ERROR);
3394 catchAndAssertEquals(function() {
3395- EXACT("m");
3396+ EXACT.apply(this, ["m"]);
3397 }, ERRORS.NA_ERROR);
3398 catchAndAssertEquals(function() {
3399- EXACT(10, 10, 10);
3400+ EXACT.apply(this, [10, 10, 10]);
3401 }, ERRORS.NA_ERROR);
3402 catchAndAssertEquals(function() {
3403- EXACT(false);
3404+ EXACT.apply(this, [false]);
3405 }, ERRORS.NA_ERROR);
3406-
3407 });
3408
3409
3410@@ -115,10 +114,10 @@ test("NOT", function(){
3411 NOT("1.2");
3412 }, ERRORS.VALUE_ERROR);
3413 catchAndAssertEquals(function() {
3414- NOT();
3415+ NOT.apply(this, []);
3416 }, ERRORS.NA_ERROR);
3417 catchAndAssertEquals(function() {
3418- NOT(false, false);
3419+ NOT.apply(this, [false, false]);
3420 }, ERRORS.NA_ERROR);
3421 });
3422
3423@@ -144,7 +143,7 @@ test("OR", function(){
3424 OR(false, "1.1");
3425 }, ERRORS.VALUE_ERROR);
3426 catchAndAssertEquals(function() {
3427- OR();
3428+ OR.apply(this, []);
3429 }, ERRORS.NA_ERROR);
3430 });
3431
3432diff --git a/tests/Formulas/MathTest.ts b/tests/Formulas/MathTest.ts
3433index bd10cdb..52a5b4a 100644
3434--- a/tests/Formulas/MathTest.ts
3435+++ b/tests/Formulas/MathTest.ts
3436@@ -66,10 +66,10 @@ test("ABS", function(){
3437 assertEquals(ABS(false), 0);
3438 assertEquals(ABS("-44"), 44);
3439 catchAndAssertEquals(function() {
3440- ABS();
3441+ ABS.apply(this, []);
3442 }, ERRORS.NA_ERROR);
3443 catchAndAssertEquals(function() {
3444- ABS("str");
3445+ ABS.apply(this, ["str"]);
3446 }, ERRORS.VALUE_ERROR);
3447 });
3448
3449@@ -86,6 +86,9 @@ test("ACOS", function(){
3450 catchAndAssertEquals(function() {
3451 ACOS(2);
3452 }, ERRORS.NUM_ERROR);
3453+ catchAndAssertEquals(function() {
3454+ ACOS.apply(this, []);
3455+ }, ERRORS.NA_ERROR);
3456 });
3457
3458
3459@@ -102,6 +105,9 @@ test("ACOSH", function(){
3460 catchAndAssertEquals(function() {
3461 ACOSH(false);
3462 }, ERRORS.NUM_ERROR);
3463+ catchAndAssertEquals(function() {
3464+ ACOSH.apply(this, []);
3465+ }, ERRORS.NA_ERROR);
3466 });
3467
3468
3469@@ -118,6 +124,9 @@ test("ACOTH", function(){
3470 catchAndAssertEquals(function() {
3471 ACOTH(false);
3472 }, ERRORS.NUM_ERROR);
3473+ catchAndAssertEquals(function() {
3474+ ACOTH.apply(this, []);
3475+ }, ERRORS.NA_ERROR);
3476 });
3477
3478
3479@@ -132,6 +141,9 @@ test("ASIN", function(){
3480 catchAndAssertEquals(function() {
3481 ASIN("str");
3482 }, ERRORS.VALUE_ERROR);
3483+ catchAndAssertEquals(function() {
3484+ ASIN.apply(this, []);
3485+ }, ERRORS.NA_ERROR);
3486 });
3487
3488
3489@@ -144,6 +156,9 @@ test("ASINH", function(){
3490 catchAndAssertEquals(function() {
3491 ASINH("str");
3492 }, ERRORS.VALUE_ERROR);
3493+ catchAndAssertEquals(function() {
3494+ ASINH.apply(this, []);
3495+ }, ERRORS.NA_ERROR);
3496 });
3497
3498
3499@@ -154,8 +169,11 @@ test("ATAN", function(){
3500 assertEquals(ATAN(false), 0);
3501 assertEquals(ATAN(true), 0.7853981633974483);
3502 catchAndAssertEquals(function() {
3503- ASINH("str");
3504+ ATAN("str");
3505 }, ERRORS.VALUE_ERROR);
3506+ catchAndAssertEquals(function() {
3507+ ATAN.apply(this, []);
3508+ }, ERRORS.NA_ERROR);
3509 });
3510
3511
3512@@ -173,6 +191,9 @@ test("ATAN2", function(){
3513 catchAndAssertEquals(function() {
3514 ATAN2("str", false);
3515 }, ERRORS.VALUE_ERROR);
3516+ catchAndAssertEquals(function() {
3517+ ATAN2.apply(this, []);
3518+ }, ERRORS.NA_ERROR);
3519 });
3520
3521
3522@@ -206,10 +227,10 @@ test("CEILING", function(){
3523 CEILING(10, 0);
3524 }, ERRORS.DIV_ZERO_ERROR);
3525 catchAndAssertEquals(function() {
3526- CEILING(10, 1, 2);
3527+ CEILING.apply(this, [10, 1, 2]);
3528 }, ERRORS.NA_ERROR);
3529 catchAndAssertEquals(function() {
3530- CEILING();
3531+ CEILING.apply(this, []);
3532 }, ERRORS.NA_ERROR);
3533 });
3534
3535@@ -232,13 +253,13 @@ test("COMBIN", function(){
3536 COMBIN(0, 1);
3537 }, ERRORS.NUM_ERROR);
3538 catchAndAssertEquals(function() {
3539- COMBIN();
3540+ COMBIN.apply(this, []);
3541 }, ERRORS.NA_ERROR);
3542 catchAndAssertEquals(function() {
3543- COMBIN(4);
3544+ COMBIN.apply(this, [4]);
3545 }, ERRORS.NA_ERROR);
3546 catchAndAssertEquals(function() {
3547- COMBIN(4, 2, 66);
3548+ COMBIN.apply(this, [4, 2, 66]);
3549 }, ERRORS.NA_ERROR);
3550 });
3551
3552@@ -254,10 +275,10 @@ test("COS", function(){
3553 COS("str");
3554 }, ERRORS.VALUE_ERROR);
3555 catchAndAssertEquals(function() {
3556- COS();
3557+ COS.apply(this, []);
3558 }, ERRORS.NA_ERROR);
3559 catchAndAssertEquals(function() {
3560- COS(1, 1);
3561+ COS.apply(this, [1, 1]);
3562 }, ERRORS.NA_ERROR);
3563 assertEquals(COS([0, "str"]), 1);
3564 });
3565@@ -270,16 +291,16 @@ test("COSH", function(){
3566 assertEquals(COSH(0), 1);
3567 assertEquals(COSH(true), 1.5430806348152437);
3568 assertEquals(COSH(""), 1);
3569+ assertEquals(COSH([0, "str"]), 1);
3570 catchAndAssertEquals(function() {
3571 COSH("str");
3572 }, ERRORS.VALUE_ERROR);
3573 catchAndAssertEquals(function() {
3574- COSH();
3575+ COSH.apply(this, []);
3576 }, ERRORS.NA_ERROR);
3577 catchAndAssertEquals(function() {
3578- COSH(1, 1);
3579+ COSH.apply(this, [1, 1]);
3580 }, ERRORS.NA_ERROR);
3581- assertEquals(COSH([0, "str"]), 1);
3582 });
3583
3584
3585@@ -301,10 +322,10 @@ test("COT", function(){
3586 COT("str");
3587 }, ERRORS.VALUE_ERROR);
3588 catchAndAssertEquals(function() {
3589- COT();
3590+ COT.apply(this, []);
3591 }, ERRORS.NA_ERROR);
3592 catchAndAssertEquals(function() {
3593- COT(1, 1);
3594+ COT.apply(this, [1, 1]);
3595 }, ERRORS.NA_ERROR);
3596 });
3597
3598@@ -328,10 +349,10 @@ test("COTH", function(){
3599 COTH("str");
3600 }, ERRORS.VALUE_ERROR);
3601 catchAndAssertEquals(function() {
3602- COTH();
3603+ COTH.apply(this, []);
3604 }, ERRORS.NA_ERROR);
3605 catchAndAssertEquals(function() {
3606- COTH(1, 1);
3607+ COTH.apply(this, [1, 1]);
3608 }, ERRORS.NA_ERROR);
3609 });
3610
3611@@ -373,13 +394,13 @@ test("COUNTIF", function(){
3612 assertEquals(COUNTIF([1, 5, 5, 5, 10, 5], "=$10"), 1);
3613 assertEquals(COUNTIF([1, 5, 5, 5, 10, 5], "= $ 10"), 1);
3614 catchAndAssertEquals(function() {
3615- COUNTIF([0, 1, 0, 1]);
3616+ COUNTIF.apply(this, [[0, 1, 0, 1]]);
3617 }, ERRORS.NA_ERROR);
3618 catchAndAssertEquals(function() {
3619- COUNTIF();
3620+ COUNTIF.apply(this, []);
3621 }, ERRORS.NA_ERROR);
3622 catchAndAssertEquals(function() {
3623- COUNTIF([], "=1", []);
3624+ COUNTIF.apply(this, [[], "=1", []]);
3625 }, ERRORS.NA_ERROR);
3626 });
3627
3628@@ -438,7 +459,7 @@ test("COUNTUNIQUE", function(){
3629 assertEquals(COUNTUNIQUE(["", " ", [""], []]), 2);
3630 assertEquals(COUNTUNIQUE([[""], []]), 1);
3631 catchAndAssertEquals(function() {
3632- COUNTUNIQUE();
3633+ COUNTUNIQUE.apply(this, []);
3634 }, ERRORS.NA_ERROR);
3635 });
3636
3637@@ -454,10 +475,10 @@ test("DEGREES", function(){
3638 DEGREES("str");
3639 }, ERRORS.VALUE_ERROR);
3640 catchAndAssertEquals(function() {
3641- DEGREES();
3642+ DEGREES.apply(this, []);
3643 }, ERRORS.NA_ERROR);
3644 catchAndAssertEquals(function() {
3645- DEGREES(10, 10);
3646+ DEGREES.apply(this, [10, 10]);
3647 }, ERRORS.NA_ERROR);
3648 });
3649
3650@@ -470,7 +491,7 @@ test("ERF", function(){
3651 assertEquals(ERF(true), 0.8427007929497149);
3652 assertEquals(ERF(false), 1.1102230246251565e-16);
3653 catchAndAssertEquals(function() {
3654- ERF();
3655+ ERF.apply(this, []);
3656 }, ERRORS.NA_ERROR);
3657 catchAndAssertEquals(function() {
3658 ERF([]);
3659@@ -488,7 +509,7 @@ test("ERFC", function(){
3660 assertEquals(ERFC(-1), 1.842700792949715);
3661 assertEquals(ERFC(-10), 2);
3662 catchAndAssertEquals(function() {
3663- ERFC();
3664+ ERFC.apply(this, []);
3665 }, ERRORS.NA_ERROR);
3666 catchAndAssertEquals(function() {
3667 ERFC([]);
3668@@ -506,10 +527,10 @@ test("EVEN", function(){
3669 assertEquals(EVEN([11, 22]), 12);
3670 assertEquals(EVEN([10, 22, "str"]), 10);
3671 catchAndAssertEquals(function() {
3672- EVEN();
3673+ EVEN.apply(this, []);
3674 }, ERRORS.NA_ERROR);
3675 catchAndAssertEquals(function() {
3676- EVEN(1, 2, 3);
3677+ EVEN.apply(this, [1, 2, 3]);
3678 }, ERRORS.NA_ERROR);
3679 catchAndAssertEquals(function() {
3680 EVEN("str");
3681@@ -532,10 +553,10 @@ test("FLOOR", function(){
3682 FLOOR(10, 0);
3683 }, ERRORS.DIV_ZERO_ERROR);
3684 catchAndAssertEquals(function() {
3685- FLOOR(10, 1, 2);
3686+ FLOOR.apply(this, [10, 1, 2]);
3687 }, ERRORS.NA_ERROR);
3688 catchAndAssertEquals(function() {
3689- FLOOR();
3690+ FLOOR.apply(this, []);
3691 }, ERRORS.NA_ERROR);
3692 });
3693
3694@@ -566,10 +587,10 @@ test("INT", function(){
3695 assertEquals(INT(""), 0);
3696 assertEquals(INT([1.1, "str"]), 1);
3697 catchAndAssertEquals(function() {
3698- INT(100, 10);
3699+ INT.apply(this, [100, 10]);
3700 }, ERRORS.NA_ERROR);
3701 catchAndAssertEquals(function() {
3702- INT();
3703+ INT.apply(this, []);
3704 }, ERRORS.NA_ERROR);
3705 catchAndAssertEquals(function() {
3706 INT("str");
3707@@ -585,10 +606,10 @@ test("ISEVEN", function(){
3708 assertEquals(ISEVEN(true), false);
3709 assertEquals(ISEVEN([4]), true);
3710 catchAndAssertEquals(function() {
3711- ISEVEN(100, 10);
3712+ ISEVEN.apply(this, [100, 10]);
3713 }, ERRORS.NA_ERROR);
3714 catchAndAssertEquals(function() {
3715- ISEVEN();
3716+ ISEVEN.apply(this, []);
3717 }, ERRORS.NA_ERROR);
3718 catchAndAssertEquals(function() {
3719 ISEVEN("");
3720@@ -604,10 +625,10 @@ test("ISODD", function(){
3721 assertEquals(ISODD(true), true);
3722 assertEquals(ISODD([4]), false);
3723 catchAndAssertEquals(function() {
3724- ISODD(100, 10);
3725+ ISODD.apply(this, [100, 10]);
3726 }, ERRORS.NA_ERROR);
3727 catchAndAssertEquals(function() {
3728- ISODD();
3729+ ISODD.apply(this, []);
3730 }, ERRORS.NA_ERROR);
3731 catchAndAssertEquals(function() {
3732 ISODD("");
3733@@ -627,24 +648,21 @@ test("LN", function(){
3734 LN("str");
3735 }, ERRORS.VALUE_ERROR);
3736 catchAndAssertEquals(function() {
3737- LN();
3738+ LN.apply(this, []);
3739 }, ERRORS.NA_ERROR);
3740 catchAndAssertEquals(function() {
3741- LN(10, 10);
3742+ LN.apply(this, [10, 10]);
3743 }, ERRORS.NA_ERROR);
3744 });
3745
3746
3747 test("LOG", function(){
3748 assertEquals(LOG(256, 2), 8);
3749- assertEquals(LOG(100), 2);
3750- assertEquals(LOG(100), 2);
3751+ assertEquals(LOG(100, 10), 2);
3752 assertEquals(LOG(256, 10), 2.408239965311849);
3753- assertEquals(LOG(256), 2.408239965311849);
3754- assertEquals(LOG("100"), 2);
3755 assertEquals(LOG(1, 2), 0);
3756 catchAndAssertEquals(function() {
3757- LOG("str");
3758+ LOG("str", 10);
3759 }, ERRORS.VALUE_ERROR);
3760 catchAndAssertEquals(function() {
3761 LOG(256, 0);
3762@@ -658,6 +676,9 @@ test("LOG", function(){
3763 catchAndAssertEquals(function() {
3764 LOG(256, true);
3765 }, ERRORS.DIV_ZERO_ERROR);
3766+ catchAndAssertEquals(function() {
3767+ LOG.apply(this, [10]);
3768+ }, ERRORS.NA_ERROR);
3769 });
3770
3771
3772@@ -676,27 +697,30 @@ test("LOG10", function(){
3773 LOG10("str");
3774 }, ERRORS.VALUE_ERROR);
3775 catchAndAssertEquals(function() {
3776- LOG10();
3777+ LOG10.apply(this, []);
3778 }, ERRORS.NA_ERROR);
3779 catchAndAssertEquals(function() {
3780- LOG10(10, 10);
3781+ LOG10.apply(this, [10, 10]);
3782 }, ERRORS.NA_ERROR);
3783 });
3784
3785
3786 test("MOD", function(){
3787 assertEquals(MOD(10, 3), 1);
3788+ assertEquals(MOD(10, "3"), 1);
3789+ assertEquals(MOD(10.1, 3), 1.0999999999999996);
3790+ assertEquals(MOD(10, 3.1), 0.6999999999999997);
3791 catchAndAssertEquals(function() {
3792- MOD(10, 3, 10);
3793+ MOD.apply(this, [10, 3, 10]);
3794 }, ERRORS.NA_ERROR);
3795 catchAndAssertEquals(function() {
3796- MOD([10, 3]);
3797+ MOD.apply(this, [[10, 3]]);
3798 }, ERRORS.NA_ERROR);
3799 catchAndAssertEquals(function() {
3800 MOD(0, 0);
3801 }, ERRORS.DIV_ZERO_ERROR);
3802 catchAndAssertEquals(function() {
3803- MOD(10);
3804+ MOD.apply(this, [10]);
3805 }, ERRORS.NA_ERROR);
3806 catchAndAssertEquals(function() {
3807 MOD(10, false);
3808@@ -707,9 +731,6 @@ test("MOD", function(){
3809 catchAndAssertEquals(function() {
3810 MOD(10, "str");
3811 }, ERRORS.VALUE_ERROR);
3812- assertEquals(MOD(10, "3"), 1);
3813- assertEquals(MOD(10.1, 3), 1.0999999999999996);
3814- assertEquals(MOD(10, 3.1), 0.6999999999999997);
3815 });
3816
3817
3818@@ -723,10 +744,10 @@ test("ODD", function(){
3819 assertEquals(ODD([10, 22]), 11);
3820 assertEquals(ODD([10, 22, "str"]), 11);
3821 catchAndAssertEquals(function() {
3822- ODD();
3823+ ODD.apply(this, []);
3824 }, ERRORS.NA_ERROR);
3825 catchAndAssertEquals(function() {
3826- ODD(1, 2, 3);
3827+ ODD.apply(this, [1, 2, 3]);
3828 }, ERRORS.NA_ERROR);
3829 catchAndAssertEquals(function() {
3830 ODD("str");
3831@@ -736,6 +757,9 @@ test("ODD", function(){
3832
3833 test("PI", function(){
3834 assertEquals(PI(), 3.141592653589793);
3835+ catchAndAssertEquals(function() {
3836+ PI.apply(this, [1]);
3837+ }, ERRORS.NA_ERROR);
3838 });
3839
3840
3841@@ -749,13 +773,13 @@ test("POWER", function(){
3842 POWER(4, "str");
3843 }, ERRORS.VALUE_ERROR);
3844 catchAndAssertEquals(function() {
3845- POWER();
3846+ POWER.apply(this, []);
3847 }, ERRORS.NA_ERROR);
3848 catchAndAssertEquals(function() {
3849- POWER(4);
3850+ POWER.apply(this, [4]);
3851 }, ERRORS.NA_ERROR);
3852 catchAndAssertEquals(function() {
3853- POWER(4, 10, 22);
3854+ POWER.apply(this, [4, 10, 22]);
3855 }, ERRORS.NA_ERROR);
3856 });
3857
3858@@ -768,27 +792,25 @@ test("RADIANS", function(){
3859 RADIANS("str");
3860 }, ERRORS.VALUE_ERROR);
3861 catchAndAssertEquals(function() {
3862- RADIANS();
3863+ RADIANS.apply(this, []);
3864 }, ERRORS.NA_ERROR);
3865 catchAndAssertEquals(function() {
3866- RADIANS(4, 10);
3867+ RADIANS.apply(this, [4, 10]);
3868 }, ERRORS.NA_ERROR);
3869 });
3870
3871
3872-
3873 test("ROUND", function(){
3874 assertEquals(ROUND(99.44, 1), 99.4);
3875 assertEquals(ROUND(99.44, 0), 99);
3876 assertEquals(ROUND(99.4444444444444, 9), 99.444444444);
3877- assertEquals(ROUND(99.44), 99);
3878- assertEquals(ROUND("99.44"), 99);
3879+ assertEquals(ROUND("99.44", 0), 99);
3880 assertEquals(ROUND([99.44, 22.222], [1, 4]), 99.4);
3881 catchAndAssertEquals(function() {
3882- ROUND();
3883+ ROUND.apply(this, []);
3884 }, ERRORS.NA_ERROR);
3885 catchAndAssertEquals(function() {
3886- ROUND(99.44, 1, 44);
3887+ ROUND.apply(this, [99.44, 1, 44]);
3888 }, ERRORS.NA_ERROR);
3889 catchAndAssertEquals(function() {
3890 ROUND(99.999, "str");
3891@@ -804,10 +826,10 @@ test("ROUNDDOWN", function(){
3892 assertEquals(ROUNDDOWN("99.99"), 99);
3893 assertEquals(ROUNDDOWN([99.46666, 22.222], [1, 4]), 99.4);
3894 catchAndAssertEquals(function() {
3895- ROUNDDOWN();
3896+ ROUNDDOWN.apply(this, []);
3897 }, ERRORS.NA_ERROR);
3898 catchAndAssertEquals(function() {
3899- ROUNDDOWN(99.44, 1, 44);
3900+ ROUNDDOWN.apply(this, [99.44, 1, 44]);
3901 }, ERRORS.NA_ERROR);
3902 catchAndAssertEquals(function() {
3903 ROUNDDOWN(99.999, "str");
3904@@ -823,10 +845,10 @@ test("ROUNDUP", function(){
3905 assertEquals(ROUNDUP("99.99"), 100);
3906 assertEquals(ROUNDUP([99.46666, 22.222], [1, 4]), 99.5);
3907 catchAndAssertEquals(function() {
3908- ROUNDUP();
3909+ ROUNDUP.apply(this, []);
3910 }, ERRORS.NA_ERROR);
3911 catchAndAssertEquals(function() {
3912- ROUNDUP(99.44, 1, 44);
3913+ ROUNDUP.apply(this, [99.44, 1, 44]);
3914 }, ERRORS.NA_ERROR);
3915 catchAndAssertEquals(function() {
3916 ROUNDUP(99.999, "str");
3917@@ -849,6 +871,9 @@ test("SIN", function(){
3918 assertEquals(SIN([1]), 0.8414709848078965);
3919 assertEquals(SIN([[1]]), 0.8414709848078965);
3920 assertEquals(SIN([1, "str"]), 0.8414709848078965);
3921+ catchAndAssertEquals(function() {
3922+ SIN.apply(this, [1, 44]);
3923+ }, ERRORS.NA_ERROR);
3924 });
3925
3926
3927@@ -885,10 +910,10 @@ test("SQRT", function(){
3928 SQRT(-9);
3929 }, ERRORS.VALUE_ERROR);
3930 catchAndAssertEquals(function() {
3931- SQRT();
3932+ SQRT.apply(this, []);
3933 }, ERRORS.NA_ERROR);
3934 catchAndAssertEquals(function() {
3935- SQRT(4, 4);
3936+ SQRT.apply(this, [4, 4]);
3937 }, ERRORS.NA_ERROR);
3938 });
3939
3940@@ -907,10 +932,10 @@ test("SQRTPI", function(){
3941 SQRTPI(-1);
3942 }, ERRORS.NUM_ERROR);
3943 catchAndAssertEquals(function() {
3944- SQRTPI();
3945+ SQRTPI.apply(this, []);
3946 }, ERRORS.NA_ERROR);
3947 catchAndAssertEquals(function() {
3948- SQRTPI(4, 4);
3949+ SQRTPI.apply(this, [4, 4]);
3950 }, ERRORS.NA_ERROR);
3951 });
3952
3953@@ -972,13 +997,13 @@ test("SUMIF", function(){
3954 assertEquals(SUMIF(["mom", "pop", "dad", "etc", "mom"], "????", [1, 1, 1, 1, 1]), 0);
3955 assertEquals(SUMIF([0, 1, 0, 1], "=1", [1, 2, 4, 8]), 10);
3956 catchAndAssertEquals(function() {
3957- SUMIF([0, 1, 0, 1]);
3958+ SUMIF.apply(this, [[0, 1, 0, 1]]);
3959 }, ERRORS.NA_ERROR);
3960 catchAndAssertEquals(function() {
3961- SUMIF();
3962+ SUMIF.apply(this, []);
3963 }, ERRORS.NA_ERROR);
3964 catchAndAssertEquals(function() {
3965- SUMIF([], "=1", [], true);
3966+ SUMIF.apply(this, [[], "=1", [], true]);
3967 }, ERRORS.NA_ERROR);
3968 });
3969
3970@@ -1020,7 +1045,7 @@ test("SUMSQ", function(){
3971 SUMSQ([]);
3972 }, ERRORS.REF_ERROR);
3973 catchAndAssertEquals(function() {
3974- SUMSQ();
3975+ SUMSQ.apply(this, []);
3976 }, ERRORS.NA_ERROR);
3977 });
3978
3979@@ -1036,10 +1061,10 @@ test("SUMX2MY2", function(){
3980 SUMX2MY2([1,2,3],[4,5, []]);
3981 }, ERRORS.REF_ERROR);
3982 catchAndAssertEquals(function() {
3983- SUMX2MY2([1,2,3],[4,5]);
3984+ SUMX2MY2.apply(this, [[1,2,3],[4,5]]);
3985 }, ERRORS.NA_ERROR);
3986 catchAndAssertEquals(function() {
3987- SUMX2MY2();
3988+ SUMX2MY2.apply(this, []);
3989 }, ERRORS.NA_ERROR);
3990 });
3991
3992@@ -1055,10 +1080,10 @@ test("SUMX2PY2", function(){
3993 SUMX2PY2([1,2,3],[4,5, []]);
3994 }, ERRORS.REF_ERROR);
3995 catchAndAssertEquals(function() {
3996- SUMX2PY2([1,2,3],[4,5]);
3997+ SUMX2PY2.apply(this, [[1,2,3],[4,5]]);
3998 }, ERRORS.NA_ERROR);
3999 catchAndAssertEquals(function() {
4000- SUMX2PY2();
4001+ SUMX2PY2.apply(this, []);
4002 }, ERRORS.NA_ERROR);
4003 });
4004
4005@@ -1076,10 +1101,10 @@ test("TAN", function(){
4006 TAN("str");
4007 }, ERRORS.VALUE_ERROR);
4008 catchAndAssertEquals(function() {
4009- TAN();
4010+ TAN.apply(this, []);
4011 }, ERRORS.NA_ERROR);
4012 catchAndAssertEquals(function() {
4013- TAN(1, 1);
4014+ TAN.apply(this, [1, 1]);
4015 }, ERRORS.NA_ERROR);
4016 assertEquals(TAN([1, 44]), 1.5574077246549023);
4017 assertEquals(TAN([1, "str"]), 1.5574077246549023);
4018@@ -1099,10 +1124,10 @@ test("TANH", function(){
4019 TANH("str");
4020 }, ERRORS.VALUE_ERROR);
4021 catchAndAssertEquals(function() {
4022- TANH();
4023+ TANH.apply(this, []);
4024 }, ERRORS.NA_ERROR);
4025 catchAndAssertEquals(function() {
4026- TANH(1, 1);
4027+ TANH.apply(this, [1, 1]);
4028 }, ERRORS.NA_ERROR);
4029 assertEquals(TANH([1, 44]), 0.7615941559557649);
4030 assertEquals(TANH([1, "str"]), 0.7615941559557649);
4031@@ -1121,9 +1146,9 @@ test("TRUNC", function(){
4032 assertEquals(TRUNC(31111.41592653589793, -4), 30000);
4033 assertEquals(TRUNC(31111.41592653589793, -2), 31100);
4034 catchAndAssertEquals(function() {
4035- TRUNC();
4036+ TRUNC.apply(this, []);
4037 }, ERRORS.NA_ERROR);
4038 catchAndAssertEquals(function() {
4039- TRUNC(3.1, 1, 1);
4040+ TRUNC.apply(this, [3.1, 1, 1]);
4041 }, ERRORS.NA_ERROR);
4042 });
4043diff --git a/tests/Formulas/StatisticalTest.ts b/tests/Formulas/StatisticalTest.ts
4044index b9f2208..77df6ef 100644
4045--- a/tests/Formulas/StatisticalTest.ts
4046+++ b/tests/Formulas/StatisticalTest.ts
4047@@ -145,13 +145,13 @@ test("CORREL", function(){
4048 CORREL([9], [5]);
4049 }, ERRORS.DIV_ZERO_ERROR);
4050 catchAndAssertEquals(function() {
4051- CORREL();
4052+ CORREL.apply(this, []);
4053 }, ERRORS.NA_ERROR);
4054 catchAndAssertEquals(function() {
4055- CORREL([9, 5]);
4056+ CORREL.apply(this, [[9, 5]]);
4057 }, ERRORS.NA_ERROR);
4058 catchAndAssertEquals(function() {
4059- CORREL([9, 5],[10]);
4060+ CORREL.apply(this, [[9, 5],[10]]);
4061 }, ERRORS.NA_ERROR);
4062 });
4063
4064@@ -228,13 +228,13 @@ test("EXPONDIST", function(){
4065 EXPONDIST(4, 0.5, "1");
4066 }, ERRORS.VALUE_ERROR);
4067 catchAndAssertEquals(function() {
4068- EXPONDIST();
4069+ EXPONDIST.apply(this, []);
4070 }, ERRORS.NA_ERROR);
4071 catchAndAssertEquals(function() {
4072- EXPONDIST(4, 0.5);
4073+ EXPONDIST.apply(this, [4, 0.5]);
4074 }, ERRORS.NA_ERROR);
4075 catchAndAssertEquals(function() {
4076- EXPONDIST(4, 0.5, true, 1);
4077+ EXPONDIST.apply(this, [4, 0.5, true, 1]);
4078 }, ERRORS.NA_ERROR);
4079 });
4080
4081@@ -246,10 +246,10 @@ test("FINV", function(){
4082 assertEquals(FINV(["0.42"], [33, []], [5]), 1.303222112500911);
4083 assertEquals(FINV("0.42", 2, 3), 1.174597274485816);
4084 catchAndAssertEquals(function() {
4085- FINV();
4086+ FINV.apply(this, []);
4087 }, ERRORS.NA_ERROR);
4088 catchAndAssertEquals(function() {
4089- FINV(0.42, 2, 4, 4);
4090+ FINV.apply(this, [0.42, 2, 4, 4]);
4091 }, ERRORS.NA_ERROR);
4092 catchAndAssertEquals(function() {
4093 FINV(0.42, 2, []);
4094@@ -277,10 +277,10 @@ test("FISHER", function(){
4095 FISHER(-1);
4096 }, ERRORS.NUM_ERROR);
4097 catchAndAssertEquals(function() {
4098- FISHER();
4099+ FISHER.apply(this, []);
4100 }, ERRORS.NA_ERROR);
4101 catchAndAssertEquals(function() {
4102- FISHER(0.55, 0.1);
4103+ FISHER.apply(this, [0.55, 0.1]);
4104 }, ERRORS.NA_ERROR);
4105 });
4106
4107@@ -298,10 +298,10 @@ test("FISHERINV", function(){
4108 FISHER("str");
4109 }, ERRORS.VALUE_ERROR);
4110 catchAndAssertEquals(function() {
4111- FISHER();
4112+ FISHER.apply(this, []);
4113 }, ERRORS.NA_ERROR);
4114 catchAndAssertEquals(function() {
4115- FISHER(0.55, 0.1);
4116+ FISHER.apply(this, [0.55, 0.1]);
4117 }, ERRORS.NA_ERROR);
4118 });
4119
4120@@ -408,9 +408,9 @@ test("F.DIST", function(){
4121 FDIST$LEFTTAILED(-15.35, 7, 6, 1);
4122 }, ERRORS.NUM_ERROR);
4123 catchAndAssertEquals(function() {
4124- FDIST$LEFTTAILED(15.35, 7, 6);
4125+ FDIST$LEFTTAILED.apply(this, [15.35, 7, 6]);
4126 }, ERRORS.NA_ERROR);
4127 catchAndAssertEquals(function() {
4128- FDIST$LEFTTAILED();
4129+ FDIST$LEFTTAILED.apply(this, []);
4130 }, ERRORS.NA_ERROR);
4131 });
4132diff --git a/tests/Formulas/TextTest.ts b/tests/Formulas/TextTest.ts
4133index bc617da..7086557 100644
4134--- a/tests/Formulas/TextTest.ts
4135+++ b/tests/Formulas/TextTest.ts
4136@@ -26,7 +26,7 @@ test("SPLIT", function(){
4137 SPLIT([], "er");
4138 }, ERRORS.REF_ERROR);
4139 catchAndAssertEquals(function() {
4140- SPLIT("er", "er", true, 10);
4141+ SPLIT.apply(this, ["er", "er", true, 10]);
4142 }, ERRORS.NA_ERROR);
4143 });
4144
4145@@ -49,7 +49,7 @@ test("CHAR", function(){
4146 CHAR(0);
4147 }, ERRORS.NUM_ERROR);
4148 catchAndAssertEquals(function() {
4149- CHAR();
4150+ CHAR.apply(this, []);
4151 }, ERRORS.NA_ERROR);
4152 });
4153
4154@@ -61,17 +61,18 @@ test("CODE", function(){
4155 assertEquals(CODE('#'), 35);
4156 assertEquals(CODE(false), 70);
4157 assertEquals(CODE(true), 84);
4158+ assertEquals(CODE(['a']), 97);
4159+ assertEquals(CODE([['a'], 'p']), 97);
4160 catchAndAssertEquals(function() {
4161- CODE();
4162+ CODE.apply(this, []);
4163 }, ERRORS.NA_ERROR);
4164 catchAndAssertEquals(function() {
4165- CODE("a", "m");
4166+ CODE.apply(this, ["a", "m"]);
4167 }, ERRORS.NA_ERROR);
4168 catchAndAssertEquals(function() {
4169 CODE("");
4170 }, ERRORS.VALUE_ERROR);
4171- assertEquals(CODE(['a']), 97);
4172- assertEquals(CODE([['a'], 'p']), 97);
4173+
4174 });
4175
4176
4177@@ -84,7 +85,7 @@ test("CONCATENATE", function(){
4178 assertEquals(CONCATENATE([22, 14, "m", false]), "2214mFALSE");
4179 assertEquals(CONCATENATE([22, 14, ["m", false]]), "2214mFALSE");
4180 catchAndAssertEquals(function() {
4181- CONCATENATE();
4182+ CONCATENATE.apply(this, []);
4183 }, ERRORS.NA_ERROR);
4184 catchAndAssertEquals(function() {
4185 CONCATENATE("10", 4, false, []);
4186@@ -110,6 +111,12 @@ test("CONVERT", function(){
4187 assertEquals(CONVERT(10, "ton", "stone"), 1428.5714285714287);
4188 assertEquals(CONVERT(10, "tspm", "bushel"), 0.0014188796696394089);
4189 assertEquals(CONVERT(10, "c", "Wh"), 0.011622222222222223);
4190+ catchAndAssertEquals(function() {
4191+ CONVERT.apply(this, []);
4192+ }, ERRORS.NA_ERROR);
4193+ catchAndAssertEquals(function() {
4194+ CONVERT.apply(this, [5.1, "mm", "m", 10]);
4195+ }, ERRORS.NA_ERROR);
4196 });
4197
4198