OSDN Git Service

This closes #1792, support to update defined names reference when rename worksheet...
[excelize/excelize.git] / calc.go
1 // Copyright 2016 - 2024 The excelize Authors. All rights reserved. Use of
2 // this source code is governed by a BSD-style license that can be found in
3 // the LICENSE file.
4 //
5 // Package excelize providing a set of functions that allow you to write to and
6 // read from XLAM / XLSM / XLSX / XLTM / XLTX files. Supports reading and
7 // writing spreadsheet documents generated by Microsoft Excelâ„¢ 2007 and later.
8 // Supports complex components by high compatibility, and provided streaming
9 // API for generating or reading data from a worksheet with huge amounts of
10 // data. This library needs Go version 1.18 or later.
11
12 package excelize
13
14 import (
15         "bytes"
16         "container/list"
17         "errors"
18         "fmt"
19         "math"
20         "math/big"
21         "math/cmplx"
22         "math/rand"
23         "net/url"
24         "reflect"
25         "regexp"
26         "sort"
27         "strconv"
28         "strings"
29         "sync"
30         "time"
31         "unicode"
32         "unicode/utf8"
33         "unsafe"
34
35         "github.com/xuri/efp"
36         "golang.org/x/text/language"
37         "golang.org/x/text/message"
38 )
39
40 const (
41         // Excel formula errors
42         formulaErrorDIV         = "#DIV/0!"
43         formulaErrorNAME        = "#NAME?"
44         formulaErrorNA          = "#N/A"
45         formulaErrorNUM         = "#NUM!"
46         formulaErrorVALUE       = "#VALUE!"
47         formulaErrorREF         = "#REF!"
48         formulaErrorNULL        = "#NULL!"
49         formulaErrorSPILL       = "#SPILL!"
50         formulaErrorCALC        = "#CALC!"
51         formulaErrorGETTINGDATA = "#GETTING_DATA"
52         // Formula criteria condition enumeration
53         _ byte = iota
54         criteriaEq
55         criteriaLe
56         criteriaGe
57         criteriaNe
58         criteriaL
59         criteriaG
60         criteriaErr
61         criteriaRegexp
62
63         categoryWeightAndMass
64         categoryDistance
65         categoryTime
66         categoryPressure
67         categoryForce
68         categoryEnergy
69         categoryPower
70         categoryMagnetism
71         categoryTemperature
72         categoryVolumeAndLiquidMeasure
73         categoryArea
74         categoryInformation
75         categorySpeed
76
77         matchModeExact      = 0
78         matchModeMinGreater = 1
79         matchModeMaxLess    = -1
80         matchModeWildcard   = 2
81
82         searchModeLinear        = 1
83         searchModeReverseLinear = -1
84         searchModeAscBinary     = 2
85         searchModeDescBinary    = -2
86
87         maxFinancialIterations = 128
88         financialPrecision     = 1.0e-08
89         // Date and time format regular expressions
90         monthRe    = `((jan|january)|(feb|february)|(mar|march)|(apr|april)|(may)|(jun|june)|(jul|july)|(aug|august)|(sep|september)|(oct|october)|(nov|november)|(dec|december))`
91         df1        = `(([0-9])+)/(([0-9])+)/(([0-9])+)`
92         df2        = monthRe + ` (([0-9])+), (([0-9])+)`
93         df3        = `(([0-9])+)-(([0-9])+)-(([0-9])+)`
94         df4        = `(([0-9])+)-` + monthRe + `-(([0-9])+)`
95         datePrefix = `^((` + df1 + `|` + df2 + `|` + df3 + `|` + df4 + `) )?`
96         tfhh       = `(([0-9])+) (am|pm)`
97         tfhhmm     = `(([0-9])+):(([0-9])+)( (am|pm))?`
98         tfmmss     = `(([0-9])+):(([0-9])+\.([0-9])+)( (am|pm))?`
99         tfhhmmss   = `(([0-9])+):(([0-9])+):(([0-9])+(\.([0-9])+)?)( (am|pm))?`
100         timeSuffix = `( (` + tfhh + `|` + tfhhmm + `|` + tfmmss + `|` + tfhhmmss + `))?$`
101 )
102
103 var (
104         // tokenPriority defined basic arithmetic operator priority
105         tokenPriority = map[string]int{
106                 "^":  5,
107                 "*":  4,
108                 "/":  4,
109                 "+":  3,
110                 "-":  3,
111                 "&":  2,
112                 "=":  1,
113                 "<>": 1,
114                 "<":  1,
115                 "<=": 1,
116                 ">":  1,
117                 ">=": 1,
118         }
119         month2num = map[string]int{
120                 "january":   1,
121                 "february":  2,
122                 "march":     3,
123                 "april":     4,
124                 "may":       5,
125                 "june":      6,
126                 "july":      7,
127                 "august":    8,
128                 "september": 9,
129                 "october":   10,
130                 "november":  11,
131                 "december":  12,
132                 "jan":       1,
133                 "feb":       2,
134                 "mar":       3,
135                 "apr":       4,
136                 "jun":       6,
137                 "jul":       7,
138                 "aug":       8,
139                 "sep":       9,
140                 "oct":       10,
141                 "nov":       11,
142                 "dec":       12,
143         }
144         dateFormats = map[string]*regexp.Regexp{
145                 "mm/dd/yy":    regexp.MustCompile(`^` + df1 + timeSuffix),
146                 "mm dd, yy":   regexp.MustCompile(`^` + df2 + timeSuffix),
147                 "yy-mm-dd":    regexp.MustCompile(`^` + df3 + timeSuffix),
148                 "yy-mmStr-dd": regexp.MustCompile(`^` + df4 + timeSuffix),
149         }
150         timeFormats = map[string]*regexp.Regexp{
151                 "hh":       regexp.MustCompile(datePrefix + tfhh + `$`),
152                 "hh:mm":    regexp.MustCompile(datePrefix + tfhhmm + `$`),
153                 "mm:ss":    regexp.MustCompile(datePrefix + tfmmss + `$`),
154                 "hh:mm:ss": regexp.MustCompile(datePrefix + tfhhmmss + `$`),
155         }
156         dateOnlyFormats = []*regexp.Regexp{
157                 regexp.MustCompile(`^` + df1 + `$`),
158                 regexp.MustCompile(`^` + df2 + `$`),
159                 regexp.MustCompile(`^` + df3 + `$`),
160                 regexp.MustCompile(`^` + df4 + `$`),
161         }
162         addressFmtMaps = map[string]func(col, row int) (string, error){
163                 "1_TRUE": func(col, row int) (string, error) {
164                         return CoordinatesToCellName(col, row, true)
165                 },
166                 "1_FALSE": func(col, row int) (string, error) {
167                         return fmt.Sprintf("R%dC%d", row, col), nil
168                 },
169                 "2_TRUE": func(col, row int) (string, error) {
170                         column, err := ColumnNumberToName(col)
171                         if err != nil {
172                                 return "", err
173                         }
174                         return fmt.Sprintf("%s$%d", column, row), nil
175                 },
176                 "2_FALSE": func(col, row int) (string, error) {
177                         return fmt.Sprintf("R%dC[%d]", row, col), nil
178                 },
179                 "3_TRUE": func(col, row int) (string, error) {
180                         column, err := ColumnNumberToName(col)
181                         if err != nil {
182                                 return "", err
183                         }
184                         return fmt.Sprintf("$%s%d", column, row), nil
185                 },
186                 "3_FALSE": func(col, row int) (string, error) {
187                         return fmt.Sprintf("R[%d]C%d", row, col), nil
188                 },
189                 "4_TRUE": func(col, row int) (string, error) {
190                         return CoordinatesToCellName(col, row, false)
191                 },
192                 "4_FALSE": func(col, row int) (string, error) {
193                         return fmt.Sprintf("R[%d]C[%d]", row, col), nil
194                 },
195         }
196         formulaFormats = []*regexp.Regexp{
197                 regexp.MustCompile(`^(\d+)$`),
198                 regexp.MustCompile(`^=(.*)$`),
199                 regexp.MustCompile(`^<>(.*)$`),
200                 regexp.MustCompile(`^<=(.*)$`),
201                 regexp.MustCompile(`^>=(.*)$`),
202                 regexp.MustCompile(`^<(.*)$`),
203                 regexp.MustCompile(`^>(.*)$`),
204         }
205         formulaCriterias = []byte{
206                 criteriaEq,
207                 criteriaEq,
208                 criteriaNe,
209                 criteriaLe,
210                 criteriaGe,
211                 criteriaL,
212                 criteriaG,
213         }
214 )
215
216 // calcContext defines the formula execution context.
217 type calcContext struct {
218         mu                sync.Mutex
219         entry             string
220         maxCalcIterations uint
221         iterations        map[string]uint
222         iterationsCache   map[string]formulaArg
223 }
224
225 // cellRef defines the structure of a cell reference.
226 type cellRef struct {
227         Col   int
228         Row   int
229         Sheet string
230 }
231
232 // cellRef defines the structure of a cell range.
233 type cellRange struct {
234         From cellRef
235         To   cellRef
236 }
237
238 // formulaCriteria defined formula criteria parser result.
239 type formulaCriteria struct {
240         Type      byte
241         Condition formulaArg
242 }
243
244 // ArgType is the type of formula argument type.
245 type ArgType byte
246
247 // Formula argument types enumeration.
248 const (
249         ArgUnknown ArgType = iota
250         ArgNumber
251         ArgString
252         ArgList
253         ArgMatrix
254         ArgError
255         ArgEmpty
256 )
257
258 // formulaArg is the argument of a formula or function.
259 type formulaArg struct {
260         SheetName            string
261         Number               float64
262         String               string
263         List                 []formulaArg
264         Matrix               [][]formulaArg
265         Boolean              bool
266         Error                string
267         Type                 ArgType
268         cellRefs, cellRanges *list.List
269 }
270
271 // Value returns a string data type of the formula argument.
272 func (fa formulaArg) Value() (value string) {
273         switch fa.Type {
274         case ArgNumber:
275                 if fa.Boolean {
276                         if fa.Number == 0 {
277                                 return "FALSE"
278                         }
279                         return "TRUE"
280                 }
281                 return fmt.Sprintf("%g", fa.Number)
282         case ArgString:
283                 return fa.String
284         case ArgError:
285                 return fa.Error
286         }
287         return
288 }
289
290 // ToNumber returns a formula argument with number data type.
291 func (fa formulaArg) ToNumber() formulaArg {
292         var n float64
293         var err error
294         switch fa.Type {
295         case ArgString:
296                 n, err = strconv.ParseFloat(fa.String, 64)
297                 if err != nil {
298                         return newErrorFormulaArg(formulaErrorVALUE, err.Error())
299                 }
300         case ArgNumber:
301                 n = fa.Number
302         }
303         return newNumberFormulaArg(n)
304 }
305
306 // ToBool returns a formula argument with boolean data type.
307 func (fa formulaArg) ToBool() formulaArg {
308         var b bool
309         var err error
310         switch fa.Type {
311         case ArgString:
312                 b, err = strconv.ParseBool(fa.String)
313                 if err != nil {
314                         return newErrorFormulaArg(formulaErrorVALUE, err.Error())
315                 }
316         case ArgNumber:
317                 if fa.Number == 1 {
318                         b = true
319                 }
320         }
321         return newBoolFormulaArg(b)
322 }
323
324 // ToList returns a formula argument with array data type.
325 func (fa formulaArg) ToList() []formulaArg {
326         switch fa.Type {
327         case ArgMatrix:
328                 var args []formulaArg
329                 for _, row := range fa.Matrix {
330                         args = append(args, row...)
331                 }
332                 return args
333         case ArgList:
334                 return fa.List
335         case ArgNumber, ArgString, ArgError, ArgUnknown:
336                 return []formulaArg{fa}
337         }
338         return nil
339 }
340
341 // formulaFuncs is the type of the formula functions.
342 type formulaFuncs struct {
343         f           *File
344         ctx         *calcContext
345         sheet, cell string
346 }
347
348 // CalcCellValue provides a function to get calculated cell value. This feature
349 // is currently in working processing. Iterative calculation, implicit
350 // intersection, explicit intersection, array formula, table formula and some
351 // other formulas are not supported currently.
352 //
353 // Supported formula functions:
354 //
355 //      ABS
356 //      ACCRINT
357 //      ACCRINTM
358 //      ACOS
359 //      ACOSH
360 //      ACOT
361 //      ACOTH
362 //      ADDRESS
363 //      AGGREGATE
364 //      AMORDEGRC
365 //      AMORLINC
366 //      AND
367 //      ARABIC
368 //      ARRAYTOTEXT
369 //      ASIN
370 //      ASINH
371 //      ATAN
372 //      ATAN2
373 //      ATANH
374 //      AVEDEV
375 //      AVERAGE
376 //      AVERAGEA
377 //      AVERAGEIF
378 //      AVERAGEIFS
379 //      BASE
380 //      BESSELI
381 //      BESSELJ
382 //      BESSELK
383 //      BESSELY
384 //      BETA.DIST
385 //      BETA.INV
386 //      BETADIST
387 //      BETAINV
388 //      BIN2DEC
389 //      BIN2HEX
390 //      BIN2OCT
391 //      BINOM.DIST
392 //      BINOM.DIST.RANGE
393 //      BINOM.INV
394 //      BINOMDIST
395 //      BITAND
396 //      BITLSHIFT
397 //      BITOR
398 //      BITRSHIFT
399 //      BITXOR
400 //      CEILING
401 //      CEILING.MATH
402 //      CEILING.PRECISE
403 //      CHAR
404 //      CHIDIST
405 //      CHIINV
406 //      CHISQ.DIST
407 //      CHISQ.DIST.RT
408 //      CHISQ.INV
409 //      CHISQ.INV.RT
410 //      CHISQ.TEST
411 //      CHITEST
412 //      CHOOSE
413 //      CLEAN
414 //      CODE
415 //      COLUMN
416 //      COLUMNS
417 //      COMBIN
418 //      COMBINA
419 //      COMPLEX
420 //      CONCAT
421 //      CONCATENATE
422 //      CONFIDENCE
423 //      CONFIDENCE.NORM
424 //      CONFIDENCE.T
425 //      CONVERT
426 //      CORREL
427 //      COS
428 //      COSH
429 //      COT
430 //      COTH
431 //      COUNT
432 //      COUNTA
433 //      COUNTBLANK
434 //      COUNTIF
435 //      COUNTIFS
436 //      COUPDAYBS
437 //      COUPDAYS
438 //      COUPDAYSNC
439 //      COUPNCD
440 //      COUPNUM
441 //      COUPPCD
442 //      COVAR
443 //      COVARIANCE.P
444 //      COVARIANCE.S
445 //      CRITBINOM
446 //      CSC
447 //      CSCH
448 //      CUMIPMT
449 //      CUMPRINC
450 //      DATE
451 //      DATEDIF
452 //      DATEVALUE
453 //      DAVERAGE
454 //      DAY
455 //      DAYS
456 //      DAYS360
457 //      DB
458 //      DBCS
459 //      DCOUNT
460 //      DCOUNTA
461 //      DDB
462 //      DEC2BIN
463 //      DEC2HEX
464 //      DEC2OCT
465 //      DECIMAL
466 //      DEGREES
467 //      DELTA
468 //      DEVSQ
469 //      DGET
470 //      DISC
471 //      DMAX
472 //      DMIN
473 //      DOLLARDE
474 //      DOLLARFR
475 //      DPRODUCT
476 //      DSTDEV
477 //      DSTDEVP
478 //      DSUM
479 //      DURATION
480 //      DVAR
481 //      DVARP
482 //      EDATE
483 //      EFFECT
484 //      ENCODEURL
485 //      EOMONTH
486 //      ERF
487 //      ERF.PRECISE
488 //      ERFC
489 //      ERFC.PRECISE
490 //      ERROR.TYPE
491 //      EUROCONVERT
492 //      EVEN
493 //      EXACT
494 //      EXP
495 //      EXPON.DIST
496 //      EXPONDIST
497 //      F.DIST
498 //      F.DIST.RT
499 //      F.INV
500 //      F.INV.RT
501 //      F.TEST
502 //      FACT
503 //      FACTDOUBLE
504 //      FALSE
505 //      FDIST
506 //      FIND
507 //      FINDB
508 //      FINV
509 //      FISHER
510 //      FISHERINV
511 //      FIXED
512 //      FLOOR
513 //      FLOOR.MATH
514 //      FLOOR.PRECISE
515 //      FORECAST
516 //      FORECAST.LINEAR
517 //      FORMULATEXT
518 //      FREQUENCY
519 //      FTEST
520 //      FV
521 //      FVSCHEDULE
522 //      GAMMA
523 //      GAMMA.DIST
524 //      GAMMA.INV
525 //      GAMMADIST
526 //      GAMMAINV
527 //      GAMMALN
528 //      GAMMALN.PRECISE
529 //      GAUSS
530 //      GCD
531 //      GEOMEAN
532 //      GESTEP
533 //      GROWTH
534 //      HARMEAN
535 //      HEX2BIN
536 //      HEX2DEC
537 //      HEX2OCT
538 //      HLOOKUP
539 //      HOUR
540 //      HYPERLINK
541 //      HYPGEOM.DIST
542 //      HYPGEOMDIST
543 //      IF
544 //      IFERROR
545 //      IFNA
546 //      IFS
547 //      IMABS
548 //      IMAGINARY
549 //      IMARGUMENT
550 //      IMCONJUGATE
551 //      IMCOS
552 //      IMCOSH
553 //      IMCOT
554 //      IMCSC
555 //      IMCSCH
556 //      IMDIV
557 //      IMEXP
558 //      IMLN
559 //      IMLOG10
560 //      IMLOG2
561 //      IMPOWER
562 //      IMPRODUCT
563 //      IMREAL
564 //      IMSEC
565 //      IMSECH
566 //      IMSIN
567 //      IMSINH
568 //      IMSQRT
569 //      IMSUB
570 //      IMSUM
571 //      IMTAN
572 //      INDEX
573 //      INDIRECT
574 //      INT
575 //      INTERCEPT
576 //      INTRATE
577 //      IPMT
578 //      IRR
579 //      ISBLANK
580 //      ISERR
581 //      ISERROR
582 //      ISEVEN
583 //      ISFORMULA
584 //      ISLOGICAL
585 //      ISNA
586 //      ISNONTEXT
587 //      ISNUMBER
588 //      ISO.CEILING
589 //      ISODD
590 //      ISOWEEKNUM
591 //      ISPMT
592 //      ISREF
593 //      ISTEXT
594 //      KURT
595 //      LARGE
596 //      LCM
597 //      LEFT
598 //      LEFTB
599 //      LEN
600 //      LENB
601 //      LN
602 //      LOG
603 //      LOG10
604 //      LOGINV
605 //      LOGNORM.DIST
606 //      LOGNORM.INV
607 //      LOGNORMDIST
608 //      LOOKUP
609 //      LOWER
610 //      MATCH
611 //      MAX
612 //      MAXA
613 //      MAXIFS
614 //      MDETERM
615 //      MDURATION
616 //      MEDIAN
617 //      MID
618 //      MIDB
619 //      MIN
620 //      MINA
621 //      MINIFS
622 //      MINUTE
623 //      MINVERSE
624 //      MIRR
625 //      MMULT
626 //      MOD
627 //      MODE
628 //      MODE.MULT
629 //      MODE.SNGL
630 //      MONTH
631 //      MROUND
632 //      MULTINOMIAL
633 //      MUNIT
634 //      N
635 //      NA
636 //      NEGBINOM.DIST
637 //      NEGBINOMDIST
638 //      NETWORKDAYS
639 //      NETWORKDAYS.INTL
640 //      NOMINAL
641 //      NORM.DIST
642 //      NORM.INV
643 //      NORM.S.DIST
644 //      NORM.S.INV
645 //      NORMDIST
646 //      NORMINV
647 //      NORMSDIST
648 //      NORMSINV
649 //      NOT
650 //      NOW
651 //      NPER
652 //      NPV
653 //      OCT2BIN
654 //      OCT2DEC
655 //      OCT2HEX
656 //      ODD
657 //      ODDFPRICE
658 //      ODDFYIELD
659 //      ODDLPRICE
660 //      ODDLYIELD
661 //      OR
662 //      PDURATION
663 //      PEARSON
664 //      PERCENTILE
665 //      PERCENTILE.EXC
666 //      PERCENTILE.INC
667 //      PERCENTRANK
668 //      PERCENTRANK.EXC
669 //      PERCENTRANK.INC
670 //      PERMUT
671 //      PERMUTATIONA
672 //      PHI
673 //      PI
674 //      PMT
675 //      POISSON
676 //      POISSON.DIST
677 //      POWER
678 //      PPMT
679 //      PRICE
680 //      PRICEDISC
681 //      PRICEMAT
682 //      PROB
683 //      PRODUCT
684 //      PROPER
685 //      PV
686 //      QUARTILE
687 //      QUARTILE.EXC
688 //      QUARTILE.INC
689 //      QUOTIENT
690 //      RADIANS
691 //      RAND
692 //      RANDBETWEEN
693 //      RANK
694 //      RANK.EQ
695 //      RATE
696 //      RECEIVED
697 //      REPLACE
698 //      REPLACEB
699 //      REPT
700 //      RIGHT
701 //      RIGHTB
702 //      ROMAN
703 //      ROUND
704 //      ROUNDDOWN
705 //      ROUNDUP
706 //      ROW
707 //      ROWS
708 //      RRI
709 //      RSQ
710 //      SEARCH
711 //      SEARCHB
712 //      SEC
713 //      SECH
714 //      SECOND
715 //      SERIESSUM
716 //      SHEET
717 //      SHEETS
718 //      SIGN
719 //      SIN
720 //      SINH
721 //      SKEW
722 //      SKEW.P
723 //      SLN
724 //      SLOPE
725 //      SMALL
726 //      SQRT
727 //      SQRTPI
728 //      STANDARDIZE
729 //      STDEV
730 //      STDEV.P
731 //      STDEV.S
732 //      STDEVA
733 //      STDEVP
734 //      STDEVPA
735 //      STEYX
736 //      SUBSTITUTE
737 //      SUBTOTAL
738 //      SUM
739 //      SUMIF
740 //      SUMIFS
741 //      SUMPRODUCT
742 //      SUMSQ
743 //      SUMX2MY2
744 //      SUMX2PY2
745 //      SUMXMY2
746 //      SWITCH
747 //      SYD
748 //      T
749 //      T.DIST
750 //      T.DIST.2T
751 //      T.DIST.RT
752 //      T.INV
753 //      T.INV.2T
754 //      T.TEST
755 //      TAN
756 //      TANH
757 //      TBILLEQ
758 //      TBILLPRICE
759 //      TBILLYIELD
760 //      TDIST
761 //      TEXT
762 //      TEXTAFTER
763 //      TEXTBEFORE
764 //      TEXTJOIN
765 //      TIME
766 //      TIMEVALUE
767 //      TINV
768 //      TODAY
769 //      TRANSPOSE
770 //      TREND
771 //      TRIM
772 //      TRIMMEAN
773 //      TRUE
774 //      TRUNC
775 //      TTEST
776 //      TYPE
777 //      UNICHAR
778 //      UNICODE
779 //      UPPER
780 //      VALUE
781 //      VALUETOTEXT
782 //      VAR
783 //      VAR.P
784 //      VAR.S
785 //      VARA
786 //      VARP
787 //      VARPA
788 //      VDB
789 //      VLOOKUP
790 //      WEEKDAY
791 //      WEEKNUM
792 //      WEIBULL
793 //      WEIBULL.DIST
794 //      WORKDAY
795 //      WORKDAY.INTL
796 //      XIRR
797 //      XLOOKUP
798 //      XNPV
799 //      XOR
800 //      YEAR
801 //      YEARFRAC
802 //      YIELD
803 //      YIELDDISC
804 //      YIELDMAT
805 //      Z.TEST
806 //      ZTEST
807 func (f *File) CalcCellValue(sheet, cell string, opts ...Options) (result string, err error) {
808         var (
809                 rawCellValue = getOptions(opts...).RawCellValue
810                 styleIdx     int
811                 token        formulaArg
812         )
813         if token, err = f.calcCellValue(&calcContext{
814                 entry:             fmt.Sprintf("%s!%s", sheet, cell),
815                 maxCalcIterations: getOptions(opts...).MaxCalcIterations,
816                 iterations:        make(map[string]uint),
817                 iterationsCache:   make(map[string]formulaArg),
818         }, sheet, cell); err != nil {
819                 result = token.String
820                 return
821         }
822         if !rawCellValue {
823                 styleIdx, _ = f.GetCellStyle(sheet, cell)
824         }
825         result = token.Value()
826         if isNum, precision, decimal := isNumeric(result); isNum {
827                 if precision > 15 {
828                         result, err = f.formattedValue(&xlsxC{S: styleIdx, V: strings.ToUpper(strconv.FormatFloat(decimal, 'G', 15, 64))}, rawCellValue, CellTypeNumber)
829                         return
830                 }
831                 if !strings.HasPrefix(result, "0") {
832                         result, err = f.formattedValue(&xlsxC{S: styleIdx, V: strings.ToUpper(strconv.FormatFloat(decimal, 'f', -1, 64))}, rawCellValue, CellTypeNumber)
833                 }
834         }
835         return
836 }
837
838 // calcCellValue calculate cell value by given context, worksheet name and cell
839 // reference.
840 func (f *File) calcCellValue(ctx *calcContext, sheet, cell string) (result formulaArg, err error) {
841         var formula string
842         if formula, err = f.getCellFormula(sheet, cell, true); err != nil {
843                 return
844         }
845         ps := efp.ExcelParser()
846         tokens := ps.Parse(formula)
847         if tokens == nil {
848                 return f.cellResolver(ctx, sheet, cell)
849         }
850         result, err = f.evalInfixExp(ctx, sheet, cell, tokens)
851         return
852 }
853
854 // getPriority calculate arithmetic operator priority.
855 func getPriority(token efp.Token) (pri int) {
856         pri = tokenPriority[token.TValue]
857         if token.TValue == "-" && token.TType == efp.TokenTypeOperatorPrefix {
858                 pri = 6
859         }
860         if isBeginParenthesesToken(token) { // (
861                 pri = 0
862         }
863         return
864 }
865
866 // newNumberFormulaArg constructs a number formula argument.
867 func newNumberFormulaArg(n float64) formulaArg {
868         if math.IsNaN(n) {
869                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
870         }
871         return formulaArg{Type: ArgNumber, Number: n}
872 }
873
874 // newStringFormulaArg constructs a string formula argument.
875 func newStringFormulaArg(s string) formulaArg {
876         return formulaArg{Type: ArgString, String: s}
877 }
878
879 // newMatrixFormulaArg constructs a matrix formula argument.
880 func newMatrixFormulaArg(m [][]formulaArg) formulaArg {
881         return formulaArg{Type: ArgMatrix, Matrix: m}
882 }
883
884 // newListFormulaArg create a list formula argument.
885 func newListFormulaArg(l []formulaArg) formulaArg {
886         return formulaArg{Type: ArgList, List: l}
887 }
888
889 // newBoolFormulaArg constructs a boolean formula argument.
890 func newBoolFormulaArg(b bool) formulaArg {
891         var n float64
892         if b {
893                 n = 1
894         }
895         return formulaArg{Type: ArgNumber, Number: n, Boolean: true}
896 }
897
898 // newErrorFormulaArg create an error formula argument of a given type with a
899 // specified error message.
900 func newErrorFormulaArg(formulaError, msg string) formulaArg {
901         return formulaArg{Type: ArgError, String: formulaError, Error: msg}
902 }
903
904 // newEmptyFormulaArg create an empty formula argument.
905 func newEmptyFormulaArg() formulaArg {
906         return formulaArg{Type: ArgEmpty}
907 }
908
909 // evalInfixExp evaluate syntax analysis by given infix expression after
910 // lexical analysis. Evaluate an infix expression containing formulas by
911 // stacks:
912 //
913 //      opd  - Operand
914 //      opt  - Operator
915 //      opf  - Operation formula
916 //      opfd - Operand of the operation formula
917 //      opft - Operator of the operation formula
918 //      args - Arguments list of the operation formula
919 //
920 // TODO: handle subtypes: Nothing, Text, Logical, Error, Concatenation, Intersection, Union
921 func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.Token) (formulaArg, error) {
922         var err error
923         opdStack, optStack, opfStack, opfdStack, opftStack, argsStack := NewStack(), NewStack(), NewStack(), NewStack(), NewStack(), NewStack()
924         var inArray, inArrayRow bool
925         for i := 0; i < len(tokens); i++ {
926                 token := tokens[i]
927
928                 // out of function stack
929                 if opfStack.Len() == 0 {
930                         if err = f.parseToken(ctx, sheet, token, opdStack, optStack); err != nil {
931                                 return newEmptyFormulaArg(), err
932                         }
933                 }
934
935                 // function start
936                 if isFunctionStartToken(token) {
937                         if token.TValue == "ARRAY" {
938                                 inArray = true
939                                 continue
940                         }
941                         if token.TValue == "ARRAYROW" {
942                                 inArrayRow = true
943                                 continue
944                         }
945                         opfStack.Push(token)
946                         argsStack.Push(list.New().Init())
947                         opftStack.Push(token) // to know which operators belong to a function use the function as a separator
948                         continue
949                 }
950
951                 // in function stack, walk 2 token at once
952                 if opfStack.Len() > 0 {
953                         var nextToken efp.Token
954                         if i+1 < len(tokens) {
955                                 nextToken = tokens[i+1]
956                         }
957
958                         // current token is args or range, skip next token, order required: parse reference first
959                         if token.TSubType == efp.TokenSubTypeRange {
960                                 if opftStack.Peek().(efp.Token) != opfStack.Peek().(efp.Token) {
961                                         refTo := f.getDefinedNameRefTo(token.TValue, sheet)
962                                         if refTo != "" {
963                                                 token.TValue = refTo
964                                         }
965                                         // parse reference: must reference at here
966                                         result, err := f.parseReference(ctx, sheet, token.TValue)
967                                         if err != nil {
968                                                 return result, err
969                                         }
970                                         opfdStack.Push(result)
971                                         continue
972                                 }
973                                 if nextToken.TType == efp.TokenTypeArgument || nextToken.TType == efp.TokenTypeFunction {
974                                         // parse reference: reference or range at here
975                                         refTo := f.getDefinedNameRefTo(token.TValue, sheet)
976                                         if refTo != "" {
977                                                 token.TValue = refTo
978                                         }
979                                         result, err := f.parseReference(ctx, sheet, token.TValue)
980                                         if err != nil {
981                                                 return result, err
982                                         }
983                                         // when current token is range, next token is argument and opfdStack not empty,
984                                         // should push value to opfdStack and continue
985                                         if nextToken.TType == efp.TokenTypeArgument && !opfdStack.Empty() {
986                                                 opfdStack.Push(result)
987                                                 continue
988                                         }
989                                         argsStack.Peek().(*list.List).PushBack(result)
990                                         continue
991                                 }
992                         }
993
994                         if isEndParenthesesToken(token) && isBeginParenthesesToken(opftStack.Peek().(efp.Token)) {
995                                 if arg := argsStack.Peek().(*list.List).Back(); arg != nil {
996                                         opfdStack.Push(arg.Value.(formulaArg))
997                                         argsStack.Peek().(*list.List).Remove(arg)
998                                 }
999                         }
1000
1001                         // check current token is opft
1002                         if err = f.parseToken(ctx, sheet, token, opfdStack, opftStack); err != nil {
1003                                 return newEmptyFormulaArg(), err
1004                         }
1005
1006                         // current token is arg
1007                         if token.TType == efp.TokenTypeArgument {
1008                                 for opftStack.Peek().(efp.Token) != opfStack.Peek().(efp.Token) {
1009                                         // calculate trigger
1010                                         topOpt := opftStack.Peek().(efp.Token)
1011                                         if err := calculate(opfdStack, topOpt); err != nil {
1012                                                 argsStack.Peek().(*list.List).PushFront(newErrorFormulaArg(formulaErrorVALUE, err.Error()))
1013                                         }
1014                                         opftStack.Pop()
1015                                 }
1016                                 if !opfdStack.Empty() {
1017                                         argsStack.Peek().(*list.List).PushBack(opfdStack.Pop().(formulaArg))
1018                                 }
1019                                 continue
1020                         }
1021
1022                         if inArrayRow && isOperand(token) {
1023                                 continue
1024                         }
1025                         if inArrayRow && isFunctionStopToken(token) {
1026                                 inArrayRow = false
1027                                 continue
1028                         }
1029                         if inArray && isFunctionStopToken(token) {
1030                                 argsStack.Peek().(*list.List).PushBack(opfdStack.Pop())
1031                                 inArray = false
1032                                 continue
1033                         }
1034                         if errArg := f.evalInfixExpFunc(ctx, sheet, cell, token, nextToken, opfStack, opdStack, opftStack, opfdStack, argsStack); errArg.Type == ArgError {
1035                                 return errArg, errors.New(errArg.Error)
1036                         }
1037                 }
1038         }
1039         for optStack.Len() != 0 {
1040                 topOpt := optStack.Peek().(efp.Token)
1041                 if err = calculate(opdStack, topOpt); err != nil {
1042                         return newEmptyFormulaArg(), err
1043                 }
1044                 optStack.Pop()
1045         }
1046         if opdStack.Len() == 0 {
1047                 return newEmptyFormulaArg(), ErrInvalidFormula
1048         }
1049         return opdStack.Peek().(formulaArg), err
1050 }
1051
1052 // evalInfixExpFunc evaluate formula function in the infix expression.
1053 func (f *File) evalInfixExpFunc(ctx *calcContext, sheet, cell string, token, nextToken efp.Token, opfStack, opdStack, opftStack, opfdStack, argsStack *Stack) formulaArg {
1054         if !isFunctionStopToken(token) {
1055                 return newEmptyFormulaArg()
1056         }
1057         prepareEvalInfixExp(opfStack, opftStack, opfdStack, argsStack)
1058         // call formula function to evaluate
1059         arg := callFuncByName(&formulaFuncs{f: f, sheet: sheet, cell: cell, ctx: ctx}, strings.NewReplacer(
1060                 "_xlfn.", "", ".", "dot").Replace(opfStack.Peek().(efp.Token).TValue),
1061                 []reflect.Value{reflect.ValueOf(argsStack.Peek().(*list.List))})
1062         if arg.Type == ArgError && opfStack.Len() == 1 {
1063                 return arg
1064         }
1065         argsStack.Pop()
1066         opftStack.Pop() // remove current function separator
1067         opfStack.Pop()
1068         if opfStack.Len() > 0 { // still in function stack
1069                 if nextToken.TType == efp.TokenTypeOperatorInfix || (opftStack.Len() > 1 && opfdStack.Len() > 0) {
1070                         // mathematics calculate in formula function
1071                         opfdStack.Push(arg)
1072                         return newEmptyFormulaArg()
1073                 }
1074                 argsStack.Peek().(*list.List).PushBack(arg)
1075                 return newEmptyFormulaArg()
1076         }
1077         if arg.Type == ArgMatrix && len(arg.Matrix) > 0 && len(arg.Matrix[0]) > 0 {
1078                 opdStack.Push(arg.Matrix[0][0])
1079                 return newEmptyFormulaArg()
1080         }
1081         opdStack.Push(arg)
1082         return newEmptyFormulaArg()
1083 }
1084
1085 // prepareEvalInfixExp check the token and stack state for formula function
1086 // evaluate.
1087 func prepareEvalInfixExp(opfStack, opftStack, opfdStack, argsStack *Stack) {
1088         // current token is function stop
1089         for opftStack.Peek().(efp.Token) != opfStack.Peek().(efp.Token) {
1090                 // calculate trigger
1091                 topOpt := opftStack.Peek().(efp.Token)
1092                 if err := calculate(opfdStack, topOpt); err != nil {
1093                         argsStack.Peek().(*list.List).PushBack(newErrorFormulaArg(err.Error(), err.Error()))
1094                         opftStack.Pop()
1095                         continue
1096                 }
1097                 opftStack.Pop()
1098         }
1099         argument := true
1100         if opftStack.Len() > 2 && opfdStack.Len() == 1 {
1101                 topOpt := opftStack.Pop()
1102                 if opftStack.Peek().(efp.Token).TType == efp.TokenTypeOperatorInfix {
1103                         argument = false
1104                 }
1105                 opftStack.Push(topOpt)
1106         }
1107         // push opfd to args
1108         if argument && opfdStack.Len() > 0 {
1109                 argsStack.Peek().(*list.List).PushBack(opfdStack.Pop().(formulaArg))
1110         }
1111 }
1112
1113 // calcPow evaluate exponentiation arithmetic operations.
1114 func calcPow(rOpd, lOpd formulaArg, opdStack *Stack) error {
1115         lOpdVal := lOpd.ToNumber()
1116         if lOpdVal.Type != ArgNumber {
1117                 return errors.New(lOpdVal.Value())
1118         }
1119         rOpdVal := rOpd.ToNumber()
1120         if rOpdVal.Type != ArgNumber {
1121                 return errors.New(rOpdVal.Value())
1122         }
1123         opdStack.Push(newNumberFormulaArg(math.Pow(lOpdVal.Number, rOpdVal.Number)))
1124         return nil
1125 }
1126
1127 // calcEq evaluate equal arithmetic operations.
1128 func calcEq(rOpd, lOpd formulaArg, opdStack *Stack) error {
1129         opdStack.Push(newBoolFormulaArg(rOpd.Value() == lOpd.Value()))
1130         return nil
1131 }
1132
1133 // calcNEq evaluate not equal arithmetic operations.
1134 func calcNEq(rOpd, lOpd formulaArg, opdStack *Stack) error {
1135         opdStack.Push(newBoolFormulaArg(rOpd.Value() != lOpd.Value()))
1136         return nil
1137 }
1138
1139 // calcL evaluate less than arithmetic operations.
1140 func calcL(rOpd, lOpd formulaArg, opdStack *Stack) error {
1141         if rOpd.Type == ArgNumber && lOpd.Type == ArgNumber {
1142                 opdStack.Push(newBoolFormulaArg(lOpd.Number < rOpd.Number))
1143         }
1144         if rOpd.Type == ArgString && lOpd.Type == ArgString {
1145                 opdStack.Push(newBoolFormulaArg(strings.Compare(lOpd.Value(), rOpd.Value()) == -1))
1146         }
1147         if rOpd.Type == ArgNumber && lOpd.Type == ArgString {
1148                 opdStack.Push(newBoolFormulaArg(false))
1149         }
1150         if rOpd.Type == ArgString && lOpd.Type == ArgNumber {
1151                 opdStack.Push(newBoolFormulaArg(true))
1152         }
1153         return nil
1154 }
1155
1156 // calcLe evaluate less than or equal arithmetic operations.
1157 func calcLe(rOpd, lOpd formulaArg, opdStack *Stack) error {
1158         if rOpd.Type == ArgNumber && lOpd.Type == ArgNumber {
1159                 opdStack.Push(newBoolFormulaArg(lOpd.Number <= rOpd.Number))
1160         }
1161         if rOpd.Type == ArgString && lOpd.Type == ArgString {
1162                 opdStack.Push(newBoolFormulaArg(strings.Compare(lOpd.Value(), rOpd.Value()) != 1))
1163         }
1164         if rOpd.Type == ArgNumber && lOpd.Type == ArgString {
1165                 opdStack.Push(newBoolFormulaArg(false))
1166         }
1167         if rOpd.Type == ArgString && lOpd.Type == ArgNumber {
1168                 opdStack.Push(newBoolFormulaArg(true))
1169         }
1170         return nil
1171 }
1172
1173 // calcG evaluate greater than arithmetic operations.
1174 func calcG(rOpd, lOpd formulaArg, opdStack *Stack) error {
1175         if rOpd.Type == ArgNumber && lOpd.Type == ArgNumber {
1176                 opdStack.Push(newBoolFormulaArg(lOpd.Number > rOpd.Number))
1177         }
1178         if rOpd.Type == ArgString && lOpd.Type == ArgString {
1179                 opdStack.Push(newBoolFormulaArg(strings.Compare(lOpd.Value(), rOpd.Value()) == 1))
1180         }
1181         if rOpd.Type == ArgNumber && lOpd.Type == ArgString {
1182                 opdStack.Push(newBoolFormulaArg(true))
1183         }
1184         if rOpd.Type == ArgString && lOpd.Type == ArgNumber {
1185                 opdStack.Push(newBoolFormulaArg(false))
1186         }
1187         return nil
1188 }
1189
1190 // calcGe evaluate greater than or equal arithmetic operations.
1191 func calcGe(rOpd, lOpd formulaArg, opdStack *Stack) error {
1192         if rOpd.Type == ArgNumber && lOpd.Type == ArgNumber {
1193                 opdStack.Push(newBoolFormulaArg(lOpd.Number >= rOpd.Number))
1194         }
1195         if rOpd.Type == ArgString && lOpd.Type == ArgString {
1196                 opdStack.Push(newBoolFormulaArg(strings.Compare(lOpd.Value(), rOpd.Value()) != -1))
1197         }
1198         if rOpd.Type == ArgNumber && lOpd.Type == ArgString {
1199                 opdStack.Push(newBoolFormulaArg(true))
1200         }
1201         if rOpd.Type == ArgString && lOpd.Type == ArgNumber {
1202                 opdStack.Push(newBoolFormulaArg(false))
1203         }
1204         return nil
1205 }
1206
1207 // calcSplice evaluate splice '&' operations.
1208 func calcSplice(rOpd, lOpd formulaArg, opdStack *Stack) error {
1209         opdStack.Push(newStringFormulaArg(lOpd.Value() + rOpd.Value()))
1210         return nil
1211 }
1212
1213 // calcAdd evaluate addition arithmetic operations.
1214 func calcAdd(rOpd, lOpd formulaArg, opdStack *Stack) error {
1215         lOpdVal := lOpd.ToNumber()
1216         if lOpdVal.Type != ArgNumber {
1217                 return errors.New(lOpdVal.Value())
1218         }
1219         rOpdVal := rOpd.ToNumber()
1220         if rOpdVal.Type != ArgNumber {
1221                 return errors.New(rOpdVal.Value())
1222         }
1223         opdStack.Push(newNumberFormulaArg(lOpdVal.Number + rOpdVal.Number))
1224         return nil
1225 }
1226
1227 // calcSubtract evaluate subtraction arithmetic operations.
1228 func calcSubtract(rOpd, lOpd formulaArg, opdStack *Stack) error {
1229         if rOpd.Value() == "" {
1230                 rOpd = newNumberFormulaArg(0)
1231         }
1232         if lOpd.Value() == "" {
1233                 lOpd = newNumberFormulaArg(0)
1234         }
1235         lOpdVal := lOpd.ToNumber()
1236         if lOpdVal.Type != ArgNumber {
1237                 return errors.New(lOpdVal.Value())
1238         }
1239         rOpdVal := rOpd.ToNumber()
1240         if rOpdVal.Type != ArgNumber {
1241                 return errors.New(rOpdVal.Value())
1242         }
1243         opdStack.Push(newNumberFormulaArg(lOpdVal.Number - rOpdVal.Number))
1244         return nil
1245 }
1246
1247 // calcMultiply evaluate multiplication arithmetic operations.
1248 func calcMultiply(rOpd, lOpd formulaArg, opdStack *Stack) error {
1249         lOpdVal := lOpd.ToNumber()
1250         if lOpdVal.Type != ArgNumber {
1251                 return errors.New(lOpdVal.Value())
1252         }
1253         rOpdVal := rOpd.ToNumber()
1254         if rOpdVal.Type != ArgNumber {
1255                 return errors.New(rOpdVal.Value())
1256         }
1257         opdStack.Push(newNumberFormulaArg(lOpdVal.Number * rOpdVal.Number))
1258         return nil
1259 }
1260
1261 // calcDiv evaluate division arithmetic operations.
1262 func calcDiv(rOpd, lOpd formulaArg, opdStack *Stack) error {
1263         lOpdVal := lOpd.ToNumber()
1264         if lOpdVal.Type != ArgNumber {
1265                 return errors.New(lOpdVal.Value())
1266         }
1267         rOpdVal := rOpd.ToNumber()
1268         if rOpdVal.Type != ArgNumber {
1269                 return errors.New(rOpdVal.Value())
1270         }
1271         if rOpdVal.Number == 0 {
1272                 return errors.New(formulaErrorDIV)
1273         }
1274         opdStack.Push(newNumberFormulaArg(lOpdVal.Number / rOpdVal.Number))
1275         return nil
1276 }
1277
1278 // calculate evaluate basic arithmetic operations.
1279 func calculate(opdStack *Stack, opt efp.Token) error {
1280         if opt.TValue == "-" && opt.TType == efp.TokenTypeOperatorPrefix {
1281                 if opdStack.Len() < 1 {
1282                         return ErrInvalidFormula
1283                 }
1284                 opd := opdStack.Pop().(formulaArg)
1285                 opdStack.Push(newNumberFormulaArg(0 - opd.ToNumber().Number))
1286         }
1287         if opt.TValue == "-" && opt.TType == efp.TokenTypeOperatorInfix {
1288                 if opdStack.Len() < 2 {
1289                         return ErrInvalidFormula
1290                 }
1291                 rOpd := opdStack.Pop().(formulaArg)
1292                 lOpd := opdStack.Pop().(formulaArg)
1293                 if err := calcSubtract(rOpd, lOpd, opdStack); err != nil {
1294                         return err
1295                 }
1296         }
1297         tokenCalcFunc := map[string]func(rOpd, lOpd formulaArg, opdStack *Stack) error{
1298                 "^":  calcPow,
1299                 "*":  calcMultiply,
1300                 "/":  calcDiv,
1301                 "+":  calcAdd,
1302                 "=":  calcEq,
1303                 "<>": calcNEq,
1304                 "<":  calcL,
1305                 "<=": calcLe,
1306                 ">":  calcG,
1307                 ">=": calcGe,
1308                 "&":  calcSplice,
1309         }
1310         if fn, ok := tokenCalcFunc[opt.TValue]; ok {
1311                 if opdStack.Len() < 2 {
1312                         return ErrInvalidFormula
1313                 }
1314                 rOpd := opdStack.Pop().(formulaArg)
1315                 lOpd := opdStack.Pop().(formulaArg)
1316                 if opt.TValue != "&" {
1317                         if rOpd.Value() == "" {
1318                                 rOpd = newNumberFormulaArg(0)
1319                         }
1320                         if lOpd.Value() == "" {
1321                                 lOpd = newNumberFormulaArg(0)
1322                         }
1323                 }
1324                 if rOpd.Type == ArgError {
1325                         return errors.New(rOpd.Value())
1326                 }
1327                 if lOpd.Type == ArgError {
1328                         return errors.New(lOpd.Value())
1329                 }
1330                 return fn(rOpd, lOpd, opdStack)
1331         }
1332         return nil
1333 }
1334
1335 // parseOperatorPrefixToken parse operator prefix token.
1336 func (f *File) parseOperatorPrefixToken(optStack, opdStack *Stack, token efp.Token) (err error) {
1337         if optStack.Len() == 0 {
1338                 optStack.Push(token)
1339                 return
1340         }
1341         tokenPriority := getPriority(token)
1342         topOpt := optStack.Peek().(efp.Token)
1343         topOptPriority := getPriority(topOpt)
1344         if topOpt.TValue == "-" && topOpt.TType == efp.TokenTypeOperatorPrefix && token.TValue == "-" && token.TType == efp.TokenTypeOperatorPrefix {
1345                 optStack.Pop()
1346                 return
1347         }
1348         if tokenPriority > topOptPriority {
1349                 optStack.Push(token)
1350                 return
1351         }
1352         for tokenPriority <= topOptPriority {
1353                 optStack.Pop()
1354                 if err = calculate(opdStack, topOpt); err != nil {
1355                         return
1356                 }
1357                 if optStack.Len() > 0 {
1358                         topOpt = optStack.Peek().(efp.Token)
1359                         topOptPriority = getPriority(topOpt)
1360                         continue
1361                 }
1362                 break
1363         }
1364         optStack.Push(token)
1365         return
1366 }
1367
1368 // isFunctionStartToken determine if the token is function start.
1369 func isFunctionStartToken(token efp.Token) bool {
1370         return token.TType == efp.TokenTypeFunction && token.TSubType == efp.TokenSubTypeStart
1371 }
1372
1373 // isFunctionStopToken determine if the token is function stop.
1374 func isFunctionStopToken(token efp.Token) bool {
1375         return token.TType == efp.TokenTypeFunction && token.TSubType == efp.TokenSubTypeStop
1376 }
1377
1378 // isBeginParenthesesToken determine if the token is begin parentheses: (.
1379 func isBeginParenthesesToken(token efp.Token) bool {
1380         return token.TType == efp.TokenTypeSubexpression && token.TSubType == efp.TokenSubTypeStart
1381 }
1382
1383 // isEndParenthesesToken determine if the token is end parentheses: ).
1384 func isEndParenthesesToken(token efp.Token) bool {
1385         return token.TType == efp.TokenTypeSubexpression && token.TSubType == efp.TokenSubTypeStop
1386 }
1387
1388 // isOperatorPrefixToken determine if the token is parse operator prefix
1389 // token.
1390 func isOperatorPrefixToken(token efp.Token) bool {
1391         _, ok := tokenPriority[token.TValue]
1392         return (token.TValue == "-" && token.TType == efp.TokenTypeOperatorPrefix) || (ok && token.TType == efp.TokenTypeOperatorInfix)
1393 }
1394
1395 // isOperand determine if the token is parse operand.
1396 func isOperand(token efp.Token) bool {
1397         return token.TType == efp.TokenTypeOperand && (token.TSubType == efp.TokenSubTypeNumber || token.TSubType == efp.TokenSubTypeText || token.TSubType == efp.TokenSubTypeLogical)
1398 }
1399
1400 // tokenToFormulaArg create a formula argument by given token.
1401 func tokenToFormulaArg(token efp.Token) formulaArg {
1402         switch token.TSubType {
1403         case efp.TokenSubTypeLogical:
1404                 return newBoolFormulaArg(strings.EqualFold(token.TValue, "TRUE"))
1405         case efp.TokenSubTypeNumber:
1406                 num, _ := strconv.ParseFloat(token.TValue, 64)
1407                 return newNumberFormulaArg(num)
1408         default:
1409                 return newStringFormulaArg(token.TValue)
1410         }
1411 }
1412
1413 // formulaArgToToken create a token by given formula argument.
1414 func formulaArgToToken(arg formulaArg) efp.Token {
1415         switch arg.Type {
1416         case ArgNumber:
1417                 if arg.Boolean {
1418                         return efp.Token{TValue: arg.Value(), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeLogical}
1419                 }
1420                 return efp.Token{TValue: arg.Value(), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber}
1421         default:
1422                 return efp.Token{TValue: arg.Value(), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeText}
1423         }
1424 }
1425
1426 // parseToken parse basic arithmetic operator priority and evaluate based on
1427 // operators and operands.
1428 func (f *File) parseToken(ctx *calcContext, sheet string, token efp.Token, opdStack, optStack *Stack) error {
1429         // parse reference: must reference at here
1430         if token.TSubType == efp.TokenSubTypeRange {
1431                 refTo := f.getDefinedNameRefTo(token.TValue, sheet)
1432                 if refTo != "" {
1433                         token.TValue = refTo
1434                 }
1435                 result, err := f.parseReference(ctx, sheet, token.TValue)
1436                 if err != nil {
1437                         return errors.New(formulaErrorNAME)
1438                 }
1439                 token = formulaArgToToken(result)
1440         }
1441         if isOperatorPrefixToken(token) {
1442                 if err := f.parseOperatorPrefixToken(optStack, opdStack, token); err != nil {
1443                         return err
1444                 }
1445         }
1446         if isBeginParenthesesToken(token) { // (
1447                 optStack.Push(token)
1448         }
1449         if isEndParenthesesToken(token) { // )
1450                 for !isBeginParenthesesToken(optStack.Peek().(efp.Token)) { // != (
1451                         topOpt := optStack.Peek().(efp.Token)
1452                         if err := calculate(opdStack, topOpt); err != nil {
1453                                 return err
1454                         }
1455                         optStack.Pop()
1456                 }
1457                 optStack.Pop()
1458         }
1459         if token.TType == efp.TokenTypeOperatorPostfix && !opdStack.Empty() {
1460                 topOpd := opdStack.Pop().(formulaArg)
1461                 opdStack.Push(newNumberFormulaArg(topOpd.Number / 100))
1462         }
1463         // opd
1464         if isOperand(token) {
1465                 opdStack.Push(tokenToFormulaArg(token))
1466         }
1467         return nil
1468 }
1469
1470 // parseRef parse reference for a cell, column name or row number.
1471 func parseRef(ref string) (cellRef, bool, bool, error) {
1472         var (
1473                 err, colErr, rowErr error
1474                 cr                  cellRef
1475                 cell                = ref
1476                 tokens              = strings.Split(ref, "!")
1477         )
1478         if len(tokens) == 2 { // have a worksheet
1479                 cr.Sheet, cell = tokens[0], tokens[1]
1480         }
1481         if cr.Col, cr.Row, err = CellNameToCoordinates(cell); err != nil {
1482                 if cr.Col, colErr = ColumnNameToNumber(cell); colErr == nil { // cast to column
1483                         return cr, true, false, nil
1484                 }
1485                 if cr.Row, rowErr = strconv.Atoi(cell); rowErr == nil { // cast to row
1486                         return cr, false, true, nil
1487                 }
1488                 return cr, false, false, err
1489         }
1490         return cr, false, false, err
1491 }
1492
1493 // prepareCellRange checking and convert cell reference to a cell range.
1494 func (cr *cellRange) prepareCellRange(col, row bool, cellRef cellRef) error {
1495         if col {
1496                 cellRef.Row = TotalRows
1497         }
1498         if row {
1499                 cellRef.Col = MaxColumns
1500         }
1501         if cellRef.Sheet == "" {
1502                 cellRef.Sheet = cr.From.Sheet
1503         }
1504         if cr.From.Sheet != cellRef.Sheet || cr.To.Sheet != cellRef.Sheet {
1505                 return errors.New("invalid reference")
1506         }
1507         if cr.From.Col > cellRef.Col {
1508                 cr.From.Col = cellRef.Col
1509         }
1510         if cr.From.Row > cellRef.Row {
1511                 cr.From.Row = cellRef.Row
1512         }
1513         if cr.To.Col < cellRef.Col {
1514                 cr.To.Col = cellRef.Col
1515         }
1516         if cr.To.Row < cellRef.Row {
1517                 cr.To.Row = cellRef.Row
1518         }
1519         return nil
1520 }
1521
1522 // parseReference parse reference and extract values by given reference
1523 // characters and default sheet name.
1524 func (f *File) parseReference(ctx *calcContext, sheet, reference string) (formulaArg, error) {
1525         reference = strings.ReplaceAll(reference, "$", "")
1526         ranges, cellRanges, cellRefs := strings.Split(reference, ":"), list.New(), list.New()
1527         if len(ranges) > 1 {
1528                 var cr cellRange
1529                 for i, ref := range ranges {
1530                         cellRef, col, row, err := parseRef(ref)
1531                         if err != nil {
1532                                 return newErrorFormulaArg(formulaErrorNAME, "invalid reference"), errors.New("invalid reference")
1533                         }
1534                         if i == 0 {
1535                                 if col {
1536                                         cellRef.Row = 1
1537                                 }
1538                                 if row {
1539                                         cellRef.Col = 1
1540                                 }
1541                                 if cellRef.Sheet == "" {
1542                                         cellRef.Sheet = sheet
1543                                 }
1544                                 cr.From, cr.To = cellRef, cellRef
1545                                 continue
1546                         }
1547                         if err := cr.prepareCellRange(col, row, cellRef); err != nil {
1548                                 return newErrorFormulaArg(formulaErrorNAME, err.Error()), err
1549                         }
1550                 }
1551                 cellRanges.PushBack(cr)
1552                 return f.rangeResolver(ctx, cellRefs, cellRanges)
1553         }
1554         cellRef, _, _, err := parseRef(reference)
1555         if err != nil {
1556                 return newErrorFormulaArg(formulaErrorNAME, "invalid reference"), errors.New("invalid reference")
1557         }
1558         if cellRef.Sheet == "" {
1559                 cellRef.Sheet = sheet
1560         }
1561         cellRefs.PushBack(cellRef)
1562         return f.rangeResolver(ctx, cellRefs, cellRanges)
1563 }
1564
1565 // prepareValueRange prepare value range.
1566 func prepareValueRange(cr cellRange, valueRange []int) {
1567         if cr.From.Row < valueRange[0] || valueRange[0] == 0 {
1568                 valueRange[0] = cr.From.Row
1569         }
1570         if cr.From.Col < valueRange[2] || valueRange[2] == 0 {
1571                 valueRange[2] = cr.From.Col
1572         }
1573         if cr.To.Row > valueRange[1] || valueRange[1] == 0 {
1574                 valueRange[1] = cr.To.Row
1575         }
1576         if cr.To.Col > valueRange[3] || valueRange[3] == 0 {
1577                 valueRange[3] = cr.To.Col
1578         }
1579 }
1580
1581 // prepareValueRef prepare value reference.
1582 func prepareValueRef(cr cellRef, valueRange []int) {
1583         if cr.Row < valueRange[0] || valueRange[0] == 0 {
1584                 valueRange[0] = cr.Row
1585         }
1586         if cr.Col < valueRange[2] || valueRange[2] == 0 {
1587                 valueRange[2] = cr.Col
1588         }
1589         if cr.Row > valueRange[1] || valueRange[1] == 0 {
1590                 valueRange[1] = cr.Row
1591         }
1592         if cr.Col > valueRange[3] || valueRange[3] == 0 {
1593                 valueRange[3] = cr.Col
1594         }
1595 }
1596
1597 // cellResolver calc cell value by given worksheet name, cell reference and context.
1598 func (f *File) cellResolver(ctx *calcContext, sheet, cell string) (formulaArg, error) {
1599         var (
1600                 arg   formulaArg
1601                 value string
1602                 err   error
1603         )
1604         ref := fmt.Sprintf("%s!%s", sheet, cell)
1605         if formula, _ := f.getCellFormula(sheet, cell, true); len(formula) != 0 {
1606                 ctx.mu.Lock()
1607                 if ctx.entry != ref {
1608                         if ctx.iterations[ref] <= f.options.MaxCalcIterations {
1609                                 ctx.iterations[ref]++
1610                                 ctx.mu.Unlock()
1611                                 arg, _ = f.calcCellValue(ctx, sheet, cell)
1612                                 ctx.iterationsCache[ref] = arg
1613                                 return arg, nil
1614                         }
1615                         ctx.mu.Unlock()
1616                         return ctx.iterationsCache[ref], nil
1617                 }
1618                 ctx.mu.Unlock()
1619         }
1620         if value, err = f.GetCellValue(sheet, cell, Options{RawCellValue: true}); err != nil {
1621                 return arg, err
1622         }
1623         arg = newStringFormulaArg(value)
1624         cellType, _ := f.GetCellType(sheet, cell)
1625         switch cellType {
1626         case CellTypeBool:
1627                 return arg.ToBool(), err
1628         case CellTypeNumber, CellTypeUnset:
1629                 if arg.Value() == "" {
1630                         return newEmptyFormulaArg(), err
1631                 }
1632                 return arg.ToNumber(), err
1633         case CellTypeInlineString, CellTypeSharedString:
1634                 return arg, err
1635         default:
1636                 return newEmptyFormulaArg(), err
1637         }
1638 }
1639
1640 // rangeResolver extract value as string from given reference and range list.
1641 // This function will not ignore the empty cell. For example, A1:A2:A2:B3 will
1642 // be reference A1:B3.
1643 func (f *File) rangeResolver(ctx *calcContext, cellRefs, cellRanges *list.List) (arg formulaArg, err error) {
1644         arg.cellRefs, arg.cellRanges = cellRefs, cellRanges
1645         // value range order: from row, to row, from column, to column
1646         valueRange := []int{0, 0, 0, 0}
1647         var sheet string
1648         // prepare value range
1649         for temp := cellRanges.Front(); temp != nil; temp = temp.Next() {
1650                 cr := temp.Value.(cellRange)
1651                 rng := []int{cr.From.Col, cr.From.Row, cr.To.Col, cr.To.Row}
1652                 _ = sortCoordinates(rng)
1653                 cr.From.Col, cr.From.Row, cr.To.Col, cr.To.Row = rng[0], rng[1], rng[2], rng[3]
1654                 prepareValueRange(cr, valueRange)
1655                 if cr.From.Sheet != "" {
1656                         sheet = cr.From.Sheet
1657                 }
1658         }
1659         for temp := cellRefs.Front(); temp != nil; temp = temp.Next() {
1660                 cr := temp.Value.(cellRef)
1661                 if cr.Sheet != "" {
1662                         sheet = cr.Sheet
1663                 }
1664                 prepareValueRef(cr, valueRange)
1665         }
1666         // extract value from ranges
1667         if cellRanges.Len() > 0 {
1668                 arg.Type = ArgMatrix
1669                 for row := valueRange[0]; row <= valueRange[1]; row++ {
1670                         var matrixRow []formulaArg
1671                         for col := valueRange[2]; col <= valueRange[3]; col++ {
1672                                 var cell string
1673                                 var value formulaArg
1674                                 if cell, err = CoordinatesToCellName(col, row); err != nil {
1675                                         return
1676                                 }
1677                                 if value, err = f.cellResolver(ctx, sheet, cell); err != nil {
1678                                         return
1679                                 }
1680                                 matrixRow = append(matrixRow, value)
1681                         }
1682                         arg.Matrix = append(arg.Matrix, matrixRow)
1683                 }
1684                 return
1685         }
1686         // extract value from references
1687         for temp := cellRefs.Front(); temp != nil; temp = temp.Next() {
1688                 cr := temp.Value.(cellRef)
1689                 var cell string
1690                 if cell, err = CoordinatesToCellName(cr.Col, cr.Row); err != nil {
1691                         return
1692                 }
1693                 if arg, err = f.cellResolver(ctx, cr.Sheet, cell); err != nil {
1694                         return
1695                 }
1696                 arg.cellRefs, arg.cellRanges = cellRefs, cellRanges
1697         }
1698         return
1699 }
1700
1701 // callFuncByName calls the no error or only error return function with
1702 // reflect by given receiver, name and parameters.
1703 func callFuncByName(receiver interface{}, name string, params []reflect.Value) (arg formulaArg) {
1704         function := reflect.ValueOf(receiver).MethodByName(name)
1705         if function.IsValid() {
1706                 rt := function.Call(params)
1707                 if len(rt) == 0 {
1708                         return
1709                 }
1710                 arg = rt[0].Interface().(formulaArg)
1711                 return
1712         }
1713         return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("not support %s function", name))
1714 }
1715
1716 // formulaCriteriaParser parse formula criteria.
1717 func formulaCriteriaParser(exp formulaArg) *formulaCriteria {
1718         prepareValue := func(cond string) (expected float64, err error) {
1719                 percentile := 1.0
1720                 if strings.HasSuffix(cond, "%") {
1721                         cond = strings.TrimSuffix(cond, "%")
1722                         percentile /= 100
1723                 }
1724                 if expected, err = strconv.ParseFloat(cond, 64); err != nil {
1725                         return
1726                 }
1727                 expected *= percentile
1728                 return
1729         }
1730         fc, val := &formulaCriteria{}, exp.Value()
1731         if val == "" {
1732                 return fc
1733         }
1734         for i, re := range formulaFormats {
1735                 if match := re.FindStringSubmatch(val); len(match) > 1 {
1736                         fc.Condition = newStringFormulaArg(match[1])
1737                         if num, err := prepareValue(match[1]); err == nil {
1738                                 fc.Condition = newNumberFormulaArg(num)
1739                         }
1740                         fc.Type = formulaCriterias[i]
1741                         return fc
1742                 }
1743         }
1744         if strings.Contains(val, "?") {
1745                 val = strings.ReplaceAll(val, "?", ".")
1746         }
1747         if strings.Contains(val, "*") {
1748                 val = strings.ReplaceAll(val, "*", ".*")
1749         }
1750         fc.Type, fc.Condition = criteriaRegexp, newStringFormulaArg(val)
1751         if num := fc.Condition.ToNumber(); num.Type == ArgNumber {
1752                 fc.Condition = num
1753         }
1754         return fc
1755 }
1756
1757 // formulaCriteriaEval evaluate formula criteria expression.
1758 func formulaCriteriaEval(val formulaArg, criteria *formulaCriteria) (result bool, err error) {
1759         s := NewStack()
1760         tokenCalcFunc := map[byte]func(rOpd, lOpd formulaArg, opdStack *Stack) error{
1761                 criteriaEq: calcEq,
1762                 criteriaNe: calcNEq,
1763                 criteriaL:  calcL,
1764                 criteriaLe: calcLe,
1765                 criteriaG:  calcG,
1766                 criteriaGe: calcGe,
1767         }
1768         switch criteria.Type {
1769         case criteriaEq, criteriaLe, criteriaGe, criteriaNe, criteriaL, criteriaG:
1770                 if fn, ok := tokenCalcFunc[criteria.Type]; ok {
1771                         if _ = fn(criteria.Condition, val, s); s.Len() > 0 {
1772                                 return s.Pop().(formulaArg).Number == 1, err
1773                         }
1774                 }
1775         case criteriaRegexp:
1776                 return regexp.MatchString(criteria.Condition.Value(), val.Value())
1777         }
1778         return
1779 }
1780
1781 // Engineering Functions
1782
1783 // BESSELI function the modified Bessel function, which is equivalent to the
1784 // Bessel function evaluated for purely imaginary arguments. The syntax of
1785 // the Besseli function is:
1786 //
1787 //      BESSELI(x,n)
1788 func (fn *formulaFuncs) BESSELI(argsList *list.List) formulaArg {
1789         if argsList.Len() != 2 {
1790                 return newErrorFormulaArg(formulaErrorVALUE, "BESSELI requires 2 numeric arguments")
1791         }
1792         return fn.bassel(argsList, true)
1793 }
1794
1795 // BESSELJ function returns the Bessel function, Jn(x), for a specified order
1796 // and value of x. The syntax of the function is:
1797 //
1798 //      BESSELJ(x,n)
1799 func (fn *formulaFuncs) BESSELJ(argsList *list.List) formulaArg {
1800         if argsList.Len() != 2 {
1801                 return newErrorFormulaArg(formulaErrorVALUE, "BESSELJ requires 2 numeric arguments")
1802         }
1803         return fn.bassel(argsList, false)
1804 }
1805
1806 // bassel is an implementation of the formula functions BESSELI and BESSELJ.
1807 func (fn *formulaFuncs) bassel(argsList *list.List, modfied bool) formulaArg {
1808         x, n := argsList.Front().Value.(formulaArg).ToNumber(), argsList.Back().Value.(formulaArg).ToNumber()
1809         if x.Type != ArgNumber {
1810                 return x
1811         }
1812         if n.Type != ArgNumber {
1813                 return n
1814         }
1815         max, x1 := 100, x.Number*0.5
1816         x2 := x1 * x1
1817         x1 = math.Pow(x1, n.Number)
1818         n1, n2, n3, n4, add := fact(n.Number), 1.0, 0.0, n.Number, false
1819         result := x1 / n1
1820         t := result * 0.9
1821         for result != t && max != 0 {
1822                 x1 *= x2
1823                 n3++
1824                 n1 *= n3
1825                 n4++
1826                 n2 *= n4
1827                 t = result
1828                 r := x1 / n1 / n2
1829                 if modfied || add {
1830                         result += r
1831                 } else {
1832                         result -= r
1833                 }
1834                 max--
1835                 add = !add
1836         }
1837         return newNumberFormulaArg(result)
1838 }
1839
1840 // BESSELK function calculates the modified Bessel functions, Kn(x), which are
1841 // also known as the hyperbolic Bessel Functions. These are the equivalent of
1842 // the Bessel functions, evaluated for purely imaginary arguments. The syntax
1843 // of the function is:
1844 //
1845 //      BESSELK(x,n)
1846 func (fn *formulaFuncs) BESSELK(argsList *list.List) formulaArg {
1847         if argsList.Len() != 2 {
1848                 return newErrorFormulaArg(formulaErrorVALUE, "BESSELK requires 2 numeric arguments")
1849         }
1850         x, n := argsList.Front().Value.(formulaArg).ToNumber(), argsList.Back().Value.(formulaArg).ToNumber()
1851         if x.Type != ArgNumber {
1852                 return x
1853         }
1854         if n.Type != ArgNumber {
1855                 return n
1856         }
1857         if x.Number <= 0 || n.Number < 0 {
1858                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
1859         }
1860         var result float64
1861         switch math.Floor(n.Number) {
1862         case 0:
1863                 result = fn.besselK0(x)
1864         case 1:
1865                 result = fn.besselK1(x)
1866         default:
1867                 result = fn.besselK2(x, n)
1868         }
1869         return newNumberFormulaArg(result)
1870 }
1871
1872 // besselK0 is an implementation of the formula function BESSELK.
1873 func (fn *formulaFuncs) besselK0(x formulaArg) float64 {
1874         var y float64
1875         if x.Number <= 2 {
1876                 n2 := x.Number * 0.5
1877                 y = n2 * n2
1878                 args := list.New()
1879                 args.PushBack(x)
1880                 args.PushBack(newNumberFormulaArg(0))
1881                 return -math.Log(n2)*fn.BESSELI(args).Number +
1882                         (-0.57721566 + y*(0.42278420+y*(0.23069756+y*(0.3488590e-1+y*(0.262698e-2+y*
1883                                 (0.10750e-3+y*0.74e-5))))))
1884         }
1885         y = 2 / x.Number
1886         return math.Exp(-x.Number) / math.Sqrt(x.Number) *
1887                 (1.25331414 + y*(-0.7832358e-1+y*(0.2189568e-1+y*(-0.1062446e-1+y*
1888                         (0.587872e-2+y*(-0.251540e-2+y*0.53208e-3))))))
1889 }
1890
1891 // besselK1 is an implementation of the formula function BESSELK.
1892 func (fn *formulaFuncs) besselK1(x formulaArg) float64 {
1893         var n2, y float64
1894         if x.Number <= 2 {
1895                 n2 = x.Number * 0.5
1896                 y = n2 * n2
1897                 args := list.New()
1898                 args.PushBack(x)
1899                 args.PushBack(newNumberFormulaArg(1))
1900                 return math.Log(n2)*fn.BESSELI(args).Number +
1901                         (1+y*(0.15443144+y*(-0.67278579+y*(-0.18156897+y*(-0.1919402e-1+y*(-0.110404e-2+y*(-0.4686e-4)))))))/x.Number
1902         }
1903         y = 2 / x.Number
1904         return math.Exp(-x.Number) / math.Sqrt(x.Number) *
1905                 (1.25331414 + y*(0.23498619+y*(-0.3655620e-1+y*(0.1504268e-1+y*(-0.780353e-2+y*
1906                         (0.325614e-2+y*(-0.68245e-3)))))))
1907 }
1908
1909 // besselK2 is an implementation of the formula function BESSELK.
1910 func (fn *formulaFuncs) besselK2(x, n formulaArg) float64 {
1911         tox, bkm, bk, bkp := 2/x.Number, fn.besselK0(x), fn.besselK1(x), 0.0
1912         for i := 1.0; i < n.Number; i++ {
1913                 bkp = bkm + i*tox*bk
1914                 bkm = bk
1915                 bk = bkp
1916         }
1917         return bk
1918 }
1919
1920 // BESSELY function returns the Bessel function, Yn(x), (also known as the
1921 // Weber function or the Neumann function), for a specified order and value
1922 // of x. The syntax of the function is:
1923 //
1924 //      BESSELY(x,n)
1925 func (fn *formulaFuncs) BESSELY(argsList *list.List) formulaArg {
1926         if argsList.Len() != 2 {
1927                 return newErrorFormulaArg(formulaErrorVALUE, "BESSELY requires 2 numeric arguments")
1928         }
1929         x, n := argsList.Front().Value.(formulaArg).ToNumber(), argsList.Back().Value.(formulaArg).ToNumber()
1930         if x.Type != ArgNumber {
1931                 return x
1932         }
1933         if n.Type != ArgNumber {
1934                 return n
1935         }
1936         if x.Number <= 0 || n.Number < 0 {
1937                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
1938         }
1939         var result float64
1940         switch math.Floor(n.Number) {
1941         case 0:
1942                 result = fn.besselY0(x)
1943         case 1:
1944                 result = fn.besselY1(x)
1945         default:
1946                 result = fn.besselY2(x, n)
1947         }
1948         return newNumberFormulaArg(result)
1949 }
1950
1951 // besselY0 is an implementation of the formula function BESSELY.
1952 func (fn *formulaFuncs) besselY0(x formulaArg) float64 {
1953         var y float64
1954         if x.Number < 8 {
1955                 y = x.Number * x.Number
1956                 f1 := -2957821389.0 + y*(7062834065.0+y*(-512359803.6+y*(10879881.29+y*
1957                         (-86327.92757+y*228.4622733))))
1958                 f2 := 40076544269.0 + y*(745249964.8+y*(7189466.438+y*
1959                         (47447.26470+y*(226.1030244+y))))
1960                 args := list.New()
1961                 args.PushBack(x)
1962                 args.PushBack(newNumberFormulaArg(0))
1963                 return f1/f2 + 0.636619772*fn.BESSELJ(args).Number*math.Log(x.Number)
1964         }
1965         z := 8.0 / x.Number
1966         y = z * z
1967         xx := x.Number - 0.785398164
1968         f1 := 1 + y*(-0.1098628627e-2+y*(0.2734510407e-4+y*(-0.2073370639e-5+y*0.2093887211e-6)))
1969         f2 := -0.1562499995e-1 + y*(0.1430488765e-3+y*(-0.6911147651e-5+y*(0.7621095161e-6+y*
1970                 (-0.934945152e-7))))
1971         return math.Sqrt(0.636619772/x.Number) * (math.Sin(xx)*f1 + z*math.Cos(xx)*f2)
1972 }
1973
1974 // besselY1 is an implementation of the formula function BESSELY.
1975 func (fn *formulaFuncs) besselY1(x formulaArg) float64 {
1976         if x.Number < 8 {
1977                 y := x.Number * x.Number
1978                 f1 := x.Number * (-0.4900604943e13 + y*(0.1275274390e13+y*(-0.5153438139e11+y*
1979                         (0.7349264551e9+y*(-0.4237922726e7+y*0.8511937935e4)))))
1980                 f2 := 0.2499580570e14 + y*(0.4244419664e12+y*(0.3733650367e10+y*(0.2245904002e8+y*
1981                         (0.1020426050e6+y*(0.3549632885e3+y)))))
1982                 args := list.New()
1983                 args.PushBack(x)
1984                 args.PushBack(newNumberFormulaArg(1))
1985                 return f1/f2 + 0.636619772*(fn.BESSELJ(args).Number*math.Log(x.Number)-1/x.Number)
1986         }
1987         return math.Sqrt(0.636619772/x.Number) * math.Sin(x.Number-2.356194491)
1988 }
1989
1990 // besselY2 is an implementation of the formula function BESSELY.
1991 func (fn *formulaFuncs) besselY2(x, n formulaArg) float64 {
1992         tox, bym, by, byp := 2/x.Number, fn.besselY0(x), fn.besselY1(x), 0.0
1993         for i := 1.0; i < n.Number; i++ {
1994                 byp = i*tox*by - bym
1995                 bym = by
1996                 by = byp
1997         }
1998         return by
1999 }
2000
2001 // BIN2DEC function converts a Binary (a base-2 number) into a decimal number.
2002 // The syntax of the function is:
2003 //
2004 //      BIN2DEC(number)
2005 func (fn *formulaFuncs) BIN2DEC(argsList *list.List) formulaArg {
2006         if argsList.Len() != 1 {
2007                 return newErrorFormulaArg(formulaErrorVALUE, "BIN2DEC requires 1 numeric argument")
2008         }
2009         token := argsList.Front().Value.(formulaArg)
2010         number := token.ToNumber()
2011         if number.Type != ArgNumber {
2012                 return newErrorFormulaArg(formulaErrorVALUE, number.Error)
2013         }
2014         return fn.bin2dec(token.Value())
2015 }
2016
2017 // BIN2HEX function converts a Binary (Base 2) number into a Hexadecimal
2018 // (Base 16) number. The syntax of the function is:
2019 //
2020 //      BIN2HEX(number,[places])
2021 func (fn *formulaFuncs) BIN2HEX(argsList *list.List) formulaArg {
2022         if argsList.Len() < 1 {
2023                 return newErrorFormulaArg(formulaErrorVALUE, "BIN2HEX requires at least 1 argument")
2024         }
2025         if argsList.Len() > 2 {
2026                 return newErrorFormulaArg(formulaErrorVALUE, "BIN2HEX allows at most 2 arguments")
2027         }
2028         token := argsList.Front().Value.(formulaArg)
2029         number := token.ToNumber()
2030         if number.Type != ArgNumber {
2031                 return newErrorFormulaArg(formulaErrorVALUE, number.Error)
2032         }
2033         decimal, newList := fn.bin2dec(token.Value()), list.New()
2034         if decimal.Type != ArgNumber {
2035                 return decimal
2036         }
2037         newList.PushBack(decimal)
2038         if argsList.Len() == 2 {
2039                 newList.PushBack(argsList.Back().Value.(formulaArg))
2040         }
2041         return fn.dec2x("BIN2HEX", newList)
2042 }
2043
2044 // BIN2OCT function converts a Binary (Base 2) number into an Octal (Base 8)
2045 // number. The syntax of the function is:
2046 //
2047 //      BIN2OCT(number,[places])
2048 func (fn *formulaFuncs) BIN2OCT(argsList *list.List) formulaArg {
2049         if argsList.Len() < 1 {
2050                 return newErrorFormulaArg(formulaErrorVALUE, "BIN2OCT requires at least 1 argument")
2051         }
2052         if argsList.Len() > 2 {
2053                 return newErrorFormulaArg(formulaErrorVALUE, "BIN2OCT allows at most 2 arguments")
2054         }
2055         token := argsList.Front().Value.(formulaArg)
2056         number := token.ToNumber()
2057         if number.Type != ArgNumber {
2058                 return newErrorFormulaArg(formulaErrorVALUE, number.Error)
2059         }
2060         decimal, newList := fn.bin2dec(token.Value()), list.New()
2061         if decimal.Type != ArgNumber {
2062                 return decimal
2063         }
2064         newList.PushBack(decimal)
2065         if argsList.Len() == 2 {
2066                 newList.PushBack(argsList.Back().Value.(formulaArg))
2067         }
2068         return fn.dec2x("BIN2OCT", newList)
2069 }
2070
2071 // bin2dec is an implementation of the formula function BIN2DEC.
2072 func (fn *formulaFuncs) bin2dec(number string) formulaArg {
2073         decimal, length := 0.0, len(number)
2074         for i := length; i > 0; i-- {
2075                 s := string(number[length-i])
2076                 if i == 10 && s == "1" {
2077                         decimal += math.Pow(-2.0, float64(i-1))
2078                         continue
2079                 }
2080                 if s == "1" {
2081                         decimal += math.Pow(2.0, float64(i-1))
2082                         continue
2083                 }
2084                 if s != "0" {
2085                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
2086                 }
2087         }
2088         return newNumberFormulaArg(decimal)
2089 }
2090
2091 // BITAND function returns the bitwise 'AND' for two supplied integers. The
2092 // syntax of the function is:
2093 //
2094 //      BITAND(number1,number2)
2095 func (fn *formulaFuncs) BITAND(argsList *list.List) formulaArg {
2096         return fn.bitwise("BITAND", argsList)
2097 }
2098
2099 // BITLSHIFT function returns a supplied integer, shifted left by a specified
2100 // number of bits. The syntax of the function is:
2101 //
2102 //      BITLSHIFT(number1,shift_amount)
2103 func (fn *formulaFuncs) BITLSHIFT(argsList *list.List) formulaArg {
2104         return fn.bitwise("BITLSHIFT", argsList)
2105 }
2106
2107 // BITOR function returns the bitwise 'OR' for two supplied integers. The
2108 // syntax of the function is:
2109 //
2110 //      BITOR(number1,number2)
2111 func (fn *formulaFuncs) BITOR(argsList *list.List) formulaArg {
2112         return fn.bitwise("BITOR", argsList)
2113 }
2114
2115 // BITRSHIFT function returns a supplied integer, shifted right by a specified
2116 // number of bits. The syntax of the function is:
2117 //
2118 //      BITRSHIFT(number1,shift_amount)
2119 func (fn *formulaFuncs) BITRSHIFT(argsList *list.List) formulaArg {
2120         return fn.bitwise("BITRSHIFT", argsList)
2121 }
2122
2123 // BITXOR function returns the bitwise 'XOR' (exclusive 'OR') for two supplied
2124 // integers. The syntax of the function is:
2125 //
2126 //      BITXOR(number1,number2)
2127 func (fn *formulaFuncs) BITXOR(argsList *list.List) formulaArg {
2128         return fn.bitwise("BITXOR", argsList)
2129 }
2130
2131 // bitwise is an implementation of the formula functions BITAND, BITLSHIFT,
2132 // BITOR, BITRSHIFT and BITXOR.
2133 func (fn *formulaFuncs) bitwise(name string, argsList *list.List) formulaArg {
2134         if argsList.Len() != 2 {
2135                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 numeric arguments", name))
2136         }
2137         num1, num2 := argsList.Front().Value.(formulaArg).ToNumber(), argsList.Back().Value.(formulaArg).ToNumber()
2138         if num1.Type != ArgNumber || num2.Type != ArgNumber {
2139                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
2140         }
2141         max := math.Pow(2, 48) - 1
2142         if num1.Number < 0 || num1.Number > max || num2.Number < 0 || num2.Number > max {
2143                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
2144         }
2145         bitwiseFuncMap := map[string]func(a, b int) int{
2146                 "BITAND":    func(a, b int) int { return a & b },
2147                 "BITLSHIFT": func(a, b int) int { return a << uint(b) },
2148                 "BITOR":     func(a, b int) int { return a | b },
2149                 "BITRSHIFT": func(a, b int) int { return a >> uint(b) },
2150                 "BITXOR":    func(a, b int) int { return a ^ b },
2151         }
2152         bitwiseFunc := bitwiseFuncMap[name]
2153         return newNumberFormulaArg(float64(bitwiseFunc(int(num1.Number), int(num2.Number))))
2154 }
2155
2156 // COMPLEX function takes two arguments, representing the real and the
2157 // imaginary coefficients of a complex number, and from these, creates a
2158 // complex number. The syntax of the function is:
2159 //
2160 //      COMPLEX(real_num,i_num,[suffix])
2161 func (fn *formulaFuncs) COMPLEX(argsList *list.List) formulaArg {
2162         if argsList.Len() < 2 {
2163                 return newErrorFormulaArg(formulaErrorVALUE, "COMPLEX requires at least 2 arguments")
2164         }
2165         if argsList.Len() > 3 {
2166                 return newErrorFormulaArg(formulaErrorVALUE, "COMPLEX allows at most 3 arguments")
2167         }
2168         realNum, i, suffix := argsList.Front().Value.(formulaArg).ToNumber(), argsList.Front().Next().Value.(formulaArg).ToNumber(), "i"
2169         if realNum.Type != ArgNumber {
2170                 return realNum
2171         }
2172         if i.Type != ArgNumber {
2173                 return i
2174         }
2175         if argsList.Len() == 3 {
2176                 if suffix = strings.ToLower(argsList.Back().Value.(formulaArg).Value()); suffix != "i" && suffix != "j" {
2177                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
2178                 }
2179         }
2180         return newStringFormulaArg(cmplx2str(complex(realNum.Number, i.Number), suffix))
2181 }
2182
2183 // cmplx2str replace complex number string characters.
2184 func cmplx2str(num complex128, suffix string) string {
2185         realPart, imagPart := fmt.Sprint(real(num)), fmt.Sprint(imag(num))
2186         isNum, i, decimal := isNumeric(realPart)
2187         if isNum && i > 15 {
2188                 realPart = strconv.FormatFloat(decimal, 'G', 15, 64)
2189         }
2190         isNum, i, decimal = isNumeric(imagPart)
2191         if isNum && i > 15 {
2192                 imagPart = strconv.FormatFloat(decimal, 'G', 15, 64)
2193         }
2194         c := realPart
2195         if imag(num) > 0 {
2196                 c += "+"
2197         }
2198         if imag(num) != 0 {
2199                 c += imagPart + "i"
2200         }
2201         c = strings.TrimPrefix(c, "(")
2202         c = strings.TrimPrefix(c, "+0+")
2203         c = strings.TrimPrefix(c, "-0+")
2204         c = strings.TrimSuffix(c, ")")
2205         c = strings.TrimPrefix(c, "0+")
2206         if strings.HasPrefix(c, "0-") {
2207                 c = "-" + strings.TrimPrefix(c, "0-")
2208         }
2209         c = strings.TrimPrefix(c, "0+")
2210         c = strings.TrimSuffix(c, "+0i")
2211         c = strings.TrimSuffix(c, "-0i")
2212         c = strings.NewReplacer("+1i", "+i", "-1i", "-i").Replace(c)
2213         c = strings.ReplaceAll(c, "i", suffix)
2214         return c
2215 }
2216
2217 // str2cmplx convert complex number string characters.
2218 func str2cmplx(c string) string {
2219         c = strings.ReplaceAll(c, "j", "i")
2220         if c == "i" {
2221                 c = "1i"
2222         }
2223         c = strings.NewReplacer("+i", "+1i", "-i", "-1i").Replace(c)
2224         return c
2225 }
2226
2227 // conversionUnit defined unit info for conversion.
2228 type conversionUnit struct {
2229         group       uint8
2230         allowPrefix bool
2231 }
2232
2233 // conversionUnits maps info list for unit conversion, that can be used in
2234 // formula function CONVERT.
2235 var conversionUnits = map[string]conversionUnit{
2236         // weight and mass
2237         "g":        {group: categoryWeightAndMass, allowPrefix: true},
2238         "sg":       {group: categoryWeightAndMass, allowPrefix: false},
2239         "lbm":      {group: categoryWeightAndMass, allowPrefix: false},
2240         "u":        {group: categoryWeightAndMass, allowPrefix: true},
2241         "ozm":      {group: categoryWeightAndMass, allowPrefix: false},
2242         "grain":    {group: categoryWeightAndMass, allowPrefix: false},
2243         "cwt":      {group: categoryWeightAndMass, allowPrefix: false},
2244         "shweight": {group: categoryWeightAndMass, allowPrefix: false},
2245         "uk_cwt":   {group: categoryWeightAndMass, allowPrefix: false},
2246         "lcwt":     {group: categoryWeightAndMass, allowPrefix: false},
2247         "hweight":  {group: categoryWeightAndMass, allowPrefix: false},
2248         "stone":    {group: categoryWeightAndMass, allowPrefix: false},
2249         "ton":      {group: categoryWeightAndMass, allowPrefix: false},
2250         "uk_ton":   {group: categoryWeightAndMass, allowPrefix: false},
2251         "LTON":     {group: categoryWeightAndMass, allowPrefix: false},
2252         "brton":    {group: categoryWeightAndMass, allowPrefix: false},
2253         // distance
2254         "m":         {group: categoryDistance, allowPrefix: true},
2255         "mi":        {group: categoryDistance, allowPrefix: false},
2256         "Nmi":       {group: categoryDistance, allowPrefix: false},
2257         "in":        {group: categoryDistance, allowPrefix: false},
2258         "ft":        {group: categoryDistance, allowPrefix: false},
2259         "yd":        {group: categoryDistance, allowPrefix: false},
2260         "ang":       {group: categoryDistance, allowPrefix: true},
2261         "ell":       {group: categoryDistance, allowPrefix: false},
2262         "ly":        {group: categoryDistance, allowPrefix: false},
2263         "parsec":    {group: categoryDistance, allowPrefix: false},
2264         "pc":        {group: categoryDistance, allowPrefix: false},
2265         "Pica":      {group: categoryDistance, allowPrefix: false},
2266         "Picapt":    {group: categoryDistance, allowPrefix: false},
2267         "pica":      {group: categoryDistance, allowPrefix: false},
2268         "survey_mi": {group: categoryDistance, allowPrefix: false},
2269         // time
2270         "yr":  {group: categoryTime, allowPrefix: false},
2271         "day": {group: categoryTime, allowPrefix: false},
2272         "d":   {group: categoryTime, allowPrefix: false},
2273         "hr":  {group: categoryTime, allowPrefix: false},
2274         "mn":  {group: categoryTime, allowPrefix: false},
2275         "min": {group: categoryTime, allowPrefix: false},
2276         "sec": {group: categoryTime, allowPrefix: true},
2277         "s":   {group: categoryTime, allowPrefix: true},
2278         // pressure
2279         "Pa":   {group: categoryPressure, allowPrefix: true},
2280         "p":    {group: categoryPressure, allowPrefix: true},
2281         "atm":  {group: categoryPressure, allowPrefix: true},
2282         "at":   {group: categoryPressure, allowPrefix: true},
2283         "mmHg": {group: categoryPressure, allowPrefix: true},
2284         "psi":  {group: categoryPressure, allowPrefix: true},
2285         "Torr": {group: categoryPressure, allowPrefix: true},
2286         // force
2287         "N":    {group: categoryForce, allowPrefix: true},
2288         "dyn":  {group: categoryForce, allowPrefix: true},
2289         "dy":   {group: categoryForce, allowPrefix: true},
2290         "lbf":  {group: categoryForce, allowPrefix: false},
2291         "pond": {group: categoryForce, allowPrefix: true},
2292         // energy
2293         "J":   {group: categoryEnergy, allowPrefix: true},
2294         "e":   {group: categoryEnergy, allowPrefix: true},
2295         "c":   {group: categoryEnergy, allowPrefix: true},
2296         "cal": {group: categoryEnergy, allowPrefix: true},
2297         "eV":  {group: categoryEnergy, allowPrefix: true},
2298         "ev":  {group: categoryEnergy, allowPrefix: true},
2299         "HPh": {group: categoryEnergy, allowPrefix: false},
2300         "hh":  {group: categoryEnergy, allowPrefix: false},
2301         "Wh":  {group: categoryEnergy, allowPrefix: true},
2302         "wh":  {group: categoryEnergy, allowPrefix: true},
2303         "flb": {group: categoryEnergy, allowPrefix: false},
2304         "BTU": {group: categoryEnergy, allowPrefix: false},
2305         "btu": {group: categoryEnergy, allowPrefix: false},
2306         // power
2307         "HP": {group: categoryPower, allowPrefix: false},
2308         "h":  {group: categoryPower, allowPrefix: false},
2309         "W":  {group: categoryPower, allowPrefix: true},
2310         "w":  {group: categoryPower, allowPrefix: true},
2311         "PS": {group: categoryPower, allowPrefix: false},
2312         "T":  {group: categoryMagnetism, allowPrefix: true},
2313         "ga": {group: categoryMagnetism, allowPrefix: true},
2314         // temperature
2315         "C":    {group: categoryTemperature, allowPrefix: false},
2316         "cel":  {group: categoryTemperature, allowPrefix: false},
2317         "F":    {group: categoryTemperature, allowPrefix: false},
2318         "fah":  {group: categoryTemperature, allowPrefix: false},
2319         "K":    {group: categoryTemperature, allowPrefix: false},
2320         "kel":  {group: categoryTemperature, allowPrefix: false},
2321         "Rank": {group: categoryTemperature, allowPrefix: false},
2322         "Reau": {group: categoryTemperature, allowPrefix: false},
2323         // volume
2324         "l":        {group: categoryVolumeAndLiquidMeasure, allowPrefix: true},
2325         "L":        {group: categoryVolumeAndLiquidMeasure, allowPrefix: true},
2326         "lt":       {group: categoryVolumeAndLiquidMeasure, allowPrefix: true},
2327         "tsp":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2328         "tspm":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2329         "tbs":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2330         "oz":       {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2331         "cup":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2332         "pt":       {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2333         "us_pt":    {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2334         "uk_pt":    {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2335         "qt":       {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2336         "uk_qt":    {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2337         "gal":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2338         "uk_gal":   {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2339         "ang3":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: true},
2340         "ang^3":    {group: categoryVolumeAndLiquidMeasure, allowPrefix: true},
2341         "barrel":   {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2342         "bushel":   {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2343         "in3":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2344         "in^3":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2345         "ft3":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2346         "ft^3":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2347         "ly3":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2348         "ly^3":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2349         "m3":       {group: categoryVolumeAndLiquidMeasure, allowPrefix: true},
2350         "m^3":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: true},
2351         "mi3":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2352         "mi^3":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2353         "yd3":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2354         "yd^3":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2355         "Nmi3":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2356         "Nmi^3":    {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2357         "Pica3":    {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2358         "Pica^3":   {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2359         "Picapt3":  {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2360         "Picapt^3": {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2361         "GRT":      {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2362         "regton":   {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2363         "MTON":     {group: categoryVolumeAndLiquidMeasure, allowPrefix: false},
2364         // area
2365         "ha":       {group: categoryArea, allowPrefix: true},
2366         "uk_acre":  {group: categoryArea, allowPrefix: false},
2367         "us_acre":  {group: categoryArea, allowPrefix: false},
2368         "ang2":     {group: categoryArea, allowPrefix: true},
2369         "ang^2":    {group: categoryArea, allowPrefix: true},
2370         "ar":       {group: categoryArea, allowPrefix: true},
2371         "ft2":      {group: categoryArea, allowPrefix: false},
2372         "ft^2":     {group: categoryArea, allowPrefix: false},
2373         "in2":      {group: categoryArea, allowPrefix: false},
2374         "in^2":     {group: categoryArea, allowPrefix: false},
2375         "ly2":      {group: categoryArea, allowPrefix: false},
2376         "ly^2":     {group: categoryArea, allowPrefix: false},
2377         "m2":       {group: categoryArea, allowPrefix: true},
2378         "m^2":      {group: categoryArea, allowPrefix: true},
2379         "Morgen":   {group: categoryArea, allowPrefix: false},
2380         "mi2":      {group: categoryArea, allowPrefix: false},
2381         "mi^2":     {group: categoryArea, allowPrefix: false},
2382         "Nmi2":     {group: categoryArea, allowPrefix: false},
2383         "Nmi^2":    {group: categoryArea, allowPrefix: false},
2384         "Pica2":    {group: categoryArea, allowPrefix: false},
2385         "Pica^2":   {group: categoryArea, allowPrefix: false},
2386         "Picapt2":  {group: categoryArea, allowPrefix: false},
2387         "Picapt^2": {group: categoryArea, allowPrefix: false},
2388         "yd2":      {group: categoryArea, allowPrefix: false},
2389         "yd^2":     {group: categoryArea, allowPrefix: false},
2390         // information
2391         "byte": {group: categoryInformation, allowPrefix: true},
2392         "bit":  {group: categoryInformation, allowPrefix: true},
2393         // speed
2394         "m/s":   {group: categorySpeed, allowPrefix: true},
2395         "m/sec": {group: categorySpeed, allowPrefix: true},
2396         "m/h":   {group: categorySpeed, allowPrefix: true},
2397         "m/hr":  {group: categorySpeed, allowPrefix: true},
2398         "mph":   {group: categorySpeed, allowPrefix: false},
2399         "admkn": {group: categorySpeed, allowPrefix: false},
2400         "kn":    {group: categorySpeed, allowPrefix: false},
2401 }
2402
2403 // unitConversions maps details of the Units of measure conversion factors,
2404 // organised by group.
2405 var unitConversions = map[byte]map[string]float64{
2406         // conversion uses gram (g) as an intermediate unit
2407         categoryWeightAndMass: {
2408                 "g":        1,
2409                 "sg":       6.85217658567918e-05,
2410                 "lbm":      2.20462262184878e-03,
2411                 "u":        6.02214179421676e+23,
2412                 "ozm":      3.52739619495804e-02,
2413                 "grain":    1.54323583529414e+01,
2414                 "cwt":      2.20462262184878e-05,
2415                 "shweight": 2.20462262184878e-05,
2416                 "uk_cwt":   1.96841305522212e-05,
2417                 "lcwt":     1.96841305522212e-05,
2418                 "hweight":  1.96841305522212e-05,
2419                 "stone":    1.57473044417770e-04,
2420                 "ton":      1.10231131092439e-06,
2421                 "uk_ton":   9.84206527611061e-07,
2422                 "LTON":     9.84206527611061e-07,
2423                 "brton":    9.84206527611061e-07,
2424         },
2425         // conversion uses meter (m) as an intermediate unit
2426         categoryDistance: {
2427                 "m":         1,
2428                 "mi":        6.21371192237334e-04,
2429                 "Nmi":       5.39956803455724e-04,
2430                 "in":        3.93700787401575e+01,
2431                 "ft":        3.28083989501312e+00,
2432                 "yd":        1.09361329833771e+00,
2433                 "ang":       1.0e+10,
2434                 "ell":       8.74890638670166e-01,
2435                 "ly":        1.05700083402462e-16,
2436                 "parsec":    3.24077928966473e-17,
2437                 "pc":        3.24077928966473e-17,
2438                 "Pica":      2.83464566929134e+03,
2439                 "Picapt":    2.83464566929134e+03,
2440                 "pica":      2.36220472440945e+02,
2441                 "survey_mi": 6.21369949494950e-04,
2442         },
2443         // conversion uses second (s) as an intermediate unit
2444         categoryTime: {
2445                 "yr":  3.16880878140289e-08,
2446                 "day": 1.15740740740741e-05,
2447                 "d":   1.15740740740741e-05,
2448                 "hr":  2.77777777777778e-04,
2449                 "mn":  1.66666666666667e-02,
2450                 "min": 1.66666666666667e-02,
2451                 "sec": 1,
2452                 "s":   1,
2453         },
2454         // conversion uses Pascal (Pa) as an intermediate unit
2455         categoryPressure: {
2456                 "Pa":   1,
2457                 "p":    1,
2458                 "atm":  9.86923266716013e-06,
2459                 "at":   9.86923266716013e-06,
2460                 "mmHg": 7.50063755419211e-03,
2461                 "psi":  1.45037737730209e-04,
2462                 "Torr": 7.50061682704170e-03,
2463         },
2464         // conversion uses Newton (N) as an intermediate unit
2465         categoryForce: {
2466                 "N":    1,
2467                 "dyn":  1.0e+5,
2468                 "dy":   1.0e+5,
2469                 "lbf":  2.24808923655339e-01,
2470                 "pond": 1.01971621297793e+02,
2471         },
2472         // conversion uses Joule (J) as an intermediate unit
2473         categoryEnergy: {
2474                 "J":   1,
2475                 "e":   9.99999519343231e+06,
2476                 "c":   2.39006249473467e-01,
2477                 "cal": 2.38846190642017e-01,
2478                 "eV":  6.24145700000000e+18,
2479                 "ev":  6.24145700000000e+18,
2480                 "HPh": 3.72506430801000e-07,
2481                 "hh":  3.72506430801000e-07,
2482                 "Wh":  2.77777916238711e-04,
2483                 "wh":  2.77777916238711e-04,
2484                 "flb": 2.37304222192651e+01,
2485                 "BTU": 9.47815067349015e-04,
2486                 "btu": 9.47815067349015e-04,
2487         },
2488         // conversion uses Horsepower (HP) as an intermediate unit
2489         categoryPower: {
2490                 "HP": 1,
2491                 "h":  1,
2492                 "W":  7.45699871582270e+02,
2493                 "w":  7.45699871582270e+02,
2494                 "PS": 1.01386966542400e+00,
2495         },
2496         // conversion uses Tesla (T) as an intermediate unit
2497         categoryMagnetism: {
2498                 "T":  1,
2499                 "ga": 10000,
2500         },
2501         // conversion uses litre (l) as an intermediate unit
2502         categoryVolumeAndLiquidMeasure: {
2503                 "l":        1,
2504                 "L":        1,
2505                 "lt":       1,
2506                 "tsp":      2.02884136211058e+02,
2507                 "tspm":     2.0e+02,
2508                 "tbs":      6.76280454036860e+01,
2509                 "oz":       3.38140227018430e+01,
2510                 "cup":      4.22675283773038e+00,
2511                 "pt":       2.11337641886519e+00,
2512                 "us_pt":    2.11337641886519e+00,
2513                 "uk_pt":    1.75975398639270e+00,
2514                 "qt":       1.05668820943259e+00,
2515                 "uk_qt":    8.79876993196351e-01,
2516                 "gal":      2.64172052358148e-01,
2517                 "uk_gal":   2.19969248299088e-01,
2518                 "ang3":     1.0e+27,
2519                 "ang^3":    1.0e+27,
2520                 "barrel":   6.28981077043211e-03,
2521                 "bushel":   2.83775932584017e-02,
2522                 "in3":      6.10237440947323e+01,
2523                 "in^3":     6.10237440947323e+01,
2524                 "ft3":      3.53146667214886e-02,
2525                 "ft^3":     3.53146667214886e-02,
2526                 "ly3":      1.18093498844171e-51,
2527                 "ly^3":     1.18093498844171e-51,
2528                 "m3":       1.0e-03,
2529                 "m^3":      1.0e-03,
2530                 "mi3":      2.39912758578928e-13,
2531                 "mi^3":     2.39912758578928e-13,
2532                 "yd3":      1.30795061931439e-03,
2533                 "yd^3":     1.30795061931439e-03,
2534                 "Nmi3":     1.57426214685811e-13,
2535                 "Nmi^3":    1.57426214685811e-13,
2536                 "Pica3":    2.27769904358706e+07,
2537                 "Pica^3":   2.27769904358706e+07,
2538                 "Picapt3":  2.27769904358706e+07,
2539                 "Picapt^3": 2.27769904358706e+07,
2540                 "GRT":      3.53146667214886e-04,
2541                 "regton":   3.53146667214886e-04,
2542                 "MTON":     8.82866668037215e-04,
2543         },
2544         // conversion uses hectare (ha) as an intermediate unit
2545         categoryArea: {
2546                 "ha":       1,
2547                 "uk_acre":  2.47105381467165e+00,
2548                 "us_acre":  2.47104393046628e+00,
2549                 "ang2":     1.0e+24,
2550                 "ang^2":    1.0e+24,
2551                 "ar":       1.0e+02,
2552                 "ft2":      1.07639104167097e+05,
2553                 "ft^2":     1.07639104167097e+05,
2554                 "in2":      1.55000310000620e+07,
2555                 "in^2":     1.55000310000620e+07,
2556                 "ly2":      1.11725076312873e-28,
2557                 "ly^2":     1.11725076312873e-28,
2558                 "m2":       1.0e+04,
2559                 "m^2":      1.0e+04,
2560                 "Morgen":   4.0e+00,
2561                 "mi2":      3.86102158542446e-03,
2562                 "mi^2":     3.86102158542446e-03,
2563                 "Nmi2":     2.91553349598123e-03,
2564                 "Nmi^2":    2.91553349598123e-03,
2565                 "Pica2":    8.03521607043214e+10,
2566                 "Pica^2":   8.03521607043214e+10,
2567                 "Picapt2":  8.03521607043214e+10,
2568                 "Picapt^2": 8.03521607043214e+10,
2569                 "yd2":      1.19599004630108e+04,
2570                 "yd^2":     1.19599004630108e+04,
2571         },
2572         // conversion uses bit (bit) as an intermediate unit
2573         categoryInformation: {
2574                 "bit":  1,
2575                 "byte": 0.125,
2576         },
2577         // conversion uses Meters per Second (m/s) as an intermediate unit
2578         categorySpeed: {
2579                 "m/s":   1,
2580                 "m/sec": 1,
2581                 "m/h":   3.60e+03,
2582                 "m/hr":  3.60e+03,
2583                 "mph":   2.23693629205440e+00,
2584                 "admkn": 1.94260256941567e+00,
2585                 "kn":    1.94384449244060e+00,
2586         },
2587 }
2588
2589 // conversionMultipliers maps details of the Multiplier prefixes that can be
2590 // used with Units of Measure in CONVERT.
2591 var conversionMultipliers = map[string]float64{
2592         "Y":  1e24,
2593         "Z":  1e21,
2594         "E":  1e18,
2595         "P":  1e15,
2596         "T":  1e12,
2597         "G":  1e9,
2598         "M":  1e6,
2599         "k":  1e3,
2600         "h":  1e2,
2601         "e":  1e1,
2602         "da": 1e1,
2603         "d":  1e-1,
2604         "c":  1e-2,
2605         "m":  1e-3,
2606         "u":  1e-6,
2607         "n":  1e-9,
2608         "p":  1e-12,
2609         "f":  1e-15,
2610         "a":  1e-18,
2611         "z":  1e-21,
2612         "y":  1e-24,
2613         "Yi": math.Pow(2, 80),
2614         "Zi": math.Pow(2, 70),
2615         "Ei": math.Pow(2, 60),
2616         "Pi": math.Pow(2, 50),
2617         "Ti": math.Pow(2, 40),
2618         "Gi": math.Pow(2, 30),
2619         "Mi": math.Pow(2, 20),
2620         "ki": math.Pow(2, 10),
2621 }
2622
2623 // getUnitDetails check and returns the unit of measure details.
2624 func getUnitDetails(uom string) (unit string, catgory byte, res float64, ok bool) {
2625         if len(uom) == 0 {
2626                 ok = false
2627                 return
2628         }
2629         if unit, ok := conversionUnits[uom]; ok {
2630                 return uom, unit.group, 1, ok
2631         }
2632         // 1 character standard metric multiplier prefixes
2633         multiplierType := uom[:1]
2634         uom = uom[1:]
2635         conversionUnit, ok1 := conversionUnits[uom]
2636         multiplier, ok2 := conversionMultipliers[multiplierType]
2637         if ok1 && ok2 {
2638                 if !conversionUnit.allowPrefix {
2639                         ok = false
2640                         return
2641                 }
2642                 unitCategory := conversionUnit.group
2643                 return uom, unitCategory, multiplier, true
2644         }
2645         // 2 character standard and binary metric multiplier prefixes
2646         if len(uom) > 0 {
2647                 multiplierType += uom[:1]
2648                 uom = uom[1:]
2649         }
2650         conversionUnit, ok1 = conversionUnits[uom]
2651         multiplier, ok2 = conversionMultipliers[multiplierType]
2652         if ok1 && ok2 {
2653                 if !conversionUnit.allowPrefix {
2654                         ok = false
2655                         return
2656                 }
2657                 unitCategory := conversionUnit.group
2658                 return uom, unitCategory, multiplier, true
2659         }
2660         ok = false
2661         return
2662 }
2663
2664 // resolveTemperatureSynonyms returns unit of measure according to a given
2665 // temperature synonyms.
2666 func resolveTemperatureSynonyms(uom string) string {
2667         switch uom {
2668         case "fah":
2669                 return "F"
2670         case "cel":
2671                 return "C"
2672         case "kel":
2673                 return "K"
2674         }
2675         return uom
2676 }
2677
2678 // convertTemperature returns converted temperature by a given unit of measure.
2679 func convertTemperature(fromUOM, toUOM string, value float64) float64 {
2680         fromUOM = resolveTemperatureSynonyms(fromUOM)
2681         toUOM = resolveTemperatureSynonyms(toUOM)
2682         if fromUOM == toUOM {
2683                 return value
2684         }
2685         // convert to Kelvin
2686         switch fromUOM {
2687         case "F":
2688                 value = (value-32)/1.8 + 273.15
2689         case "C":
2690                 value += 273.15
2691         case "Rank":
2692                 value /= 1.8
2693         case "Reau":
2694                 value = value*1.25 + 273.15
2695         }
2696         // convert from Kelvin
2697         switch toUOM {
2698         case "F":
2699                 value = (value-273.15)*1.8 + 32
2700         case "C":
2701                 value -= 273.15
2702         case "Rank":
2703                 value *= 1.8
2704         case "Reau":
2705                 value = (value - 273.15) * 0.8
2706         }
2707         return value
2708 }
2709
2710 // CONVERT function converts a number from one unit type (e.g. Yards) to
2711 // another unit type (e.g. Meters). The syntax of the function is:
2712 //
2713 //      CONVERT(number,from_unit,to_unit)
2714 func (fn *formulaFuncs) CONVERT(argsList *list.List) formulaArg {
2715         if argsList.Len() != 3 {
2716                 return newErrorFormulaArg(formulaErrorVALUE, "CONVERT requires 3 arguments")
2717         }
2718         num := argsList.Front().Value.(formulaArg).ToNumber()
2719         if num.Type != ArgNumber {
2720                 return num
2721         }
2722         fromUOM, fromCategory, fromMultiplier, ok1 := getUnitDetails(argsList.Front().Next().Value.(formulaArg).Value())
2723         toUOM, toCategory, toMultiplier, ok2 := getUnitDetails(argsList.Back().Value.(formulaArg).Value())
2724         if !ok1 || !ok2 || fromCategory != toCategory {
2725                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
2726         }
2727         val := num.Number * fromMultiplier
2728         if fromUOM == toUOM && fromMultiplier == toMultiplier {
2729                 return newNumberFormulaArg(val / fromMultiplier)
2730         } else if fromUOM == toUOM {
2731                 return newNumberFormulaArg(val / toMultiplier)
2732         } else if fromCategory == categoryTemperature {
2733                 return newNumberFormulaArg(convertTemperature(fromUOM, toUOM, val))
2734         }
2735         fromConversion := unitConversions[fromCategory][fromUOM]
2736         toConversion := unitConversions[fromCategory][toUOM]
2737         baseValue := val * (1 / fromConversion)
2738         return newNumberFormulaArg((baseValue * toConversion) / toMultiplier)
2739 }
2740
2741 // DEC2BIN function converts a decimal number into a Binary (Base 2) number.
2742 // The syntax of the function is:
2743 //
2744 //      DEC2BIN(number,[places])
2745 func (fn *formulaFuncs) DEC2BIN(argsList *list.List) formulaArg {
2746         return fn.dec2x("DEC2BIN", argsList)
2747 }
2748
2749 // DEC2HEX function converts a decimal number into a Hexadecimal (Base 16)
2750 // number. The syntax of the function is:
2751 //
2752 //      DEC2HEX(number,[places])
2753 func (fn *formulaFuncs) DEC2HEX(argsList *list.List) formulaArg {
2754         return fn.dec2x("DEC2HEX", argsList)
2755 }
2756
2757 // DEC2OCT function converts a decimal number into an Octal (Base 8) number.
2758 // The syntax of the function is:
2759 //
2760 //      DEC2OCT(number,[places])
2761 func (fn *formulaFuncs) DEC2OCT(argsList *list.List) formulaArg {
2762         return fn.dec2x("DEC2OCT", argsList)
2763 }
2764
2765 // dec2x is an implementation of the formula functions DEC2BIN, DEC2HEX and
2766 // DEC2OCT.
2767 func (fn *formulaFuncs) dec2x(name string, argsList *list.List) formulaArg {
2768         if argsList.Len() < 1 {
2769                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
2770         }
2771         if argsList.Len() > 2 {
2772                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s allows at most 2 arguments", name))
2773         }
2774         decimal := argsList.Front().Value.(formulaArg).ToNumber()
2775         if decimal.Type != ArgNumber {
2776                 return newErrorFormulaArg(formulaErrorVALUE, decimal.Error)
2777         }
2778         maxLimitMap := map[string]float64{
2779                 "DEC2BIN": 511,
2780                 "HEX2BIN": 511,
2781                 "OCT2BIN": 511,
2782                 "BIN2HEX": 549755813887,
2783                 "DEC2HEX": 549755813887,
2784                 "OCT2HEX": 549755813887,
2785                 "BIN2OCT": 536870911,
2786                 "DEC2OCT": 536870911,
2787                 "HEX2OCT": 536870911,
2788         }
2789         minLimitMap := map[string]float64{
2790                 "DEC2BIN": -512,
2791                 "HEX2BIN": -512,
2792                 "OCT2BIN": -512,
2793                 "BIN2HEX": -549755813888,
2794                 "DEC2HEX": -549755813888,
2795                 "OCT2HEX": -549755813888,
2796                 "BIN2OCT": -536870912,
2797                 "DEC2OCT": -536870912,
2798                 "HEX2OCT": -536870912,
2799         }
2800         baseMap := map[string]int{
2801                 "DEC2BIN": 2,
2802                 "HEX2BIN": 2,
2803                 "OCT2BIN": 2,
2804                 "BIN2HEX": 16,
2805                 "DEC2HEX": 16,
2806                 "OCT2HEX": 16,
2807                 "BIN2OCT": 8,
2808                 "DEC2OCT": 8,
2809                 "HEX2OCT": 8,
2810         }
2811         maxLimit, minLimit := maxLimitMap[name], minLimitMap[name]
2812         base := baseMap[name]
2813         if decimal.Number < minLimit || decimal.Number > maxLimit {
2814                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
2815         }
2816         n := int64(decimal.Number)
2817         binary := strconv.FormatUint(*(*uint64)(unsafe.Pointer(&n)), base)
2818         if argsList.Len() == 2 {
2819                 places := argsList.Back().Value.(formulaArg).ToNumber()
2820                 if places.Type != ArgNumber {
2821                         return newErrorFormulaArg(formulaErrorVALUE, places.Error)
2822                 }
2823                 binaryPlaces := len(binary)
2824                 if places.Number < 0 || places.Number > 10 || binaryPlaces > int(places.Number) {
2825                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
2826                 }
2827                 return newStringFormulaArg(strings.ToUpper(fmt.Sprintf("%s%s", strings.Repeat("0", int(places.Number)-binaryPlaces), binary)))
2828         }
2829         if decimal.Number < 0 && len(binary) > 10 {
2830                 return newStringFormulaArg(strings.ToUpper(binary[len(binary)-10:]))
2831         }
2832         return newStringFormulaArg(strings.ToUpper(binary))
2833 }
2834
2835 // DELTA function tests two numbers for equality and returns the Kronecker
2836 // Delta. i.e. the function returns 1 if the two supplied numbers are equal
2837 // and 0 otherwise. The syntax of the function is:
2838 //
2839 //      DELTA(number1,[number2])
2840 func (fn *formulaFuncs) DELTA(argsList *list.List) formulaArg {
2841         if argsList.Len() < 1 {
2842                 return newErrorFormulaArg(formulaErrorVALUE, "DELTA requires at least 1 argument")
2843         }
2844         if argsList.Len() > 2 {
2845                 return newErrorFormulaArg(formulaErrorVALUE, "DELTA allows at most 2 arguments")
2846         }
2847         number1 := argsList.Front().Value.(formulaArg).ToNumber()
2848         if number1.Type != ArgNumber {
2849                 return number1
2850         }
2851         number2 := newNumberFormulaArg(0)
2852         if argsList.Len() == 2 {
2853                 if number2 = argsList.Back().Value.(formulaArg).ToNumber(); number2.Type != ArgNumber {
2854                         return number2
2855                 }
2856         }
2857         return newBoolFormulaArg(number1.Number == number2.Number).ToNumber()
2858 }
2859
2860 // ERF function calculates the Error Function, integrated between two supplied
2861 // limits. The syntax of the function is:
2862 //
2863 //      ERF(lower_limit,[upper_limit])
2864 func (fn *formulaFuncs) ERF(argsList *list.List) formulaArg {
2865         if argsList.Len() < 1 {
2866                 return newErrorFormulaArg(formulaErrorVALUE, "ERF requires at least 1 argument")
2867         }
2868         if argsList.Len() > 2 {
2869                 return newErrorFormulaArg(formulaErrorVALUE, "ERF allows at most 2 arguments")
2870         }
2871         lower := argsList.Front().Value.(formulaArg).ToNumber()
2872         if lower.Type != ArgNumber {
2873                 return lower
2874         }
2875         if argsList.Len() == 2 {
2876                 upper := argsList.Back().Value.(formulaArg).ToNumber()
2877                 if upper.Type != ArgNumber {
2878                         return upper
2879                 }
2880                 return newNumberFormulaArg(math.Erf(upper.Number) - math.Erf(lower.Number))
2881         }
2882         return newNumberFormulaArg(math.Erf(lower.Number))
2883 }
2884
2885 // ERFdotPRECISE function calculates the Error Function, integrated between a
2886 // supplied lower or upper limit and 0. The syntax of the function is:
2887 //
2888 //      ERF.PRECISE(x)
2889 func (fn *formulaFuncs) ERFdotPRECISE(argsList *list.List) formulaArg {
2890         if argsList.Len() != 1 {
2891                 return newErrorFormulaArg(formulaErrorVALUE, "ERF.PRECISE requires 1 argument")
2892         }
2893         x := argsList.Front().Value.(formulaArg).ToNumber()
2894         if x.Type != ArgNumber {
2895                 return x
2896         }
2897         return newNumberFormulaArg(math.Erf(x.Number))
2898 }
2899
2900 // erfc is an implementation of the formula functions ERFC and ERFC.PRECISE.
2901 func (fn *formulaFuncs) erfc(name string, argsList *list.List) formulaArg {
2902         if argsList.Len() != 1 {
2903                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 1 argument", name))
2904         }
2905         x := argsList.Front().Value.(formulaArg).ToNumber()
2906         if x.Type != ArgNumber {
2907                 return x
2908         }
2909         return newNumberFormulaArg(math.Erfc(x.Number))
2910 }
2911
2912 // ERFC function calculates the Complementary Error Function, integrated
2913 // between a supplied lower limit and infinity. The syntax of the function
2914 // is:
2915 //
2916 //      ERFC(x)
2917 func (fn *formulaFuncs) ERFC(argsList *list.List) formulaArg {
2918         return fn.erfc("ERFC", argsList)
2919 }
2920
2921 // ERFCdotPRECISE function calculates the Complementary Error Function,
2922 // integrated between a supplied lower limit and infinity. The syntax of the
2923 // function is:
2924 //
2925 //      ERFC(x)
2926 func (fn *formulaFuncs) ERFCdotPRECISE(argsList *list.List) formulaArg {
2927         return fn.erfc("ERFC.PRECISE", argsList)
2928 }
2929
2930 // GESTEP unction tests whether a supplied number is greater than a supplied
2931 // step size and returns. The syntax of the function is:
2932 //
2933 //      GESTEP(number,[step])
2934 func (fn *formulaFuncs) GESTEP(argsList *list.List) formulaArg {
2935         if argsList.Len() < 1 {
2936                 return newErrorFormulaArg(formulaErrorVALUE, "GESTEP requires at least 1 argument")
2937         }
2938         if argsList.Len() > 2 {
2939                 return newErrorFormulaArg(formulaErrorVALUE, "GESTEP allows at most 2 arguments")
2940         }
2941         number := argsList.Front().Value.(formulaArg).ToNumber()
2942         if number.Type != ArgNumber {
2943                 return number
2944         }
2945         step := newNumberFormulaArg(0)
2946         if argsList.Len() == 2 {
2947                 if step = argsList.Back().Value.(formulaArg).ToNumber(); step.Type != ArgNumber {
2948                         return step
2949                 }
2950         }
2951         return newBoolFormulaArg(number.Number >= step.Number).ToNumber()
2952 }
2953
2954 // HEX2BIN function converts a Hexadecimal (Base 16) number into a Binary
2955 // (Base 2) number. The syntax of the function is:
2956 //
2957 //      HEX2BIN(number,[places])
2958 func (fn *formulaFuncs) HEX2BIN(argsList *list.List) formulaArg {
2959         if argsList.Len() < 1 {
2960                 return newErrorFormulaArg(formulaErrorVALUE, "HEX2BIN requires at least 1 argument")
2961         }
2962         if argsList.Len() > 2 {
2963                 return newErrorFormulaArg(formulaErrorVALUE, "HEX2BIN allows at most 2 arguments")
2964         }
2965         decimal, newList := fn.hex2dec(argsList.Front().Value.(formulaArg).Value()), list.New()
2966         if decimal.Type != ArgNumber {
2967                 return decimal
2968         }
2969         newList.PushBack(decimal)
2970         if argsList.Len() == 2 {
2971                 newList.PushBack(argsList.Back().Value.(formulaArg))
2972         }
2973         return fn.dec2x("HEX2BIN", newList)
2974 }
2975
2976 // HEX2DEC function converts a hexadecimal (a base-16 number) into a decimal
2977 // number. The syntax of the function is:
2978 //
2979 //      HEX2DEC(number)
2980 func (fn *formulaFuncs) HEX2DEC(argsList *list.List) formulaArg {
2981         if argsList.Len() != 1 {
2982                 return newErrorFormulaArg(formulaErrorVALUE, "HEX2DEC requires 1 numeric argument")
2983         }
2984         return fn.hex2dec(argsList.Front().Value.(formulaArg).Value())
2985 }
2986
2987 // HEX2OCT function converts a Hexadecimal (Base 16) number into an Octal
2988 // (Base 8) number. The syntax of the function is:
2989 //
2990 //      HEX2OCT(number,[places])
2991 func (fn *formulaFuncs) HEX2OCT(argsList *list.List) formulaArg {
2992         if argsList.Len() < 1 {
2993                 return newErrorFormulaArg(formulaErrorVALUE, "HEX2OCT requires at least 1 argument")
2994         }
2995         if argsList.Len() > 2 {
2996                 return newErrorFormulaArg(formulaErrorVALUE, "HEX2OCT allows at most 2 arguments")
2997         }
2998         decimal, newList := fn.hex2dec(argsList.Front().Value.(formulaArg).Value()), list.New()
2999         if decimal.Type != ArgNumber {
3000                 return decimal
3001         }
3002         newList.PushBack(decimal)
3003         if argsList.Len() == 2 {
3004                 newList.PushBack(argsList.Back().Value.(formulaArg))
3005         }
3006         return fn.dec2x("HEX2OCT", newList)
3007 }
3008
3009 // hex2dec is an implementation of the formula function HEX2DEC.
3010 func (fn *formulaFuncs) hex2dec(number string) formulaArg {
3011         decimal, length := 0.0, len(number)
3012         for i := length; i > 0; i-- {
3013                 num, err := strconv.ParseInt(string(number[length-i]), 16, 64)
3014                 if err != nil {
3015                         return newErrorFormulaArg(formulaErrorNUM, err.Error())
3016                 }
3017                 if i == 10 && string(number[length-i]) == "F" {
3018                         decimal += math.Pow(-16.0, float64(i-1))
3019                         continue
3020                 }
3021                 decimal += float64(num) * math.Pow(16.0, float64(i-1))
3022         }
3023         return newNumberFormulaArg(decimal)
3024 }
3025
3026 // IMABS function returns the absolute value (the modulus) of a complex
3027 // number. The syntax of the function is:
3028 //
3029 //      IMABS(inumber)
3030 func (fn *formulaFuncs) IMABS(argsList *list.List) formulaArg {
3031         if argsList.Len() != 1 {
3032                 return newErrorFormulaArg(formulaErrorVALUE, "IMABS requires 1 argument")
3033         }
3034         value := argsList.Front().Value.(formulaArg).Value()
3035         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3036         if err != nil {
3037                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3038         }
3039         return newNumberFormulaArg(cmplx.Abs(inumber))
3040 }
3041
3042 // IMAGINARY function returns the imaginary coefficient of a supplied complex
3043 // number. The syntax of the function is:
3044 //
3045 //      IMAGINARY(inumber)
3046 func (fn *formulaFuncs) IMAGINARY(argsList *list.List) formulaArg {
3047         if argsList.Len() != 1 {
3048                 return newErrorFormulaArg(formulaErrorVALUE, "IMAGINARY requires 1 argument")
3049         }
3050         value := argsList.Front().Value.(formulaArg).Value()
3051         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3052         if err != nil {
3053                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3054         }
3055         return newNumberFormulaArg(imag(inumber))
3056 }
3057
3058 // IMARGUMENT function returns the phase (also called the argument) of a
3059 // supplied complex number. The syntax of the function is:
3060 //
3061 //      IMARGUMENT(inumber)
3062 func (fn *formulaFuncs) IMARGUMENT(argsList *list.List) formulaArg {
3063         if argsList.Len() != 1 {
3064                 return newErrorFormulaArg(formulaErrorVALUE, "IMARGUMENT requires 1 argument")
3065         }
3066         value := argsList.Front().Value.(formulaArg).Value()
3067         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3068         if err != nil {
3069                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3070         }
3071         return newNumberFormulaArg(cmplx.Phase(inumber))
3072 }
3073
3074 // IMCONJUGATE function returns the complex conjugate of a supplied complex
3075 // number. The syntax of the function is:
3076 //
3077 //      IMCONJUGATE(inumber)
3078 func (fn *formulaFuncs) IMCONJUGATE(argsList *list.List) formulaArg {
3079         if argsList.Len() != 1 {
3080                 return newErrorFormulaArg(formulaErrorVALUE, "IMCONJUGATE requires 1 argument")
3081         }
3082         value := argsList.Front().Value.(formulaArg).Value()
3083         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3084         if err != nil {
3085                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3086         }
3087         return newStringFormulaArg(cmplx2str(cmplx.Conj(inumber), value[len(value)-1:]))
3088 }
3089
3090 // IMCOS function returns the cosine of a supplied complex number. The syntax
3091 // of the function is:
3092 //
3093 //      IMCOS(inumber)
3094 func (fn *formulaFuncs) IMCOS(argsList *list.List) formulaArg {
3095         if argsList.Len() != 1 {
3096                 return newErrorFormulaArg(formulaErrorVALUE, "IMCOS requires 1 argument")
3097         }
3098         value := argsList.Front().Value.(formulaArg).Value()
3099         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3100         if err != nil {
3101                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3102         }
3103         return newStringFormulaArg(cmplx2str(cmplx.Cos(inumber), value[len(value)-1:]))
3104 }
3105
3106 // IMCOSH function returns the hyperbolic cosine of a supplied complex number. The syntax
3107 // of the function is:
3108 //
3109 //      IMCOSH(inumber)
3110 func (fn *formulaFuncs) IMCOSH(argsList *list.List) formulaArg {
3111         if argsList.Len() != 1 {
3112                 return newErrorFormulaArg(formulaErrorVALUE, "IMCOSH requires 1 argument")
3113         }
3114         value := argsList.Front().Value.(formulaArg).Value()
3115         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3116         if err != nil {
3117                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3118         }
3119         return newStringFormulaArg(cmplx2str(cmplx.Cosh(inumber), value[len(value)-1:]))
3120 }
3121
3122 // IMCOT function returns the cotangent of a supplied complex number. The syntax
3123 // of the function is:
3124 //
3125 //      IMCOT(inumber)
3126 func (fn *formulaFuncs) IMCOT(argsList *list.List) formulaArg {
3127         if argsList.Len() != 1 {
3128                 return newErrorFormulaArg(formulaErrorVALUE, "IMCOT requires 1 argument")
3129         }
3130         value := argsList.Front().Value.(formulaArg).Value()
3131         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3132         if err != nil {
3133                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3134         }
3135         return newStringFormulaArg(cmplx2str(cmplx.Cot(inumber), value[len(value)-1:]))
3136 }
3137
3138 // IMCSC function returns the cosecant of a supplied complex number. The syntax
3139 // of the function is:
3140 //
3141 //      IMCSC(inumber)
3142 func (fn *formulaFuncs) IMCSC(argsList *list.List) formulaArg {
3143         if argsList.Len() != 1 {
3144                 return newErrorFormulaArg(formulaErrorVALUE, "IMCSC requires 1 argument")
3145         }
3146         value := argsList.Front().Value.(formulaArg).Value()
3147         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3148         if err != nil {
3149                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3150         }
3151         num := 1 / cmplx.Sin(inumber)
3152         if cmplx.IsInf(num) {
3153                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
3154         }
3155         return newStringFormulaArg(cmplx2str(num, value[len(value)-1:]))
3156 }
3157
3158 // IMCSCH function returns the hyperbolic cosecant of a supplied complex
3159 // number. The syntax of the function is:
3160 //
3161 //      IMCSCH(inumber)
3162 func (fn *formulaFuncs) IMCSCH(argsList *list.List) formulaArg {
3163         if argsList.Len() != 1 {
3164                 return newErrorFormulaArg(formulaErrorVALUE, "IMCSCH requires 1 argument")
3165         }
3166         value := argsList.Front().Value.(formulaArg).Value()
3167         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3168         if err != nil {
3169                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3170         }
3171         num := 1 / cmplx.Sinh(inumber)
3172         if cmplx.IsInf(num) {
3173                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
3174         }
3175         return newStringFormulaArg(cmplx2str(num, value[len(value)-1:]))
3176 }
3177
3178 // IMDIV function calculates the quotient of two complex numbers (i.e. divides
3179 // one complex number by another). The syntax of the function is:
3180 //
3181 //      IMDIV(inumber1,inumber2)
3182 func (fn *formulaFuncs) IMDIV(argsList *list.List) formulaArg {
3183         if argsList.Len() != 2 {
3184                 return newErrorFormulaArg(formulaErrorVALUE, "IMDIV requires 2 arguments")
3185         }
3186         value := argsList.Front().Value.(formulaArg).Value()
3187         inumber1, err := strconv.ParseComplex(str2cmplx(value), 128)
3188         if err != nil {
3189                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3190         }
3191         inumber2, err := strconv.ParseComplex(str2cmplx(argsList.Back().Value.(formulaArg).Value()), 128)
3192         if err != nil {
3193                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3194         }
3195         num := inumber1 / inumber2
3196         if cmplx.IsInf(num) {
3197                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
3198         }
3199         return newStringFormulaArg(cmplx2str(num, value[len(value)-1:]))
3200 }
3201
3202 // IMEXP function returns the exponential of a supplied complex number. The
3203 // syntax of the function is:
3204 //
3205 //      IMEXP(inumber)
3206 func (fn *formulaFuncs) IMEXP(argsList *list.List) formulaArg {
3207         if argsList.Len() != 1 {
3208                 return newErrorFormulaArg(formulaErrorVALUE, "IMEXP requires 1 argument")
3209         }
3210         value := argsList.Front().Value.(formulaArg).Value()
3211         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3212         if err != nil {
3213                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3214         }
3215         return newStringFormulaArg(cmplx2str(cmplx.Exp(inumber), value[len(value)-1:]))
3216 }
3217
3218 // IMLN function returns the natural logarithm of a supplied complex number.
3219 // The syntax of the function is:
3220 //
3221 //      IMLN(inumber)
3222 func (fn *formulaFuncs) IMLN(argsList *list.List) formulaArg {
3223         if argsList.Len() != 1 {
3224                 return newErrorFormulaArg(formulaErrorVALUE, "IMLN requires 1 argument")
3225         }
3226         value := argsList.Front().Value.(formulaArg).Value()
3227         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3228         if err != nil {
3229                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3230         }
3231         num := cmplx.Log(inumber)
3232         if cmplx.IsInf(num) {
3233                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
3234         }
3235         return newStringFormulaArg(cmplx2str(num, value[len(value)-1:]))
3236 }
3237
3238 // IMLOG10 function returns the common (base 10) logarithm of a supplied
3239 // complex number. The syntax of the function is:
3240 //
3241 //      IMLOG10(inumber)
3242 func (fn *formulaFuncs) IMLOG10(argsList *list.List) formulaArg {
3243         if argsList.Len() != 1 {
3244                 return newErrorFormulaArg(formulaErrorVALUE, "IMLOG10 requires 1 argument")
3245         }
3246         value := argsList.Front().Value.(formulaArg).Value()
3247         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3248         if err != nil {
3249                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3250         }
3251         num := cmplx.Log10(inumber)
3252         if cmplx.IsInf(num) {
3253                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
3254         }
3255         return newStringFormulaArg(cmplx2str(num, value[len(value)-1:]))
3256 }
3257
3258 // IMLOG2 function calculates the base 2 logarithm of a supplied complex
3259 // number. The syntax of the function is:
3260 //
3261 //      IMLOG2(inumber)
3262 func (fn *formulaFuncs) IMLOG2(argsList *list.List) formulaArg {
3263         if argsList.Len() != 1 {
3264                 return newErrorFormulaArg(formulaErrorVALUE, "IMLOG2 requires 1 argument")
3265         }
3266         value := argsList.Front().Value.(formulaArg).Value()
3267         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3268         if err != nil {
3269                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3270         }
3271         num := cmplx.Log(inumber)
3272         if cmplx.IsInf(num) {
3273                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
3274         }
3275         return newStringFormulaArg(cmplx2str(num/cmplx.Log(2), value[len(value)-1:]))
3276 }
3277
3278 // IMPOWER function returns a supplied complex number, raised to a given
3279 // power. The syntax of the function is:
3280 //
3281 //      IMPOWER(inumber,number)
3282 func (fn *formulaFuncs) IMPOWER(argsList *list.List) formulaArg {
3283         if argsList.Len() != 2 {
3284                 return newErrorFormulaArg(formulaErrorVALUE, "IMPOWER requires 2 arguments")
3285         }
3286         value := argsList.Front().Value.(formulaArg).Value()
3287         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3288         if err != nil {
3289                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3290         }
3291         number, err := strconv.ParseComplex(str2cmplx(argsList.Back().Value.(formulaArg).Value()), 128)
3292         if err != nil {
3293                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3294         }
3295         if inumber == 0 && number == 0 {
3296                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
3297         }
3298         num := cmplx.Pow(inumber, number)
3299         if cmplx.IsInf(num) {
3300                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
3301         }
3302         return newStringFormulaArg(cmplx2str(num, value[len(value)-1:]))
3303 }
3304
3305 // IMPRODUCT function calculates the product of two or more complex numbers.
3306 // The syntax of the function is:
3307 //
3308 //      IMPRODUCT(number1,[number2],...)
3309 func (fn *formulaFuncs) IMPRODUCT(argsList *list.List) formulaArg {
3310         product := complex128(1)
3311         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
3312                 token := arg.Value.(formulaArg)
3313                 switch token.Type {
3314                 case ArgString:
3315                         if token.Value() == "" {
3316                                 continue
3317                         }
3318                         val, err := strconv.ParseComplex(str2cmplx(token.Value()), 128)
3319                         if err != nil {
3320                                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3321                         }
3322                         product = product * val
3323                 case ArgNumber:
3324                         product = product * complex(token.Number, 0)
3325                 case ArgMatrix:
3326                         for _, row := range token.Matrix {
3327                                 for _, value := range row {
3328                                         if value.Value() == "" {
3329                                                 continue
3330                                         }
3331                                         val, err := strconv.ParseComplex(str2cmplx(value.Value()), 128)
3332                                         if err != nil {
3333                                                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3334                                         }
3335                                         product = product * val
3336                                 }
3337                         }
3338                 }
3339         }
3340         return newStringFormulaArg(cmplx2str(product, "i"))
3341 }
3342
3343 // IMREAL function returns the real coefficient of a supplied complex number.
3344 // The syntax of the function is:
3345 //
3346 //      IMREAL(inumber)
3347 func (fn *formulaFuncs) IMREAL(argsList *list.List) formulaArg {
3348         if argsList.Len() != 1 {
3349                 return newErrorFormulaArg(formulaErrorVALUE, "IMREAL requires 1 argument")
3350         }
3351         value := argsList.Front().Value.(formulaArg).Value()
3352         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3353         if err != nil {
3354                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3355         }
3356         return newStringFormulaArg(fmt.Sprint(real(inumber)))
3357 }
3358
3359 // IMSEC function returns the secant of a supplied complex number. The syntax
3360 // of the function is:
3361 //
3362 //      IMSEC(inumber)
3363 func (fn *formulaFuncs) IMSEC(argsList *list.List) formulaArg {
3364         if argsList.Len() != 1 {
3365                 return newErrorFormulaArg(formulaErrorVALUE, "IMSEC requires 1 argument")
3366         }
3367         value := argsList.Front().Value.(formulaArg).Value()
3368         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3369         if err != nil {
3370                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3371         }
3372         return newStringFormulaArg(cmplx2str(1/cmplx.Cos(inumber), value[len(value)-1:]))
3373 }
3374
3375 // IMSECH function returns the hyperbolic secant of a supplied complex number.
3376 // The syntax of the function is:
3377 //
3378 //      IMSECH(inumber)
3379 func (fn *formulaFuncs) IMSECH(argsList *list.List) formulaArg {
3380         if argsList.Len() != 1 {
3381                 return newErrorFormulaArg(formulaErrorVALUE, "IMSECH requires 1 argument")
3382         }
3383         value := argsList.Front().Value.(formulaArg).Value()
3384         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3385         if err != nil {
3386                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3387         }
3388         return newStringFormulaArg(cmplx2str(1/cmplx.Cosh(inumber), value[len(value)-1:]))
3389 }
3390
3391 // IMSIN function returns the Sine of a supplied complex number. The syntax of
3392 // the function is:
3393 //
3394 //      IMSIN(inumber)
3395 func (fn *formulaFuncs) IMSIN(argsList *list.List) formulaArg {
3396         if argsList.Len() != 1 {
3397                 return newErrorFormulaArg(formulaErrorVALUE, "IMSIN requires 1 argument")
3398         }
3399         value := argsList.Front().Value.(formulaArg).Value()
3400         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3401         if err != nil {
3402                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3403         }
3404         return newStringFormulaArg(cmplx2str(cmplx.Sin(inumber), value[len(value)-1:]))
3405 }
3406
3407 // IMSINH function returns the hyperbolic sine of a supplied complex number.
3408 // The syntax of the function is:
3409 //
3410 //      IMSINH(inumber)
3411 func (fn *formulaFuncs) IMSINH(argsList *list.List) formulaArg {
3412         if argsList.Len() != 1 {
3413                 return newErrorFormulaArg(formulaErrorVALUE, "IMSINH requires 1 argument")
3414         }
3415         value := argsList.Front().Value.(formulaArg).Value()
3416         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3417         if err != nil {
3418                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3419         }
3420         return newStringFormulaArg(cmplx2str(cmplx.Sinh(inumber), value[len(value)-1:]))
3421 }
3422
3423 // IMSQRT function returns the square root of a supplied complex number. The
3424 // syntax of the function is:
3425 //
3426 //      IMSQRT(inumber)
3427 func (fn *formulaFuncs) IMSQRT(argsList *list.List) formulaArg {
3428         if argsList.Len() != 1 {
3429                 return newErrorFormulaArg(formulaErrorVALUE, "IMSQRT requires 1 argument")
3430         }
3431         value := argsList.Front().Value.(formulaArg).Value()
3432         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3433         if err != nil {
3434                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3435         }
3436         return newStringFormulaArg(cmplx2str(cmplx.Sqrt(inumber), value[len(value)-1:]))
3437 }
3438
3439 // IMSUB function calculates the difference between two complex numbers
3440 // (i.e. subtracts one complex number from another). The syntax of the
3441 // function is:
3442 //
3443 //      IMSUB(inumber1,inumber2)
3444 func (fn *formulaFuncs) IMSUB(argsList *list.List) formulaArg {
3445         if argsList.Len() != 2 {
3446                 return newErrorFormulaArg(formulaErrorVALUE, "IMSUB requires 2 arguments")
3447         }
3448         i1, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
3449         if err != nil {
3450                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3451         }
3452         i2, err := strconv.ParseComplex(str2cmplx(argsList.Back().Value.(formulaArg).Value()), 128)
3453         if err != nil {
3454                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3455         }
3456         return newStringFormulaArg(cmplx2str(i1-i2, "i"))
3457 }
3458
3459 // IMSUM function calculates the sum of two or more complex numbers. The
3460 // syntax of the function is:
3461 //
3462 //      IMSUM(inumber1,inumber2,...)
3463 func (fn *formulaFuncs) IMSUM(argsList *list.List) formulaArg {
3464         if argsList.Len() < 1 {
3465                 return newErrorFormulaArg(formulaErrorVALUE, "IMSUM requires at least 1 argument")
3466         }
3467         var result complex128
3468         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
3469                 token := arg.Value.(formulaArg)
3470                 num, err := strconv.ParseComplex(str2cmplx(token.Value()), 128)
3471                 if err != nil {
3472                         return newErrorFormulaArg(formulaErrorNUM, err.Error())
3473                 }
3474                 result += num
3475         }
3476         return newStringFormulaArg(cmplx2str(result, "i"))
3477 }
3478
3479 // IMTAN function returns the tangent of a supplied complex number. The syntax
3480 // of the function is:
3481 //
3482 //      IMTAN(inumber)
3483 func (fn *formulaFuncs) IMTAN(argsList *list.List) formulaArg {
3484         if argsList.Len() != 1 {
3485                 return newErrorFormulaArg(formulaErrorVALUE, "IMTAN requires 1 argument")
3486         }
3487         value := argsList.Front().Value.(formulaArg).Value()
3488         inumber, err := strconv.ParseComplex(str2cmplx(value), 128)
3489         if err != nil {
3490                 return newErrorFormulaArg(formulaErrorNUM, err.Error())
3491         }
3492         return newStringFormulaArg(cmplx2str(cmplx.Tan(inumber), value[len(value)-1:]))
3493 }
3494
3495 // OCT2BIN function converts an Octal (Base 8) number into a Binary (Base 2)
3496 // number. The syntax of the function is:
3497 //
3498 //      OCT2BIN(number,[places])
3499 func (fn *formulaFuncs) OCT2BIN(argsList *list.List) formulaArg {
3500         if argsList.Len() < 1 {
3501                 return newErrorFormulaArg(formulaErrorVALUE, "OCT2BIN requires at least 1 argument")
3502         }
3503         if argsList.Len() > 2 {
3504                 return newErrorFormulaArg(formulaErrorVALUE, "OCT2BIN allows at most 2 arguments")
3505         }
3506         token := argsList.Front().Value.(formulaArg)
3507         number := token.ToNumber()
3508         if number.Type != ArgNumber {
3509                 return newErrorFormulaArg(formulaErrorVALUE, number.Error)
3510         }
3511         decimal, newList := fn.oct2dec(token.Value()), list.New()
3512         newList.PushBack(decimal)
3513         if argsList.Len() == 2 {
3514                 newList.PushBack(argsList.Back().Value.(formulaArg))
3515         }
3516         return fn.dec2x("OCT2BIN", newList)
3517 }
3518
3519 // OCT2DEC function converts an Octal (a base-8 number) into a decimal number.
3520 // The syntax of the function is:
3521 //
3522 //      OCT2DEC(number)
3523 func (fn *formulaFuncs) OCT2DEC(argsList *list.List) formulaArg {
3524         if argsList.Len() != 1 {
3525                 return newErrorFormulaArg(formulaErrorVALUE, "OCT2DEC requires 1 numeric argument")
3526         }
3527         token := argsList.Front().Value.(formulaArg)
3528         number := token.ToNumber()
3529         if number.Type != ArgNumber {
3530                 return newErrorFormulaArg(formulaErrorVALUE, number.Error)
3531         }
3532         return fn.oct2dec(token.Value())
3533 }
3534
3535 // OCT2HEX function converts an Octal (Base 8) number into a Hexadecimal
3536 // (Base 16) number. The syntax of the function is:
3537 //
3538 //      OCT2HEX(number,[places])
3539 func (fn *formulaFuncs) OCT2HEX(argsList *list.List) formulaArg {
3540         if argsList.Len() < 1 {
3541                 return newErrorFormulaArg(formulaErrorVALUE, "OCT2HEX requires at least 1 argument")
3542         }
3543         if argsList.Len() > 2 {
3544                 return newErrorFormulaArg(formulaErrorVALUE, "OCT2HEX allows at most 2 arguments")
3545         }
3546         token := argsList.Front().Value.(formulaArg)
3547         number := token.ToNumber()
3548         if number.Type != ArgNumber {
3549                 return newErrorFormulaArg(formulaErrorVALUE, number.Error)
3550         }
3551         decimal, newList := fn.oct2dec(token.Value()), list.New()
3552         newList.PushBack(decimal)
3553         if argsList.Len() == 2 {
3554                 newList.PushBack(argsList.Back().Value.(formulaArg))
3555         }
3556         return fn.dec2x("OCT2HEX", newList)
3557 }
3558
3559 // oct2dec is an implementation of the formula function OCT2DEC.
3560 func (fn *formulaFuncs) oct2dec(number string) formulaArg {
3561         decimal, length := 0.0, len(number)
3562         for i := length; i > 0; i-- {
3563                 num, _ := strconv.Atoi(string(number[length-i]))
3564                 if i == 10 && string(number[length-i]) == "7" {
3565                         decimal += math.Pow(-8.0, float64(i-1))
3566                         continue
3567                 }
3568                 decimal += float64(num) * math.Pow(8.0, float64(i-1))
3569         }
3570         return newNumberFormulaArg(decimal)
3571 }
3572
3573 // Math and Trigonometric Functions
3574
3575 // ABS function returns the absolute value of any supplied number. The syntax
3576 // of the function is:
3577 //
3578 //      ABS(number)
3579 func (fn *formulaFuncs) ABS(argsList *list.List) formulaArg {
3580         if argsList.Len() != 1 {
3581                 return newErrorFormulaArg(formulaErrorVALUE, "ABS requires 1 numeric argument")
3582         }
3583         arg := argsList.Front().Value.(formulaArg).ToNumber()
3584         if arg.Type == ArgError {
3585                 return arg
3586         }
3587         return newNumberFormulaArg(math.Abs(arg.Number))
3588 }
3589
3590 // ACOS function calculates the arccosine (i.e. the inverse cosine) of a given
3591 // number, and returns an angle, in radians, between 0 and Ï€. The syntax of
3592 // the function is:
3593 //
3594 //      ACOS(number)
3595 func (fn *formulaFuncs) ACOS(argsList *list.List) formulaArg {
3596         if argsList.Len() != 1 {
3597                 return newErrorFormulaArg(formulaErrorVALUE, "ACOS requires 1 numeric argument")
3598         }
3599         arg := argsList.Front().Value.(formulaArg).ToNumber()
3600         if arg.Type == ArgError {
3601                 return arg
3602         }
3603         return newNumberFormulaArg(math.Acos(arg.Number))
3604 }
3605
3606 // ACOSH function calculates the inverse hyperbolic cosine of a supplied number.
3607 // of the function is:
3608 //
3609 //      ACOSH(number)
3610 func (fn *formulaFuncs) ACOSH(argsList *list.List) formulaArg {
3611         if argsList.Len() != 1 {
3612                 return newErrorFormulaArg(formulaErrorVALUE, "ACOSH requires 1 numeric argument")
3613         }
3614         arg := argsList.Front().Value.(formulaArg).ToNumber()
3615         if arg.Type == ArgError {
3616                 return arg
3617         }
3618         return newNumberFormulaArg(math.Acosh(arg.Number))
3619 }
3620
3621 // ACOT function calculates the arccotangent (i.e. the inverse cotangent) of a
3622 // given number, and returns an angle, in radians, between 0 and Ï€. The syntax
3623 // of the function is:
3624 //
3625 //      ACOT(number)
3626 func (fn *formulaFuncs) ACOT(argsList *list.List) formulaArg {
3627         if argsList.Len() != 1 {
3628                 return newErrorFormulaArg(formulaErrorVALUE, "ACOT requires 1 numeric argument")
3629         }
3630         arg := argsList.Front().Value.(formulaArg).ToNumber()
3631         if arg.Type == ArgError {
3632                 return arg
3633         }
3634         return newNumberFormulaArg(math.Pi/2 - math.Atan(arg.Number))
3635 }
3636
3637 // ACOTH function calculates the hyperbolic arccotangent (coth) of a supplied
3638 // value. The syntax of the function is:
3639 //
3640 //      ACOTH(number)
3641 func (fn *formulaFuncs) ACOTH(argsList *list.List) formulaArg {
3642         if argsList.Len() != 1 {
3643                 return newErrorFormulaArg(formulaErrorVALUE, "ACOTH requires 1 numeric argument")
3644         }
3645         arg := argsList.Front().Value.(formulaArg).ToNumber()
3646         if arg.Type == ArgError {
3647                 return arg
3648         }
3649         return newNumberFormulaArg(math.Atanh(1 / arg.Number))
3650 }
3651
3652 // AGGREGATE function returns the result of a specified operation or function,
3653 // applied to a list or database of values. The syntax of the function is:
3654 //
3655 //      AGGREGATE(function_num,options,ref1,[ref2],...)
3656 func (fn *formulaFuncs) AGGREGATE(argsList *list.List) formulaArg {
3657         if argsList.Len() < 2 {
3658                 return newErrorFormulaArg(formulaErrorVALUE, "AGGREGATE requires at least 3 arguments")
3659         }
3660         var fnNum, opts formulaArg
3661         if fnNum = argsList.Front().Value.(formulaArg).ToNumber(); fnNum.Type != ArgNumber {
3662                 return fnNum
3663         }
3664         subFn, ok := map[int]func(argsList *list.List) formulaArg{
3665                 1:  fn.AVERAGE,
3666                 2:  fn.COUNT,
3667                 3:  fn.COUNTA,
3668                 4:  fn.MAX,
3669                 5:  fn.MIN,
3670                 6:  fn.PRODUCT,
3671                 7:  fn.STDEVdotS,
3672                 8:  fn.STDEVdotP,
3673                 9:  fn.SUM,
3674                 10: fn.VARdotS,
3675                 11: fn.VARdotP,
3676                 12: fn.MEDIAN,
3677                 13: fn.MODEdotSNGL,
3678                 14: fn.LARGE,
3679                 15: fn.SMALL,
3680                 16: fn.PERCENTILEdotINC,
3681                 17: fn.QUARTILEdotINC,
3682                 18: fn.PERCENTILEdotEXC,
3683                 19: fn.QUARTILEdotEXC,
3684         }[int(fnNum.Number)]
3685         if !ok {
3686                 return newErrorFormulaArg(formulaErrorVALUE, "AGGREGATE has invalid function_num")
3687         }
3688         if opts = argsList.Front().Next().Value.(formulaArg).ToNumber(); opts.Type != ArgNumber {
3689                 return opts
3690         }
3691         // TODO: apply option argument values to be ignored during the calculation
3692         if int(opts.Number) < 0 || int(opts.Number) > 7 {
3693                 return newErrorFormulaArg(formulaErrorVALUE, "AGGREGATE has invalid options")
3694         }
3695         subArgList := list.New().Init()
3696         for arg := argsList.Front().Next().Next(); arg != nil; arg = arg.Next() {
3697                 subArgList.PushBack(arg.Value.(formulaArg))
3698         }
3699         return subFn(subArgList)
3700 }
3701
3702 // ARABIC function converts a Roman numeral into an Arabic numeral. The syntax
3703 // of the function is:
3704 //
3705 //      ARABIC(text)
3706 func (fn *formulaFuncs) ARABIC(argsList *list.List) formulaArg {
3707         if argsList.Len() != 1 {
3708                 return newErrorFormulaArg(formulaErrorVALUE, "ARABIC requires 1 numeric argument")
3709         }
3710         text := argsList.Front().Value.(formulaArg).Value()
3711         if len(text) > MaxFieldLength {
3712                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
3713         }
3714         text = strings.ToUpper(text)
3715         number, actualStart, index, isNegative := 0, 0, len(text)-1, false
3716         startIndex, subtractNumber, currentPartValue, currentCharValue, prevCharValue := 0, 0, 0, 0, -1
3717         for index >= 0 && text[index] == ' ' {
3718                 index--
3719         }
3720         for actualStart <= index && text[actualStart] == ' ' {
3721                 actualStart++
3722         }
3723         if actualStart <= index && text[actualStart] == '-' {
3724                 isNegative = true
3725                 actualStart++
3726         }
3727         charMap := map[rune]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
3728         for index >= actualStart {
3729                 startIndex = index
3730                 startChar := text[startIndex]
3731                 index--
3732                 for index >= actualStart && (text[index]|' ') == startChar {
3733                         index--
3734                 }
3735                 currentCharValue = charMap[rune(startChar)]
3736                 currentPartValue = (startIndex - index) * currentCharValue
3737                 if currentCharValue >= prevCharValue {
3738                         number += currentPartValue - subtractNumber
3739                         prevCharValue = currentCharValue
3740                         subtractNumber = 0
3741                         continue
3742                 }
3743                 subtractNumber += currentPartValue
3744         }
3745         if subtractNumber != 0 {
3746                 number -= subtractNumber
3747         }
3748         if isNegative {
3749                 number = -number
3750         }
3751         return newNumberFormulaArg(float64(number))
3752 }
3753
3754 // ASIN function calculates the arcsine (i.e. the inverse sine) of a given
3755 // number, and returns an angle, in radians, between -Ï€/2 and Ï€/2. The syntax
3756 // of the function is:
3757 //
3758 //      ASIN(number)
3759 func (fn *formulaFuncs) ASIN(argsList *list.List) formulaArg {
3760         if argsList.Len() != 1 {
3761                 return newErrorFormulaArg(formulaErrorVALUE, "ASIN requires 1 numeric argument")
3762         }
3763         arg := argsList.Front().Value.(formulaArg).ToNumber()
3764         if arg.Type == ArgError {
3765                 return arg
3766         }
3767         return newNumberFormulaArg(math.Asin(arg.Number))
3768 }
3769
3770 // ASINH function calculates the inverse hyperbolic sine of a supplied number.
3771 // The syntax of the function is:
3772 //
3773 //      ASINH(number)
3774 func (fn *formulaFuncs) ASINH(argsList *list.List) formulaArg {
3775         if argsList.Len() != 1 {
3776                 return newErrorFormulaArg(formulaErrorVALUE, "ASINH requires 1 numeric argument")
3777         }
3778         arg := argsList.Front().Value.(formulaArg).ToNumber()
3779         if arg.Type == ArgError {
3780                 return arg
3781         }
3782         return newNumberFormulaArg(math.Asinh(arg.Number))
3783 }
3784
3785 // ATAN function calculates the arctangent (i.e. the inverse tangent) of a
3786 // given number, and returns an angle, in radians, between -Ï€/2 and +Ï€/2. The
3787 // syntax of the function is:
3788 //
3789 //      ATAN(number)
3790 func (fn *formulaFuncs) ATAN(argsList *list.List) formulaArg {
3791         if argsList.Len() != 1 {
3792                 return newErrorFormulaArg(formulaErrorVALUE, "ATAN requires 1 numeric argument")
3793         }
3794         arg := argsList.Front().Value.(formulaArg).ToNumber()
3795         if arg.Type == ArgError {
3796                 return arg
3797         }
3798         return newNumberFormulaArg(math.Atan(arg.Number))
3799 }
3800
3801 // ATANH function calculates the inverse hyperbolic tangent of a supplied
3802 // number. The syntax of the function is:
3803 //
3804 //      ATANH(number)
3805 func (fn *formulaFuncs) ATANH(argsList *list.List) formulaArg {
3806         if argsList.Len() != 1 {
3807                 return newErrorFormulaArg(formulaErrorVALUE, "ATANH requires 1 numeric argument")
3808         }
3809         arg := argsList.Front().Value.(formulaArg).ToNumber()
3810         if arg.Type == ArgError {
3811                 return arg
3812         }
3813         return newNumberFormulaArg(math.Atanh(arg.Number))
3814 }
3815
3816 // ATAN2 function calculates the arctangent (i.e. the inverse tangent) of a
3817 // given set of x and y coordinates, and returns an angle, in radians, between
3818 // -Ï€/2 and +Ï€/2. The syntax of the function is:
3819 //
3820 //      ATAN2(x_num,y_num)
3821 func (fn *formulaFuncs) ATAN2(argsList *list.List) formulaArg {
3822         if argsList.Len() != 2 {
3823                 return newErrorFormulaArg(formulaErrorVALUE, "ATAN2 requires 2 numeric arguments")
3824         }
3825         x := argsList.Back().Value.(formulaArg).ToNumber()
3826         if x.Type == ArgError {
3827                 return x
3828         }
3829         y := argsList.Front().Value.(formulaArg).ToNumber()
3830         if y.Type == ArgError {
3831                 return y
3832         }
3833         return newNumberFormulaArg(math.Atan2(x.Number, y.Number))
3834 }
3835
3836 // BASE function converts a number into a supplied base (radix), and returns a
3837 // text representation of the calculated value. The syntax of the function is:
3838 //
3839 //      BASE(number,radix,[min_length])
3840 func (fn *formulaFuncs) BASE(argsList *list.List) formulaArg {
3841         if argsList.Len() < 2 {
3842                 return newErrorFormulaArg(formulaErrorVALUE, "BASE requires at least 2 arguments")
3843         }
3844         if argsList.Len() > 3 {
3845                 return newErrorFormulaArg(formulaErrorVALUE, "BASE allows at most 3 arguments")
3846         }
3847         var minLength int
3848         var err error
3849         number := argsList.Front().Value.(formulaArg).ToNumber()
3850         if number.Type == ArgError {
3851                 return number
3852         }
3853         radix := argsList.Front().Next().Value.(formulaArg).ToNumber()
3854         if radix.Type == ArgError {
3855                 return radix
3856         }
3857         if int(radix.Number) < 2 || int(radix.Number) > 36 {
3858                 return newErrorFormulaArg(formulaErrorVALUE, "radix must be an integer >= 2 and <= 36")
3859         }
3860         if argsList.Len() > 2 {
3861                 if minLength, err = strconv.Atoi(argsList.Back().Value.(formulaArg).Value()); err != nil {
3862                         return newErrorFormulaArg(formulaErrorVALUE, err.Error())
3863                 }
3864         }
3865         result := strconv.FormatInt(int64(number.Number), int(radix.Number))
3866         if len(result) < minLength {
3867                 result = strings.Repeat("0", minLength-len(result)) + result
3868         }
3869         return newStringFormulaArg(strings.ToUpper(result))
3870 }
3871
3872 // CEILING function rounds a supplied number away from zero, to the nearest
3873 // multiple of a given number. The syntax of the function is:
3874 //
3875 //      CEILING(number,significance)
3876 func (fn *formulaFuncs) CEILING(argsList *list.List) formulaArg {
3877         if argsList.Len() == 0 {
3878                 return newErrorFormulaArg(formulaErrorVALUE, "CEILING requires at least 1 argument")
3879         }
3880         if argsList.Len() > 2 {
3881                 return newErrorFormulaArg(formulaErrorVALUE, "CEILING allows at most 2 arguments")
3882         }
3883         number, significance, res := 0.0, 1.0, 0.0
3884         n := argsList.Front().Value.(formulaArg).ToNumber()
3885         if n.Type == ArgError {
3886                 return n
3887         }
3888         number = n.Number
3889         if number < 0 {
3890                 significance = -1
3891         }
3892         if argsList.Len() > 1 {
3893                 s := argsList.Back().Value.(formulaArg).ToNumber()
3894                 if s.Type == ArgError {
3895                         return s
3896                 }
3897                 significance = s.Number
3898         }
3899         if significance < 0 && number > 0 {
3900                 return newErrorFormulaArg(formulaErrorVALUE, "negative sig to CEILING invalid")
3901         }
3902         if argsList.Len() == 1 {
3903                 return newNumberFormulaArg(math.Ceil(number))
3904         }
3905         number, res = math.Modf(number / significance)
3906         if res > 0 {
3907                 number++
3908         }
3909         return newNumberFormulaArg(number * significance)
3910 }
3911
3912 // CEILINGdotMATH function rounds a supplied number up to a supplied multiple
3913 // of significance. The syntax of the function is:
3914 //
3915 //      CEILING.MATH(number,[significance],[mode])
3916 func (fn *formulaFuncs) CEILINGdotMATH(argsList *list.List) formulaArg {
3917         if argsList.Len() == 0 {
3918                 return newErrorFormulaArg(formulaErrorVALUE, "CEILING.MATH requires at least 1 argument")
3919         }
3920         if argsList.Len() > 3 {
3921                 return newErrorFormulaArg(formulaErrorVALUE, "CEILING.MATH allows at most 3 arguments")
3922         }
3923         number, significance, mode := 0.0, 1.0, 1.0
3924         n := argsList.Front().Value.(formulaArg).ToNumber()
3925         if n.Type == ArgError {
3926                 return n
3927         }
3928         number = n.Number
3929         if number < 0 {
3930                 significance = -1
3931         }
3932         if argsList.Len() > 1 {
3933                 s := argsList.Front().Next().Value.(formulaArg).ToNumber()
3934                 if s.Type == ArgError {
3935                         return s
3936                 }
3937                 significance = s.Number
3938         }
3939         if argsList.Len() == 1 {
3940                 return newNumberFormulaArg(math.Ceil(number))
3941         }
3942         if argsList.Len() > 2 {
3943                 m := argsList.Back().Value.(formulaArg).ToNumber()
3944                 if m.Type == ArgError {
3945                         return m
3946                 }
3947                 mode = m.Number
3948         }
3949         val, res := math.Modf(number / significance)
3950         if res != 0 {
3951                 if number > 0 {
3952                         val++
3953                 } else if mode < 0 {
3954                         val--
3955                 }
3956         }
3957         return newNumberFormulaArg(val * significance)
3958 }
3959
3960 // CEILINGdotPRECISE function rounds a supplied number up (regardless of the
3961 // number's sign), to the nearest multiple of a given number. The syntax of
3962 // the function is:
3963 //
3964 //      CEILING.PRECISE(number,[significance])
3965 func (fn *formulaFuncs) CEILINGdotPRECISE(argsList *list.List) formulaArg {
3966         if argsList.Len() == 0 {
3967                 return newErrorFormulaArg(formulaErrorVALUE, "CEILING.PRECISE requires at least 1 argument")
3968         }
3969         if argsList.Len() > 2 {
3970                 return newErrorFormulaArg(formulaErrorVALUE, "CEILING.PRECISE allows at most 2 arguments")
3971         }
3972         number, significance := 0.0, 1.0
3973         n := argsList.Front().Value.(formulaArg).ToNumber()
3974         if n.Type == ArgError {
3975                 return n
3976         }
3977         number = n.Number
3978         if number < 0 {
3979                 significance = -1
3980         }
3981         if argsList.Len() == 1 {
3982                 return newNumberFormulaArg(math.Ceil(number))
3983         }
3984         if argsList.Len() > 1 {
3985                 s := argsList.Back().Value.(formulaArg).ToNumber()
3986                 if s.Type == ArgError {
3987                         return s
3988                 }
3989                 significance = s.Number
3990                 significance = math.Abs(significance)
3991                 if significance == 0 {
3992                         return newNumberFormulaArg(significance)
3993                 }
3994         }
3995         val, res := math.Modf(number / significance)
3996         if res != 0 {
3997                 if number > 0 {
3998                         val++
3999                 }
4000         }
4001         return newNumberFormulaArg(val * significance)
4002 }
4003
4004 // COMBIN function calculates the number of combinations (in any order) of a
4005 // given number objects from a set. The syntax of the function is:
4006 //
4007 //      COMBIN(number,number_chosen)
4008 func (fn *formulaFuncs) COMBIN(argsList *list.List) formulaArg {
4009         if argsList.Len() != 2 {
4010                 return newErrorFormulaArg(formulaErrorVALUE, "COMBIN requires 2 argument")
4011         }
4012         number, chosen, val := 0.0, 0.0, 1.0
4013         n := argsList.Front().Value.(formulaArg).ToNumber()
4014         if n.Type == ArgError {
4015                 return n
4016         }
4017         number = n.Number
4018         c := argsList.Back().Value.(formulaArg).ToNumber()
4019         if c.Type == ArgError {
4020                 return c
4021         }
4022         chosen = c.Number
4023         number, chosen = math.Trunc(number), math.Trunc(chosen)
4024         if chosen > number {
4025                 return newErrorFormulaArg(formulaErrorVALUE, "COMBIN requires number >= number_chosen")
4026         }
4027         if chosen == number || chosen == 0 {
4028                 return newNumberFormulaArg(1)
4029         }
4030         for c := float64(1); c <= chosen; c++ {
4031                 val *= (number + 1 - c) / c
4032         }
4033         return newNumberFormulaArg(math.Ceil(val))
4034 }
4035
4036 // COMBINA function calculates the number of combinations, with repetitions,
4037 // of a given number objects from a set. The syntax of the function is:
4038 //
4039 //      COMBINA(number,number_chosen)
4040 func (fn *formulaFuncs) COMBINA(argsList *list.List) formulaArg {
4041         if argsList.Len() != 2 {
4042                 return newErrorFormulaArg(formulaErrorVALUE, "COMBINA requires 2 argument")
4043         }
4044         var number, chosen float64
4045         n := argsList.Front().Value.(formulaArg).ToNumber()
4046         if n.Type == ArgError {
4047                 return n
4048         }
4049         number = n.Number
4050         c := argsList.Back().Value.(formulaArg).ToNumber()
4051         if c.Type == ArgError {
4052                 return c
4053         }
4054         chosen = c.Number
4055         number, chosen = math.Trunc(number), math.Trunc(chosen)
4056         if number < chosen {
4057                 return newErrorFormulaArg(formulaErrorVALUE, "COMBINA requires number > number_chosen")
4058         }
4059         if number == 0 {
4060                 return newNumberFormulaArg(number)
4061         }
4062         args := list.New()
4063         args.PushBack(formulaArg{
4064                 String: fmt.Sprintf("%g", number+chosen-1),
4065                 Type:   ArgString,
4066         })
4067         args.PushBack(formulaArg{
4068                 String: fmt.Sprintf("%g", number-1),
4069                 Type:   ArgString,
4070         })
4071         return fn.COMBIN(args)
4072 }
4073
4074 // COS function calculates the cosine of a given angle. The syntax of the
4075 // function is:
4076 //
4077 //      COS(number)
4078 func (fn *formulaFuncs) COS(argsList *list.List) formulaArg {
4079         if argsList.Len() != 1 {
4080                 return newErrorFormulaArg(formulaErrorVALUE, "COS requires 1 numeric argument")
4081         }
4082         val := argsList.Front().Value.(formulaArg).ToNumber()
4083         if val.Type == ArgError {
4084                 return val
4085         }
4086         return newNumberFormulaArg(math.Cos(val.Number))
4087 }
4088
4089 // COSH function calculates the hyperbolic cosine (cosh) of a supplied number.
4090 // The syntax of the function is:
4091 //
4092 //      COSH(number)
4093 func (fn *formulaFuncs) COSH(argsList *list.List) formulaArg {
4094         if argsList.Len() != 1 {
4095                 return newErrorFormulaArg(formulaErrorVALUE, "COSH requires 1 numeric argument")
4096         }
4097         val := argsList.Front().Value.(formulaArg).ToNumber()
4098         if val.Type == ArgError {
4099                 return val
4100         }
4101         return newNumberFormulaArg(math.Cosh(val.Number))
4102 }
4103
4104 // COT function calculates the cotangent of a given angle. The syntax of the
4105 // function is:
4106 //
4107 //      COT(number)
4108 func (fn *formulaFuncs) COT(argsList *list.List) formulaArg {
4109         if argsList.Len() != 1 {
4110                 return newErrorFormulaArg(formulaErrorVALUE, "COT requires 1 numeric argument")
4111         }
4112         val := argsList.Front().Value.(formulaArg).ToNumber()
4113         if val.Type == ArgError {
4114                 return val
4115         }
4116         if val.Number == 0 {
4117                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
4118         }
4119         return newNumberFormulaArg(1 / math.Tan(val.Number))
4120 }
4121
4122 // COTH function calculates the hyperbolic cotangent (coth) of a supplied
4123 // angle. The syntax of the function is:
4124 //
4125 //      COTH(number)
4126 func (fn *formulaFuncs) COTH(argsList *list.List) formulaArg {
4127         if argsList.Len() != 1 {
4128                 return newErrorFormulaArg(formulaErrorVALUE, "COTH requires 1 numeric argument")
4129         }
4130         val := argsList.Front().Value.(formulaArg).ToNumber()
4131         if val.Type == ArgError {
4132                 return val
4133         }
4134         if val.Number == 0 {
4135                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
4136         }
4137         return newNumberFormulaArg((math.Exp(val.Number) + math.Exp(-val.Number)) / (math.Exp(val.Number) - math.Exp(-val.Number)))
4138 }
4139
4140 // CSC function calculates the cosecant of a given angle. The syntax of the
4141 // function is:
4142 //
4143 //      CSC(number)
4144 func (fn *formulaFuncs) CSC(argsList *list.List) formulaArg {
4145         if argsList.Len() != 1 {
4146                 return newErrorFormulaArg(formulaErrorVALUE, "CSC requires 1 numeric argument")
4147         }
4148         val := argsList.Front().Value.(formulaArg).ToNumber()
4149         if val.Type == ArgError {
4150                 return val
4151         }
4152         if val.Number == 0 {
4153                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
4154         }
4155         return newNumberFormulaArg(1 / math.Sin(val.Number))
4156 }
4157
4158 // CSCH function calculates the hyperbolic cosecant (csch) of a supplied
4159 // angle. The syntax of the function is:
4160 //
4161 //      CSCH(number)
4162 func (fn *formulaFuncs) CSCH(argsList *list.List) formulaArg {
4163         if argsList.Len() != 1 {
4164                 return newErrorFormulaArg(formulaErrorVALUE, "CSCH requires 1 numeric argument")
4165         }
4166         val := argsList.Front().Value.(formulaArg).ToNumber()
4167         if val.Type == ArgError {
4168                 return val
4169         }
4170         if val.Number == 0 {
4171                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
4172         }
4173         return newNumberFormulaArg(1 / math.Sinh(val.Number))
4174 }
4175
4176 // DECIMAL function converts a text representation of a number in a specified
4177 // base, into a decimal value. The syntax of the function is:
4178 //
4179 //      DECIMAL(text,radix)
4180 func (fn *formulaFuncs) DECIMAL(argsList *list.List) formulaArg {
4181         if argsList.Len() != 2 {
4182                 return newErrorFormulaArg(formulaErrorVALUE, "DECIMAL requires 2 numeric arguments")
4183         }
4184         text := argsList.Front().Value.(formulaArg).Value()
4185         var err error
4186         radix := argsList.Back().Value.(formulaArg).ToNumber()
4187         if radix.Type != ArgNumber {
4188                 return radix
4189         }
4190         if len(text) > 2 && (strings.HasPrefix(text, "0x") || strings.HasPrefix(text, "0X")) {
4191                 text = text[2:]
4192         }
4193         val, err := strconv.ParseInt(text, int(radix.Number), 64)
4194         if err != nil {
4195                 return newErrorFormulaArg(formulaErrorVALUE, err.Error())
4196         }
4197         return newNumberFormulaArg(float64(val))
4198 }
4199
4200 // DEGREES function converts radians into degrees. The syntax of the function
4201 // is:
4202 //
4203 //      DEGREES(angle)
4204 func (fn *formulaFuncs) DEGREES(argsList *list.List) formulaArg {
4205         if argsList.Len() != 1 {
4206                 return newErrorFormulaArg(formulaErrorVALUE, "DEGREES requires 1 numeric argument")
4207         }
4208         val := argsList.Front().Value.(formulaArg).ToNumber()
4209         if val.Type == ArgError {
4210                 return val
4211         }
4212         if val.Number == 0 {
4213                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
4214         }
4215         return newNumberFormulaArg(180.0 / math.Pi * val.Number)
4216 }
4217
4218 // EVEN function rounds a supplied number away from zero (i.e. rounds a
4219 // positive number up and a negative number down), to the next even number.
4220 // The syntax of the function is:
4221 //
4222 //      EVEN(number)
4223 func (fn *formulaFuncs) EVEN(argsList *list.List) formulaArg {
4224         if argsList.Len() != 1 {
4225                 return newErrorFormulaArg(formulaErrorVALUE, "EVEN requires 1 numeric argument")
4226         }
4227         number := argsList.Front().Value.(formulaArg).ToNumber()
4228         if number.Type == ArgError {
4229                 return number
4230         }
4231         sign := math.Signbit(number.Number)
4232         m, frac := math.Modf(number.Number / 2)
4233         val := m * 2
4234         if frac != 0 {
4235                 if !sign {
4236                         val += 2
4237                 } else {
4238                         val -= 2
4239                 }
4240         }
4241         return newNumberFormulaArg(val)
4242 }
4243
4244 // EXP function calculates the value of the mathematical constant e, raised to
4245 // the power of a given number. The syntax of the function is:
4246 //
4247 //      EXP(number)
4248 func (fn *formulaFuncs) EXP(argsList *list.List) formulaArg {
4249         if argsList.Len() != 1 {
4250                 return newErrorFormulaArg(formulaErrorVALUE, "EXP requires 1 numeric argument")
4251         }
4252         number := argsList.Front().Value.(formulaArg).ToNumber()
4253         if number.Type == ArgError {
4254                 return number
4255         }
4256         return newStringFormulaArg(strings.ToUpper(fmt.Sprintf("%g", math.Exp(number.Number))))
4257 }
4258
4259 // fact returns the factorial of a supplied number.
4260 func fact(number float64) float64 {
4261         val := float64(1)
4262         for i := float64(2); i <= number; i++ {
4263                 val *= i
4264         }
4265         return val
4266 }
4267
4268 // FACT function returns the factorial of a supplied number. The syntax of the
4269 // function is:
4270 //
4271 //      FACT(number)
4272 func (fn *formulaFuncs) FACT(argsList *list.List) formulaArg {
4273         if argsList.Len() != 1 {
4274                 return newErrorFormulaArg(formulaErrorVALUE, "FACT requires 1 numeric argument")
4275         }
4276         number := argsList.Front().Value.(formulaArg).ToNumber()
4277         if number.Type == ArgError {
4278                 return number
4279         }
4280         if number.Number < 0 {
4281                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
4282         }
4283         return newNumberFormulaArg(fact(number.Number))
4284 }
4285
4286 // FACTDOUBLE function returns the double factorial of a supplied number. The
4287 // syntax of the function is:
4288 //
4289 //      FACTDOUBLE(number)
4290 func (fn *formulaFuncs) FACTDOUBLE(argsList *list.List) formulaArg {
4291         if argsList.Len() != 1 {
4292                 return newErrorFormulaArg(formulaErrorVALUE, "FACTDOUBLE requires 1 numeric argument")
4293         }
4294         val := 1.0
4295         number := argsList.Front().Value.(formulaArg).ToNumber()
4296         if number.Type == ArgError {
4297                 return number
4298         }
4299         if number.Number < 0 {
4300                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
4301         }
4302         for i := math.Trunc(number.Number); i > 1; i -= 2 {
4303                 val *= i
4304         }
4305         return newStringFormulaArg(strings.ToUpper(fmt.Sprintf("%g", val)))
4306 }
4307
4308 // FLOOR function rounds a supplied number towards zero to the nearest
4309 // multiple of a specified significance. The syntax of the function is:
4310 //
4311 //      FLOOR(number,significance)
4312 func (fn *formulaFuncs) FLOOR(argsList *list.List) formulaArg {
4313         if argsList.Len() != 2 {
4314                 return newErrorFormulaArg(formulaErrorVALUE, "FLOOR requires 2 numeric arguments")
4315         }
4316         number := argsList.Front().Value.(formulaArg).ToNumber()
4317         if number.Type == ArgError {
4318                 return number
4319         }
4320         significance := argsList.Back().Value.(formulaArg).ToNumber()
4321         if significance.Type == ArgError {
4322                 return significance
4323         }
4324         if significance.Number < 0 && number.Number >= 0 {
4325                 return newErrorFormulaArg(formulaErrorNUM, "invalid arguments to FLOOR")
4326         }
4327         val := number.Number
4328         val, res := math.Modf(val / significance.Number)
4329         if res != 0 {
4330                 if number.Number < 0 && res < 0 {
4331                         val--
4332                 }
4333         }
4334         return newStringFormulaArg(strings.ToUpper(fmt.Sprintf("%g", val*significance.Number)))
4335 }
4336
4337 // FLOORdotMATH function rounds a supplied number down to a supplied multiple
4338 // of significance. The syntax of the function is:
4339 //
4340 //      FLOOR.MATH(number,[significance],[mode])
4341 func (fn *formulaFuncs) FLOORdotMATH(argsList *list.List) formulaArg {
4342         if argsList.Len() == 0 {
4343                 return newErrorFormulaArg(formulaErrorVALUE, "FLOOR.MATH requires at least 1 argument")
4344         }
4345         if argsList.Len() > 3 {
4346                 return newErrorFormulaArg(formulaErrorVALUE, "FLOOR.MATH allows at most 3 arguments")
4347         }
4348         significance, mode := 1.0, 1.0
4349         number := argsList.Front().Value.(formulaArg).ToNumber()
4350         if number.Type == ArgError {
4351                 return number
4352         }
4353         if number.Number < 0 {
4354                 significance = -1
4355         }
4356         if argsList.Len() > 1 {
4357                 s := argsList.Front().Next().Value.(formulaArg).ToNumber()
4358                 if s.Type == ArgError {
4359                         return s
4360                 }
4361                 significance = s.Number
4362         }
4363         if argsList.Len() == 1 {
4364                 return newNumberFormulaArg(math.Floor(number.Number))
4365         }
4366         if argsList.Len() > 2 {
4367                 m := argsList.Back().Value.(formulaArg).ToNumber()
4368                 if m.Type == ArgError {
4369                         return m
4370                 }
4371                 mode = m.Number
4372         }
4373         val, res := math.Modf(number.Number / significance)
4374         if res != 0 && number.Number < 0 && mode > 0 {
4375                 val--
4376         }
4377         return newNumberFormulaArg(val * significance)
4378 }
4379
4380 // FLOORdotPRECISE function rounds a supplied number down to a supplied
4381 // multiple of significance. The syntax of the function is:
4382 //
4383 //      FLOOR.PRECISE(number,[significance])
4384 func (fn *formulaFuncs) FLOORdotPRECISE(argsList *list.List) formulaArg {
4385         if argsList.Len() == 0 {
4386                 return newErrorFormulaArg(formulaErrorVALUE, "FLOOR.PRECISE requires at least 1 argument")
4387         }
4388         if argsList.Len() > 2 {
4389                 return newErrorFormulaArg(formulaErrorVALUE, "FLOOR.PRECISE allows at most 2 arguments")
4390         }
4391         var significance float64
4392         number := argsList.Front().Value.(formulaArg).ToNumber()
4393         if number.Type == ArgError {
4394                 return number
4395         }
4396         if number.Number < 0 {
4397                 significance = -1
4398         }
4399         if argsList.Len() == 1 {
4400                 return newNumberFormulaArg(math.Floor(number.Number))
4401         }
4402         if argsList.Len() > 1 {
4403                 s := argsList.Back().Value.(formulaArg).ToNumber()
4404                 if s.Type == ArgError {
4405                         return s
4406                 }
4407                 significance = s.Number
4408                 significance = math.Abs(significance)
4409                 if significance == 0 {
4410                         return newNumberFormulaArg(significance)
4411                 }
4412         }
4413         val, res := math.Modf(number.Number / significance)
4414         if res != 0 {
4415                 if number.Number < 0 {
4416                         val--
4417                 }
4418         }
4419         return newNumberFormulaArg(val * significance)
4420 }
4421
4422 // gcd returns the greatest common divisor of two supplied integers.
4423 func gcd(x, y float64) float64 {
4424         x, y = math.Trunc(x), math.Trunc(y)
4425         if x == 0 {
4426                 return y
4427         }
4428         if y == 0 {
4429                 return x
4430         }
4431         for x != y {
4432                 if x > y {
4433                         x = x - y
4434                 } else {
4435                         y = y - x
4436                 }
4437         }
4438         return x
4439 }
4440
4441 // GCD function returns the greatest common divisor of two or more supplied
4442 // integers. The syntax of the function is:
4443 //
4444 //      GCD(number1,[number2],...)
4445 func (fn *formulaFuncs) GCD(argsList *list.List) formulaArg {
4446         if argsList.Len() == 0 {
4447                 return newErrorFormulaArg(formulaErrorVALUE, "GCD requires at least 1 argument")
4448         }
4449         var (
4450                 val  float64
4451                 nums []float64
4452         )
4453         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
4454                 token := arg.Value.(formulaArg)
4455                 switch token.Type {
4456                 case ArgString:
4457                         num := token.ToNumber()
4458                         if num.Type == ArgError {
4459                                 return num
4460                         }
4461                         val = num.Number
4462                 case ArgNumber:
4463                         val = token.Number
4464                 }
4465                 nums = append(nums, val)
4466         }
4467         if nums[0] < 0 {
4468                 return newErrorFormulaArg(formulaErrorVALUE, "GCD only accepts positive arguments")
4469         }
4470         if len(nums) == 1 {
4471                 return newNumberFormulaArg(nums[0])
4472         }
4473         cd := nums[0]
4474         for i := 1; i < len(nums); i++ {
4475                 if nums[i] < 0 {
4476                         return newErrorFormulaArg(formulaErrorVALUE, "GCD only accepts positive arguments")
4477                 }
4478                 cd = gcd(cd, nums[i])
4479         }
4480         return newNumberFormulaArg(cd)
4481 }
4482
4483 // INT function truncates a supplied number down to the closest integer. The
4484 // syntax of the function is:
4485 //
4486 //      INT(number)
4487 func (fn *formulaFuncs) INT(argsList *list.List) formulaArg {
4488         if argsList.Len() != 1 {
4489                 return newErrorFormulaArg(formulaErrorVALUE, "INT requires 1 numeric argument")
4490         }
4491         number := argsList.Front().Value.(formulaArg).ToNumber()
4492         if number.Type == ArgError {
4493                 return number
4494         }
4495         val, frac := math.Modf(number.Number)
4496         if frac < 0 {
4497                 val--
4498         }
4499         return newNumberFormulaArg(val)
4500 }
4501
4502 // ISOdotCEILING function rounds a supplied number up (regardless of the
4503 // number's sign), to the nearest multiple of a supplied significance. The
4504 // syntax of the function is:
4505 //
4506 //      ISO.CEILING(number,[significance])
4507 func (fn *formulaFuncs) ISOdotCEILING(argsList *list.List) formulaArg {
4508         if argsList.Len() == 0 {
4509                 return newErrorFormulaArg(formulaErrorVALUE, "ISO.CEILING requires at least 1 argument")
4510         }
4511         if argsList.Len() > 2 {
4512                 return newErrorFormulaArg(formulaErrorVALUE, "ISO.CEILING allows at most 2 arguments")
4513         }
4514         var significance float64
4515         number := argsList.Front().Value.(formulaArg).ToNumber()
4516         if number.Type == ArgError {
4517                 return number
4518         }
4519         if number.Number < 0 {
4520                 significance = -1
4521         }
4522         if argsList.Len() == 1 {
4523                 return newNumberFormulaArg(math.Ceil(number.Number))
4524         }
4525         if argsList.Len() > 1 {
4526                 s := argsList.Back().Value.(formulaArg).ToNumber()
4527                 if s.Type == ArgError {
4528                         return s
4529                 }
4530                 significance = s.Number
4531                 significance = math.Abs(significance)
4532                 if significance == 0 {
4533                         return newNumberFormulaArg(significance)
4534                 }
4535         }
4536         val, res := math.Modf(number.Number / significance)
4537         if res != 0 {
4538                 if number.Number > 0 {
4539                         val++
4540                 }
4541         }
4542         return newNumberFormulaArg(val * significance)
4543 }
4544
4545 // lcm returns the least common multiple of two supplied integers.
4546 func lcm(a, b float64) float64 {
4547         a = math.Trunc(a)
4548         b = math.Trunc(b)
4549         if a == 0 && b == 0 {
4550                 return 0
4551         }
4552         return a * b / gcd(a, b)
4553 }
4554
4555 // LCM function returns the least common multiple of two or more supplied
4556 // integers. The syntax of the function is:
4557 //
4558 //      LCM(number1,[number2],...)
4559 func (fn *formulaFuncs) LCM(argsList *list.List) formulaArg {
4560         if argsList.Len() == 0 {
4561                 return newErrorFormulaArg(formulaErrorVALUE, "LCM requires at least 1 argument")
4562         }
4563         var (
4564                 val  float64
4565                 nums []float64
4566                 err  error
4567         )
4568         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
4569                 token := arg.Value.(formulaArg)
4570                 switch token.Type {
4571                 case ArgString:
4572                         if token.String == "" {
4573                                 continue
4574                         }
4575                         if val, err = strconv.ParseFloat(token.String, 64); err != nil {
4576                                 return newErrorFormulaArg(formulaErrorVALUE, err.Error())
4577                         }
4578                 case ArgNumber:
4579                         val = token.Number
4580                 }
4581                 nums = append(nums, val)
4582         }
4583         if nums[0] < 0 {
4584                 return newErrorFormulaArg(formulaErrorVALUE, "LCM only accepts positive arguments")
4585         }
4586         if len(nums) == 1 {
4587                 return newNumberFormulaArg(nums[0])
4588         }
4589         cm := nums[0]
4590         for i := 1; i < len(nums); i++ {
4591                 if nums[i] < 0 {
4592                         return newErrorFormulaArg(formulaErrorVALUE, "LCM only accepts positive arguments")
4593                 }
4594                 cm = lcm(cm, nums[i])
4595         }
4596         return newNumberFormulaArg(cm)
4597 }
4598
4599 // LN function calculates the natural logarithm of a given number. The syntax
4600 // of the function is:
4601 //
4602 //      LN(number)
4603 func (fn *formulaFuncs) LN(argsList *list.List) formulaArg {
4604         if argsList.Len() != 1 {
4605                 return newErrorFormulaArg(formulaErrorVALUE, "LN requires 1 numeric argument")
4606         }
4607         number := argsList.Front().Value.(formulaArg).ToNumber()
4608         if number.Type == ArgError {
4609                 return number
4610         }
4611         return newNumberFormulaArg(math.Log(number.Number))
4612 }
4613
4614 // LOG function calculates the logarithm of a given number, to a supplied
4615 // base. The syntax of the function is:
4616 //
4617 //      LOG(number,[base])
4618 func (fn *formulaFuncs) LOG(argsList *list.List) formulaArg {
4619         if argsList.Len() == 0 {
4620                 return newErrorFormulaArg(formulaErrorVALUE, "LOG requires at least 1 argument")
4621         }
4622         if argsList.Len() > 2 {
4623                 return newErrorFormulaArg(formulaErrorVALUE, "LOG allows at most 2 arguments")
4624         }
4625         base := 10.0
4626         number := argsList.Front().Value.(formulaArg).ToNumber()
4627         if number.Type == ArgError {
4628                 return number
4629         }
4630         if argsList.Len() > 1 {
4631                 b := argsList.Back().Value.(formulaArg).ToNumber()
4632                 if b.Type == ArgError {
4633                         return b
4634                 }
4635                 base = b.Number
4636         }
4637         if number.Number == 0 {
4638                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorDIV)
4639         }
4640         if base == 0 {
4641                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorDIV)
4642         }
4643         if base == 1 {
4644                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
4645         }
4646         return newNumberFormulaArg(math.Log(number.Number) / math.Log(base))
4647 }
4648
4649 // LOG10 function calculates the base 10 logarithm of a given number. The
4650 // syntax of the function is:
4651 //
4652 //      LOG10(number)
4653 func (fn *formulaFuncs) LOG10(argsList *list.List) formulaArg {
4654         if argsList.Len() != 1 {
4655                 return newErrorFormulaArg(formulaErrorVALUE, "LOG10 requires 1 numeric argument")
4656         }
4657         number := argsList.Front().Value.(formulaArg).ToNumber()
4658         if number.Type == ArgError {
4659                 return number
4660         }
4661         return newNumberFormulaArg(math.Log10(number.Number))
4662 }
4663
4664 // minor function implement a minor of a matrix A is the determinant of some
4665 // smaller square matrix.
4666 func minor(sqMtx [][]float64, idx int) [][]float64 {
4667         var ret [][]float64
4668         for i := range sqMtx {
4669                 if i == 0 {
4670                         continue
4671                 }
4672                 var row []float64
4673                 for j := range sqMtx {
4674                         if j == idx {
4675                                 continue
4676                         }
4677                         row = append(row, sqMtx[i][j])
4678                 }
4679                 ret = append(ret, row)
4680         }
4681         return ret
4682 }
4683
4684 // det determinant of the 2x2 matrix.
4685 func det(sqMtx [][]float64) float64 {
4686         if len(sqMtx) == 2 {
4687                 m00 := sqMtx[0][0]
4688                 m01 := sqMtx[0][1]
4689                 m10 := sqMtx[1][0]
4690                 m11 := sqMtx[1][1]
4691                 return m00*m11 - m10*m01
4692         }
4693         var res, sgn float64 = 0, 1
4694         for j := range sqMtx {
4695                 res += sgn * sqMtx[0][j] * det(minor(sqMtx, j))
4696                 sgn *= -1
4697         }
4698         return res
4699 }
4700
4701 // newNumberMatrix converts a formula arguments matrix to a number matrix.
4702 func newNumberMatrix(arg formulaArg, phalanx bool) (numMtx [][]float64, ele formulaArg) {
4703         rows := len(arg.Matrix)
4704         for r, row := range arg.Matrix {
4705                 if phalanx && len(row) != rows {
4706                         ele = newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
4707                         return
4708                 }
4709                 numMtx = append(numMtx, make([]float64, len(row)))
4710                 for c, cell := range row {
4711                         if cell.Type != ArgNumber {
4712                                 ele = newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
4713                                 return
4714                         }
4715                         numMtx[r][c] = cell.Number
4716                 }
4717         }
4718         return
4719 }
4720
4721 // newFormulaArgMatrix converts the number formula arguments matrix to a
4722 // formula arguments matrix.
4723 func newFormulaArgMatrix(numMtx [][]float64) (arg [][]formulaArg) {
4724         for r, row := range numMtx {
4725                 arg = append(arg, make([]formulaArg, len(row)))
4726                 for c, cell := range row {
4727                         arg[r][c] = newNumberFormulaArg(cell)
4728                 }
4729         }
4730         return
4731 }
4732
4733 // MDETERM calculates the determinant of a square matrix. The
4734 // syntax of the function is:
4735 //
4736 //      MDETERM(array)
4737 func (fn *formulaFuncs) MDETERM(argsList *list.List) (result formulaArg) {
4738         if argsList.Len() < 1 {
4739                 return newErrorFormulaArg(formulaErrorVALUE, "MDETERM requires 1 argument")
4740         }
4741         numMtx, errArg := newNumberMatrix(argsList.Front().Value.(formulaArg), true)
4742         if errArg.Type == ArgError {
4743                 return errArg
4744         }
4745         return newNumberFormulaArg(det(numMtx))
4746 }
4747
4748 // cofactorMatrix returns the matrix A of cofactors.
4749 func cofactorMatrix(i, j int, A [][]float64) float64 {
4750         N, sign := len(A), -1.0
4751         if (i+j)%2 == 0 {
4752                 sign = 1
4753         }
4754         var B [][]float64
4755         B = append(B, A...)
4756         for m := 0; m < N; m++ {
4757                 for n := j + 1; n < N; n++ {
4758                         B[m][n-1] = B[m][n]
4759                 }
4760                 B[m] = B[m][:len(B[m])-1]
4761         }
4762         for k := i + 1; k < N; k++ {
4763                 B[k-1] = B[k]
4764         }
4765         B = B[:len(B)-1]
4766         return sign * det(B)
4767 }
4768
4769 // adjugateMatrix returns transpose of the cofactor matrix A with Cramer's
4770 // rule.
4771 func adjugateMatrix(A [][]float64) (adjA [][]float64) {
4772         N := len(A)
4773         var B [][]float64
4774         for i := 0; i < N; i++ {
4775                 adjA = append(adjA, make([]float64, N))
4776                 for j := 0; j < N; j++ {
4777                         for m := 0; m < N; m++ {
4778                                 for n := 0; n < N; n++ {
4779                                         for x := len(B); x <= m; x++ {
4780                                                 B = append(B, []float64{})
4781                                         }
4782                                         for k := len(B[m]); k <= n; k++ {
4783                                                 B[m] = append(B[m], 0)
4784                                         }
4785                                         B[m][n] = A[m][n]
4786                                 }
4787                         }
4788                         adjA[i][j] = cofactorMatrix(j, i, B)
4789                 }
4790         }
4791         return
4792 }
4793
4794 // MINVERSE function calculates the inverse of a square matrix. The syntax of
4795 // the function is:
4796 //
4797 //      MINVERSE(array)
4798 func (fn *formulaFuncs) MINVERSE(argsList *list.List) formulaArg {
4799         if argsList.Len() != 1 {
4800                 return newErrorFormulaArg(formulaErrorVALUE, "MINVERSE requires 1 argument")
4801         }
4802         numMtx, errArg := newNumberMatrix(argsList.Front().Value.(formulaArg), true)
4803         if errArg.Type == ArgError {
4804                 return errArg
4805         }
4806         if detM := det(numMtx); detM != 0 {
4807                 datM, invertM := 1/detM, adjugateMatrix(numMtx)
4808                 for i := 0; i < len(invertM); i++ {
4809                         for j := 0; j < len(invertM[i]); j++ {
4810                                 invertM[i][j] *= datM
4811                         }
4812                 }
4813                 return newMatrixFormulaArg(newFormulaArgMatrix(invertM))
4814         }
4815         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
4816 }
4817
4818 // MMULT function calculates the matrix product of two arrays
4819 // (representing matrices). The syntax of the function is:
4820 //
4821 //      MMULT(array1,array2)
4822 func (fn *formulaFuncs) MMULT(argsList *list.List) formulaArg {
4823         if argsList.Len() != 2 {
4824                 return newErrorFormulaArg(formulaErrorVALUE, "MMULT requires 2 argument")
4825         }
4826         arr1 := argsList.Front().Value.(formulaArg)
4827         arr2 := argsList.Back().Value.(formulaArg)
4828         if arr1.Type == ArgNumber && arr2.Type == ArgNumber {
4829                 return newNumberFormulaArg(arr1.Number * arr2.Number)
4830         }
4831         numMtx1, errArg1 := newNumberMatrix(arr1, false)
4832         if errArg1.Type == ArgError {
4833                 return errArg1
4834         }
4835         numMtx2, errArg2 := newNumberMatrix(arr2, false)
4836         if errArg2.Type == ArgError {
4837                 return errArg2
4838         }
4839         array2Rows, array2Cols := len(numMtx2), len(numMtx2[0])
4840         if len(numMtx1[0]) != array2Rows {
4841                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
4842         }
4843         var numMtx [][]float64
4844         var row1, row []float64
4845         var sum float64
4846         for i := 0; i < len(numMtx1); i++ {
4847                 numMtx = append(numMtx, []float64{})
4848                 row = []float64{}
4849                 row1 = numMtx1[i]
4850                 for j := 0; j < array2Cols; j++ {
4851                         sum = 0
4852                         for k := 0; k < array2Rows; k++ {
4853                                 sum += row1[k] * numMtx2[k][j]
4854                         }
4855                         for l := len(row); l <= j; l++ {
4856                                 row = append(row, 0)
4857                         }
4858                         row[j] = sum
4859                         numMtx[i] = row
4860                 }
4861         }
4862         return newMatrixFormulaArg(newFormulaArgMatrix(numMtx))
4863 }
4864
4865 // MOD function returns the remainder of a division between two supplied
4866 // numbers. The syntax of the function is:
4867 //
4868 //      MOD(number,divisor)
4869 func (fn *formulaFuncs) MOD(argsList *list.List) formulaArg {
4870         if argsList.Len() != 2 {
4871                 return newErrorFormulaArg(formulaErrorVALUE, "MOD requires 2 numeric arguments")
4872         }
4873         number := argsList.Front().Value.(formulaArg).ToNumber()
4874         if number.Type == ArgError {
4875                 return number
4876         }
4877         divisor := argsList.Back().Value.(formulaArg).ToNumber()
4878         if divisor.Type == ArgError {
4879                 return divisor
4880         }
4881         if divisor.Number == 0 {
4882                 return newErrorFormulaArg(formulaErrorDIV, "MOD divide by zero")
4883         }
4884         trunc, rem := math.Modf(number.Number / divisor.Number)
4885         if rem < 0 {
4886                 trunc--
4887         }
4888         return newNumberFormulaArg(number.Number - divisor.Number*trunc)
4889 }
4890
4891 // MROUND function rounds a supplied number up or down to the nearest multiple
4892 // of a given number. The syntax of the function is:
4893 //
4894 //      MROUND(number,multiple)
4895 func (fn *formulaFuncs) MROUND(argsList *list.List) formulaArg {
4896         if argsList.Len() != 2 {
4897                 return newErrorFormulaArg(formulaErrorVALUE, "MROUND requires 2 numeric arguments")
4898         }
4899         n := argsList.Front().Value.(formulaArg).ToNumber()
4900         if n.Type == ArgError {
4901                 return n
4902         }
4903         multiple := argsList.Back().Value.(formulaArg).ToNumber()
4904         if multiple.Type == ArgError {
4905                 return multiple
4906         }
4907         if multiple.Number == 0 {
4908                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
4909         }
4910         if multiple.Number < 0 && n.Number > 0 ||
4911                 multiple.Number > 0 && n.Number < 0 {
4912                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
4913         }
4914         number, res := math.Modf(n.Number / multiple.Number)
4915         if math.Trunc(res+0.5) > 0 {
4916                 number++
4917         }
4918         return newNumberFormulaArg(number * multiple.Number)
4919 }
4920
4921 // MULTINOMIAL function calculates the ratio of the factorial of a sum of
4922 // supplied values to the product of factorials of those values. The syntax of
4923 // the function is:
4924 //
4925 //      MULTINOMIAL(number1,[number2],...)
4926 func (fn *formulaFuncs) MULTINOMIAL(argsList *list.List) formulaArg {
4927         val, num, denom := 0.0, 0.0, 1.0
4928         var err error
4929         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
4930                 token := arg.Value.(formulaArg)
4931                 switch token.Type {
4932                 case ArgString:
4933                         if token.String == "" {
4934                                 continue
4935                         }
4936                         if val, err = strconv.ParseFloat(token.String, 64); err != nil {
4937                                 return newErrorFormulaArg(formulaErrorVALUE, err.Error())
4938                         }
4939                 case ArgNumber:
4940                         val = token.Number
4941                 }
4942                 num += val
4943                 denom *= fact(val)
4944         }
4945         return newNumberFormulaArg(fact(num) / denom)
4946 }
4947
4948 // MUNIT function returns the unit matrix for a specified dimension. The
4949 // syntax of the function is:
4950 //
4951 //      MUNIT(dimension)
4952 func (fn *formulaFuncs) MUNIT(argsList *list.List) (result formulaArg) {
4953         if argsList.Len() != 1 {
4954                 return newErrorFormulaArg(formulaErrorVALUE, "MUNIT requires 1 numeric argument")
4955         }
4956         dimension := argsList.Back().Value.(formulaArg).ToNumber()
4957         if dimension.Type == ArgError || dimension.Number < 0 {
4958                 return newErrorFormulaArg(formulaErrorVALUE, dimension.Error)
4959         }
4960         matrix := make([][]formulaArg, 0, int(dimension.Number))
4961         for i := 0; i < int(dimension.Number); i++ {
4962                 row := make([]formulaArg, int(dimension.Number))
4963                 for j := 0; j < int(dimension.Number); j++ {
4964                         if i == j {
4965                                 row[j] = newNumberFormulaArg(1.0)
4966                         } else {
4967                                 row[j] = newNumberFormulaArg(0.0)
4968                         }
4969                 }
4970                 matrix = append(matrix, row)
4971         }
4972         return newMatrixFormulaArg(matrix)
4973 }
4974
4975 // ODD function ounds a supplied number away from zero (i.e. rounds a positive
4976 // number up and a negative number down), to the next odd number. The syntax
4977 // of the function is:
4978 //
4979 //      ODD(number)
4980 func (fn *formulaFuncs) ODD(argsList *list.List) formulaArg {
4981         if argsList.Len() != 1 {
4982                 return newErrorFormulaArg(formulaErrorVALUE, "ODD requires 1 numeric argument")
4983         }
4984         number := argsList.Back().Value.(formulaArg).ToNumber()
4985         if number.Type == ArgError {
4986                 return number
4987         }
4988         if number.Number == 0 {
4989                 return newNumberFormulaArg(1)
4990         }
4991         sign := math.Signbit(number.Number)
4992         m, frac := math.Modf((number.Number - 1) / 2)
4993         val := m*2 + 1
4994         if frac != 0 {
4995                 if !sign {
4996                         val += 2
4997                 } else {
4998                         val -= 2
4999                 }
5000         }
5001         return newNumberFormulaArg(val)
5002 }
5003
5004 // PI function returns the value of the mathematical constant Ï€ (pi), accurate
5005 // to 15 digits (14 decimal places). The syntax of the function is:
5006 //
5007 //      PI()
5008 func (fn *formulaFuncs) PI(argsList *list.List) formulaArg {
5009         if argsList.Len() != 0 {
5010                 return newErrorFormulaArg(formulaErrorVALUE, "PI accepts no arguments")
5011         }
5012         return newNumberFormulaArg(math.Pi)
5013 }
5014
5015 // POWER function calculates a given number, raised to a supplied power.
5016 // The syntax of the function is:
5017 //
5018 //      POWER(number,power)
5019 func (fn *formulaFuncs) POWER(argsList *list.List) formulaArg {
5020         if argsList.Len() != 2 {
5021                 return newErrorFormulaArg(formulaErrorVALUE, "POWER requires 2 numeric arguments")
5022         }
5023         x := argsList.Front().Value.(formulaArg).ToNumber()
5024         if x.Type == ArgError {
5025                 return x
5026         }
5027         y := argsList.Back().Value.(formulaArg).ToNumber()
5028         if y.Type == ArgError {
5029                 return y
5030         }
5031         if x.Number == 0 && y.Number == 0 {
5032                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
5033         }
5034         if x.Number == 0 && y.Number < 0 {
5035                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
5036         }
5037         return newNumberFormulaArg(math.Pow(x.Number, y.Number))
5038 }
5039
5040 // PRODUCT function returns the product (multiplication) of a supplied set of
5041 // numerical values. The syntax of the function is:
5042 //
5043 //      PRODUCT(number1,[number2],...)
5044 func (fn *formulaFuncs) PRODUCT(argsList *list.List) formulaArg {
5045         product := 1.0
5046         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
5047                 token := arg.Value.(formulaArg)
5048                 switch token.Type {
5049                 case ArgString:
5050                         num := token.ToNumber()
5051                         if num.Type != ArgNumber {
5052                                 return num
5053                         }
5054                         product = product * num.Number
5055                 case ArgNumber:
5056                         product = product * token.Number
5057                 case ArgMatrix:
5058                         for _, row := range token.Matrix {
5059                                 for _, cell := range row {
5060                                         if cell.Type == ArgNumber {
5061                                                 product *= cell.Number
5062                                         }
5063                                 }
5064                         }
5065                 }
5066         }
5067         return newNumberFormulaArg(product)
5068 }
5069
5070 // QUOTIENT function returns the integer portion of a division between two
5071 // supplied numbers. The syntax of the function is:
5072 //
5073 //      QUOTIENT(numerator,denominator)
5074 func (fn *formulaFuncs) QUOTIENT(argsList *list.List) formulaArg {
5075         if argsList.Len() != 2 {
5076                 return newErrorFormulaArg(formulaErrorVALUE, "QUOTIENT requires 2 numeric arguments")
5077         }
5078         x := argsList.Front().Value.(formulaArg).ToNumber()
5079         if x.Type == ArgError {
5080                 return x
5081         }
5082         y := argsList.Back().Value.(formulaArg).ToNumber()
5083         if y.Type == ArgError {
5084                 return y
5085         }
5086         if y.Number == 0 {
5087                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
5088         }
5089         return newNumberFormulaArg(math.Trunc(x.Number / y.Number))
5090 }
5091
5092 // RADIANS function converts radians into degrees. The syntax of the function is:
5093 //
5094 //      RADIANS(angle)
5095 func (fn *formulaFuncs) RADIANS(argsList *list.List) formulaArg {
5096         if argsList.Len() != 1 {
5097                 return newErrorFormulaArg(formulaErrorVALUE, "RADIANS requires 1 numeric argument")
5098         }
5099         angle := argsList.Front().Value.(formulaArg).ToNumber()
5100         if angle.Type == ArgError {
5101                 return angle
5102         }
5103         return newNumberFormulaArg(math.Pi / 180.0 * angle.Number)
5104 }
5105
5106 // RAND function generates a random real number between 0 and 1. The syntax of
5107 // the function is:
5108 //
5109 //      RAND()
5110 func (fn *formulaFuncs) RAND(argsList *list.List) formulaArg {
5111         if argsList.Len() != 0 {
5112                 return newErrorFormulaArg(formulaErrorVALUE, "RAND accepts no arguments")
5113         }
5114         return newNumberFormulaArg(rand.New(rand.NewSource(time.Now().UnixNano())).Float64())
5115 }
5116
5117 // RANDBETWEEN function generates a random integer between two supplied
5118 // integers. The syntax of the function is:
5119 //
5120 //      RANDBETWEEN(bottom,top)
5121 func (fn *formulaFuncs) RANDBETWEEN(argsList *list.List) formulaArg {
5122         if argsList.Len() != 2 {
5123                 return newErrorFormulaArg(formulaErrorVALUE, "RANDBETWEEN requires 2 numeric arguments")
5124         }
5125         bottom := argsList.Front().Value.(formulaArg).ToNumber()
5126         if bottom.Type == ArgError {
5127                 return bottom
5128         }
5129         top := argsList.Back().Value.(formulaArg).ToNumber()
5130         if top.Type == ArgError {
5131                 return top
5132         }
5133         if top.Number < bottom.Number {
5134                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
5135         }
5136         num := rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(int64(top.Number - bottom.Number + 1))
5137         return newNumberFormulaArg(float64(num + int64(bottom.Number)))
5138 }
5139
5140 // romanNumerals defined a numeral system that originated in ancient Rome and
5141 // remained the usual way of writing numbers throughout Europe well into the
5142 // Late Middle Ages.
5143 type romanNumerals struct {
5144         n float64
5145         s string
5146 }
5147
5148 var romanTable = [][]romanNumerals{
5149         {
5150                 {1000, "M"},
5151                 {900, "CM"},
5152                 {500, "D"},
5153                 {400, "CD"},
5154                 {100, "C"},
5155                 {90, "XC"},
5156                 {50, "L"},
5157                 {40, "XL"},
5158                 {10, "X"},
5159                 {9, "IX"},
5160                 {5, "V"},
5161                 {4, "IV"},
5162                 {1, "I"},
5163         },
5164         {
5165                 {1000, "M"},
5166                 {950, "LM"},
5167                 {900, "CM"},
5168                 {500, "D"},
5169                 {450, "LD"},
5170                 {400, "CD"},
5171                 {100, "C"},
5172                 {95, "VC"},
5173                 {90, "XC"},
5174                 {50, "L"},
5175                 {45, "VL"},
5176                 {40, "XL"},
5177                 {10, "X"},
5178                 {9, "IX"},
5179                 {5, "V"},
5180                 {4, "IV"},
5181                 {1, "I"},
5182         },
5183         {
5184                 {1000, "M"},
5185                 {990, "XM"},
5186                 {950, "LM"},
5187                 {900, "CM"},
5188                 {500, "D"},
5189                 {490, "XD"},
5190                 {450, "LD"},
5191                 {400, "CD"},
5192                 {100, "C"},
5193                 {99, "IC"},
5194                 {90, "XC"},
5195                 {50, "L"},
5196                 {45, "VL"},
5197                 {40, "XL"},
5198                 {10, "X"},
5199                 {9, "IX"},
5200                 {5, "V"},
5201                 {4, "IV"},
5202                 {1, "I"},
5203         },
5204         {
5205                 {1000, "M"},
5206                 {995, "VM"},
5207                 {990, "XM"},
5208                 {950, "LM"},
5209                 {900, "CM"},
5210                 {500, "D"},
5211                 {495, "VD"},
5212                 {490, "XD"},
5213                 {450, "LD"},
5214                 {400, "CD"},
5215                 {100, "C"},
5216                 {99, "IC"},
5217                 {90, "XC"},
5218                 {50, "L"},
5219                 {45, "VL"},
5220                 {40, "XL"},
5221                 {10, "X"},
5222                 {9, "IX"},
5223                 {5, "V"},
5224                 {4, "IV"},
5225                 {1, "I"},
5226         },
5227         {
5228                 {1000, "M"},
5229                 {999, "IM"},
5230                 {995, "VM"},
5231                 {990, "XM"},
5232                 {950, "LM"},
5233                 {900, "CM"},
5234                 {500, "D"},
5235                 {499, "ID"},
5236                 {495, "VD"},
5237                 {490, "XD"},
5238                 {450, "LD"},
5239                 {400, "CD"},
5240                 {100, "C"},
5241                 {99, "IC"},
5242                 {90, "XC"},
5243                 {50, "L"},
5244                 {45, "VL"},
5245                 {40, "XL"},
5246                 {10, "X"},
5247                 {9, "IX"},
5248                 {5, "V"},
5249                 {4, "IV"},
5250                 {1, "I"},
5251         },
5252 }
5253
5254 // ROMAN function converts an arabic number to Roman. I.e. for a supplied
5255 // integer, the function returns a text string depicting the roman numeral
5256 // form of the number. The syntax of the function is:
5257 //
5258 //      ROMAN(number,[form])
5259 func (fn *formulaFuncs) ROMAN(argsList *list.List) formulaArg {
5260         if argsList.Len() == 0 {
5261                 return newErrorFormulaArg(formulaErrorVALUE, "ROMAN requires at least 1 argument")
5262         }
5263         if argsList.Len() > 2 {
5264                 return newErrorFormulaArg(formulaErrorVALUE, "ROMAN allows at most 2 arguments")
5265         }
5266         var form int
5267         number := argsList.Front().Value.(formulaArg).ToNumber()
5268         if number.Type == ArgError {
5269                 return number
5270         }
5271         if argsList.Len() > 1 {
5272                 f := argsList.Back().Value.(formulaArg).ToNumber()
5273                 if f.Type == ArgError {
5274                         return f
5275                 }
5276                 form = int(f.Number)
5277                 if form < 0 {
5278                         form = 0
5279                 } else if form > 4 {
5280                         form = 4
5281                 }
5282         }
5283         decimalTable := romanTable[0]
5284         switch form {
5285         case 1:
5286                 decimalTable = romanTable[1]
5287         case 2:
5288                 decimalTable = romanTable[2]
5289         case 3:
5290                 decimalTable = romanTable[3]
5291         case 4:
5292                 decimalTable = romanTable[4]
5293         }
5294         val := math.Trunc(number.Number)
5295         buf := bytes.Buffer{}
5296         for _, r := range decimalTable {
5297                 for val >= r.n {
5298                         buf.WriteString(r.s)
5299                         val -= r.n
5300                 }
5301         }
5302         return newStringFormulaArg(buf.String())
5303 }
5304
5305 type roundMode byte
5306
5307 const (
5308         closest roundMode = iota
5309         down
5310         up
5311 )
5312
5313 // round rounds a supplied number up or down.
5314 func (fn *formulaFuncs) round(number, digits float64, mode roundMode) float64 {
5315         var significance float64
5316         if digits > 0 {
5317                 significance = math.Pow(1/10.0, digits)
5318         } else {
5319                 significance = math.Pow(10.0, -digits)
5320         }
5321         val, res := math.Modf(number / significance)
5322         switch mode {
5323         case closest:
5324                 const eps = 0.499999999
5325                 if res >= eps {
5326                         val++
5327                 } else if res <= -eps {
5328                         val--
5329                 }
5330         case down:
5331         case up:
5332                 if res > 0 {
5333                         val++
5334                 } else if res < 0 {
5335                         val--
5336                 }
5337         }
5338         return val * significance
5339 }
5340
5341 // ROUND function rounds a supplied number up or down, to a specified number
5342 // of decimal places. The syntax of the function is:
5343 //
5344 //      ROUND(number,num_digits)
5345 func (fn *formulaFuncs) ROUND(argsList *list.List) formulaArg {
5346         if argsList.Len() != 2 {
5347                 return newErrorFormulaArg(formulaErrorVALUE, "ROUND requires 2 numeric arguments")
5348         }
5349         number := argsList.Front().Value.(formulaArg).ToNumber()
5350         if number.Type == ArgError {
5351                 return number
5352         }
5353         digits := argsList.Back().Value.(formulaArg).ToNumber()
5354         if digits.Type == ArgError {
5355                 return digits
5356         }
5357         return newNumberFormulaArg(fn.round(number.Number, digits.Number, closest))
5358 }
5359
5360 // ROUNDDOWN function rounds a supplied number down towards zero, to a
5361 // specified number of decimal places. The syntax of the function is:
5362 //
5363 //      ROUNDDOWN(number,num_digits)
5364 func (fn *formulaFuncs) ROUNDDOWN(argsList *list.List) formulaArg {
5365         if argsList.Len() != 2 {
5366                 return newErrorFormulaArg(formulaErrorVALUE, "ROUNDDOWN requires 2 numeric arguments")
5367         }
5368         number := argsList.Front().Value.(formulaArg).ToNumber()
5369         if number.Type == ArgError {
5370                 return number
5371         }
5372         digits := argsList.Back().Value.(formulaArg).ToNumber()
5373         if digits.Type == ArgError {
5374                 return digits
5375         }
5376         return newNumberFormulaArg(fn.round(number.Number, digits.Number, down))
5377 }
5378
5379 // ROUNDUP function rounds a supplied number up, away from zero, to a
5380 // specified number of decimal places. The syntax of the function is:
5381 //
5382 //      ROUNDUP(number,num_digits)
5383 func (fn *formulaFuncs) ROUNDUP(argsList *list.List) formulaArg {
5384         if argsList.Len() != 2 {
5385                 return newErrorFormulaArg(formulaErrorVALUE, "ROUNDUP requires 2 numeric arguments")
5386         }
5387         number := argsList.Front().Value.(formulaArg).ToNumber()
5388         if number.Type == ArgError {
5389                 return number
5390         }
5391         digits := argsList.Back().Value.(formulaArg).ToNumber()
5392         if digits.Type == ArgError {
5393                 return digits
5394         }
5395         return newNumberFormulaArg(fn.round(number.Number, digits.Number, up))
5396 }
5397
5398 // SEC function calculates the secant of a given angle. The syntax of the
5399 // function is:
5400 //
5401 //      SEC(number)
5402 func (fn *formulaFuncs) SEC(argsList *list.List) formulaArg {
5403         if argsList.Len() != 1 {
5404                 return newErrorFormulaArg(formulaErrorVALUE, "SEC requires 1 numeric argument")
5405         }
5406         number := argsList.Front().Value.(formulaArg).ToNumber()
5407         if number.Type == ArgError {
5408                 return number
5409         }
5410         return newNumberFormulaArg(math.Cos(number.Number))
5411 }
5412
5413 // SECH function calculates the hyperbolic secant (sech) of a supplied angle.
5414 // The syntax of the function is:
5415 //
5416 //      SECH(number)
5417 func (fn *formulaFuncs) SECH(argsList *list.List) formulaArg {
5418         if argsList.Len() != 1 {
5419                 return newErrorFormulaArg(formulaErrorVALUE, "SECH requires 1 numeric argument")
5420         }
5421         number := argsList.Front().Value.(formulaArg).ToNumber()
5422         if number.Type == ArgError {
5423                 return number
5424         }
5425         return newNumberFormulaArg(1 / math.Cosh(number.Number))
5426 }
5427
5428 // SERIESSUM function returns the sum of a power series. The syntax of the
5429 // function is:
5430 //
5431 //      SERIESSUM(x,n,m,coefficients)
5432 func (fn *formulaFuncs) SERIESSUM(argsList *list.List) formulaArg {
5433         if argsList.Len() != 4 {
5434                 return newErrorFormulaArg(formulaErrorVALUE, "SERIESSUM requires 4 arguments")
5435         }
5436         var x, n, m formulaArg
5437         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
5438                 return x
5439         }
5440         if n = argsList.Front().Next().Value.(formulaArg).ToNumber(); n.Type != ArgNumber {
5441                 return n
5442         }
5443         if m = argsList.Front().Next().Next().Value.(formulaArg).ToNumber(); m.Type != ArgNumber {
5444                 return m
5445         }
5446         var result, i float64
5447         for _, coefficient := range argsList.Back().Value.(formulaArg).ToList() {
5448                 if coefficient.Value() == "" {
5449                         continue
5450                 }
5451                 num := coefficient.ToNumber()
5452                 if num.Type != ArgNumber {
5453                         return num
5454                 }
5455                 result += num.Number * math.Pow(x.Number, n.Number+(m.Number*i))
5456                 i++
5457         }
5458         return newNumberFormulaArg(result)
5459 }
5460
5461 // SIGN function returns the arithmetic sign (+1, -1 or 0) of a supplied
5462 // number. I.e. if the number is positive, the Sign function returns +1, if
5463 // the number is negative, the function returns -1 and if the number is 0
5464 // (zero), the function returns 0. The syntax of the function is:
5465 //
5466 //      SIGN(number)
5467 func (fn *formulaFuncs) SIGN(argsList *list.List) formulaArg {
5468         if argsList.Len() != 1 {
5469                 return newErrorFormulaArg(formulaErrorVALUE, "SIGN requires 1 numeric argument")
5470         }
5471         val := argsList.Front().Value.(formulaArg).ToNumber()
5472         if val.Type == ArgError {
5473                 return val
5474         }
5475         if val.Number < 0 {
5476                 return newNumberFormulaArg(-1)
5477         }
5478         if val.Number > 0 {
5479                 return newNumberFormulaArg(1)
5480         }
5481         return newNumberFormulaArg(0)
5482 }
5483
5484 // SIN function calculates the sine of a given angle. The syntax of the
5485 // function is:
5486 //
5487 //      SIN(number)
5488 func (fn *formulaFuncs) SIN(argsList *list.List) formulaArg {
5489         if argsList.Len() != 1 {
5490                 return newErrorFormulaArg(formulaErrorVALUE, "SIN requires 1 numeric argument")
5491         }
5492         number := argsList.Front().Value.(formulaArg).ToNumber()
5493         if number.Type == ArgError {
5494                 return number
5495         }
5496         return newNumberFormulaArg(math.Sin(number.Number))
5497 }
5498
5499 // SINH function calculates the hyperbolic sine (sinh) of a supplied number.
5500 // The syntax of the function is:
5501 //
5502 //      SINH(number)
5503 func (fn *formulaFuncs) SINH(argsList *list.List) formulaArg {
5504         if argsList.Len() != 1 {
5505                 return newErrorFormulaArg(formulaErrorVALUE, "SINH requires 1 numeric argument")
5506         }
5507         number := argsList.Front().Value.(formulaArg).ToNumber()
5508         if number.Type == ArgError {
5509                 return number
5510         }
5511         return newNumberFormulaArg(math.Sinh(number.Number))
5512 }
5513
5514 // SQRT function calculates the positive square root of a supplied number. The
5515 // syntax of the function is:
5516 //
5517 //      SQRT(number)
5518 func (fn *formulaFuncs) SQRT(argsList *list.List) formulaArg {
5519         if argsList.Len() != 1 {
5520                 return newErrorFormulaArg(formulaErrorVALUE, "SQRT requires 1 numeric argument")
5521         }
5522         value := argsList.Front().Value.(formulaArg).ToNumber()
5523         if value.Type == ArgError {
5524                 return value
5525         }
5526         if value.Number < 0 {
5527                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
5528         }
5529         return newNumberFormulaArg(math.Sqrt(value.Number))
5530 }
5531
5532 // SQRTPI function returns the square root of a supplied number multiplied by
5533 // the mathematical constant, Ï€. The syntax of the function is:
5534 //
5535 //      SQRTPI(number)
5536 func (fn *formulaFuncs) SQRTPI(argsList *list.List) formulaArg {
5537         if argsList.Len() != 1 {
5538                 return newErrorFormulaArg(formulaErrorVALUE, "SQRTPI requires 1 numeric argument")
5539         }
5540         number := argsList.Front().Value.(formulaArg).ToNumber()
5541         if number.Type == ArgError {
5542                 return number
5543         }
5544         return newNumberFormulaArg(math.Sqrt(number.Number * math.Pi))
5545 }
5546
5547 // STDEV function calculates the sample standard deviation of a supplied set
5548 // of values. The syntax of the function is:
5549 //
5550 //      STDEV(number1,[number2],...)
5551 func (fn *formulaFuncs) STDEV(argsList *list.List) formulaArg {
5552         if argsList.Len() < 1 {
5553                 return newErrorFormulaArg(formulaErrorVALUE, "STDEV requires at least 1 argument")
5554         }
5555         return fn.stdev(false, argsList)
5556 }
5557
5558 // STDEVdotS function calculates the sample standard deviation of a supplied
5559 // set of values. The syntax of the function is:
5560 //
5561 //      STDEV.S(number1,[number2],...)
5562 func (fn *formulaFuncs) STDEVdotS(argsList *list.List) formulaArg {
5563         if argsList.Len() < 1 {
5564                 return newErrorFormulaArg(formulaErrorVALUE, "STDEV.S requires at least 1 argument")
5565         }
5566         return fn.stdev(false, argsList)
5567 }
5568
5569 // STDEVA function estimates standard deviation based on a sample. The
5570 // standard deviation is a measure of how widely values are dispersed from
5571 // the average value (the mean). The syntax of the function is:
5572 //
5573 //      STDEVA(number1,[number2],...)
5574 func (fn *formulaFuncs) STDEVA(argsList *list.List) formulaArg {
5575         if argsList.Len() < 1 {
5576                 return newErrorFormulaArg(formulaErrorVALUE, "STDEVA requires at least 1 argument")
5577         }
5578         return fn.stdev(true, argsList)
5579 }
5580
5581 // calcStdevPow is part of the implementation stdev.
5582 func calcStdevPow(result, count float64, n, m formulaArg) (float64, float64) {
5583         if result == -1 {
5584                 result = math.Pow(n.Number-m.Number, 2)
5585         } else {
5586                 result += math.Pow(n.Number-m.Number, 2)
5587         }
5588         count++
5589         return result, count
5590 }
5591
5592 // calcStdev is part of the implementation stdev.
5593 func calcStdev(stdeva bool, result, count float64, mean, token formulaArg) (float64, float64) {
5594         for _, row := range token.ToList() {
5595                 if row.Type == ArgNumber || row.Type == ArgString {
5596                         if !stdeva && (row.Value() == "TRUE" || row.Value() == "FALSE") {
5597                                 continue
5598                         } else if stdeva && (row.Value() == "TRUE" || row.Value() == "FALSE") {
5599                                 num := row.ToBool()
5600                                 if num.Type == ArgNumber {
5601                                         result, count = calcStdevPow(result, count, num, mean)
5602                                         continue
5603                                 }
5604                         } else {
5605                                 num := row.ToNumber()
5606                                 if num.Type == ArgNumber {
5607                                         result, count = calcStdevPow(result, count, num, mean)
5608                                 }
5609                         }
5610                 }
5611         }
5612         return result, count
5613 }
5614
5615 // stdev is an implementation of the formula functions STDEV and STDEVA.
5616 func (fn *formulaFuncs) stdev(stdeva bool, argsList *list.List) formulaArg {
5617         count, result := -1.0, -1.0
5618         var mean formulaArg
5619         if stdeva {
5620                 mean = fn.AVERAGEA(argsList)
5621         } else {
5622                 mean = fn.AVERAGE(argsList)
5623         }
5624         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
5625                 token := arg.Value.(formulaArg)
5626                 switch token.Type {
5627                 case ArgString, ArgNumber:
5628                         if !stdeva && (token.Value() == "TRUE" || token.Value() == "FALSE") {
5629                                 continue
5630                         } else if stdeva && (token.Value() == "TRUE" || token.Value() == "FALSE") {
5631                                 num := token.ToBool()
5632                                 if num.Type == ArgNumber {
5633                                         result, count = calcStdevPow(result, count, num, mean)
5634                                         continue
5635                                 }
5636                         } else {
5637                                 num := token.ToNumber()
5638                                 if num.Type == ArgNumber {
5639                                         result, count = calcStdevPow(result, count, num, mean)
5640                                 }
5641                         }
5642                 case ArgList, ArgMatrix:
5643                         result, count = calcStdev(stdeva, result, count, mean, token)
5644                 }
5645         }
5646         if count > 0 && result >= 0 {
5647                 return newNumberFormulaArg(math.Sqrt(result / count))
5648         }
5649         return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
5650 }
5651
5652 // POISSONdotDIST function calculates the Poisson Probability Mass Function or
5653 // the Cumulative Poisson Probability Function for a supplied set of
5654 // parameters. The syntax of the function is:
5655 //
5656 //      POISSON.DIST(x,mean,cumulative)
5657 func (fn *formulaFuncs) POISSONdotDIST(argsList *list.List) formulaArg {
5658         if argsList.Len() != 3 {
5659                 return newErrorFormulaArg(formulaErrorVALUE, "POISSON.DIST requires 3 arguments")
5660         }
5661         return fn.POISSON(argsList)
5662 }
5663
5664 // POISSON function calculates the Poisson Probability Mass Function or the
5665 // Cumulative Poisson Probability Function for a supplied set of parameters.
5666 // The syntax of the function is:
5667 //
5668 //      POISSON(x,mean,cumulative)
5669 func (fn *formulaFuncs) POISSON(argsList *list.List) formulaArg {
5670         if argsList.Len() != 3 {
5671                 return newErrorFormulaArg(formulaErrorVALUE, "POISSON requires 3 arguments")
5672         }
5673         var x, mean, cumulative formulaArg
5674         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
5675                 return x
5676         }
5677         if mean = argsList.Front().Next().Value.(formulaArg).ToNumber(); mean.Type != ArgNumber {
5678                 return mean
5679         }
5680         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
5681                 return cumulative
5682         }
5683         if x.Number < 0 || mean.Number <= 0 {
5684                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
5685         }
5686         if cumulative.Number == 1 {
5687                 summer := 0.0
5688                 floor := math.Floor(x.Number)
5689                 for i := 0; i <= int(floor); i++ {
5690                         summer += math.Pow(mean.Number, float64(i)) / fact(float64(i))
5691                 }
5692                 return newNumberFormulaArg(math.Exp(0-mean.Number) * summer)
5693         }
5694         return newNumberFormulaArg(math.Exp(0-mean.Number) * math.Pow(mean.Number, x.Number) / fact(x.Number))
5695 }
5696
5697 // prepareProbArgs checking and prepare arguments for the formula function
5698 // PROB.
5699 func prepareProbArgs(argsList *list.List) []formulaArg {
5700         if argsList.Len() < 3 {
5701                 return []formulaArg{newErrorFormulaArg(formulaErrorVALUE, "PROB requires at least 3 arguments")}
5702         }
5703         if argsList.Len() > 4 {
5704                 return []formulaArg{newErrorFormulaArg(formulaErrorVALUE, "PROB requires at most 4 arguments")}
5705         }
5706         var lower, upper formulaArg
5707         xRange := argsList.Front().Value.(formulaArg)
5708         probRange := argsList.Front().Next().Value.(formulaArg)
5709         if lower = argsList.Front().Next().Next().Value.(formulaArg); lower.Type != ArgNumber {
5710                 return []formulaArg{newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)}
5711         }
5712         upper = lower
5713         if argsList.Len() == 4 {
5714                 if upper = argsList.Back().Value.(formulaArg); upper.Type != ArgNumber {
5715                         return []formulaArg{newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)}
5716                 }
5717         }
5718         nR1, nR2 := len(xRange.Matrix), len(probRange.Matrix)
5719         if nR1 == 0 || nR2 == 0 {
5720                 return []formulaArg{newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)}
5721         }
5722         if nR1 != nR2 {
5723                 return []formulaArg{newErrorFormulaArg(formulaErrorNA, formulaErrorNA)}
5724         }
5725         nC1, nC2 := len(xRange.Matrix[0]), len(probRange.Matrix[0])
5726         if nC1 != nC2 {
5727                 return []formulaArg{newErrorFormulaArg(formulaErrorNA, formulaErrorNA)}
5728         }
5729         return []formulaArg{xRange, probRange, lower, upper}
5730 }
5731
5732 // PROB function calculates the probability associated with a given range. The
5733 // syntax of the function is:
5734 //
5735 //      PROB(x_range,prob_range,lower_limit,[upper_limit])
5736 func (fn *formulaFuncs) PROB(argsList *list.List) formulaArg {
5737         args := prepareProbArgs(argsList)
5738         if len(args) == 1 {
5739                 return args[0]
5740         }
5741         xRange, probRange, lower, upper := args[0], args[1], args[2], args[3]
5742         var sum, res, fP, fW float64
5743         var stop bool
5744         for r := 0; r < len(xRange.Matrix) && !stop; r++ {
5745                 for c := 0; c < len(xRange.Matrix[0]) && !stop; c++ {
5746                         p := probRange.Matrix[r][c]
5747                         x := xRange.Matrix[r][c]
5748                         if p.Type == ArgNumber && x.Type == ArgNumber {
5749                                 if fP, fW = p.Number, x.Number; fP < 0 || fP > 1 {
5750                                         stop = true
5751                                         continue
5752                                 }
5753                                 if sum += fP; fW >= lower.Number && fW <= upper.Number {
5754                                         res += fP
5755                                 }
5756                                 continue
5757                         }
5758                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
5759                 }
5760         }
5761         if stop || math.Abs(sum-1) > 1.0e-7 {
5762                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
5763         }
5764         return newNumberFormulaArg(res)
5765 }
5766
5767 // SUBTOTAL function performs a specified calculation (e.g. the sum, product,
5768 // average, etc.) for a supplied set of values. The syntax of the function is:
5769 //
5770 //      SUBTOTAL(function_num,ref1,[ref2],...)
5771 func (fn *formulaFuncs) SUBTOTAL(argsList *list.List) formulaArg {
5772         if argsList.Len() < 2 {
5773                 return newErrorFormulaArg(formulaErrorVALUE, "SUBTOTAL requires at least 2 arguments")
5774         }
5775         var fnNum formulaArg
5776         if fnNum = argsList.Front().Value.(formulaArg).ToNumber(); fnNum.Type != ArgNumber {
5777                 return fnNum
5778         }
5779         subFn, ok := map[int]func(argsList *list.List) formulaArg{
5780                 1: fn.AVERAGE, 101: fn.AVERAGE,
5781                 2: fn.COUNT, 102: fn.COUNT,
5782                 3: fn.COUNTA, 103: fn.COUNTA,
5783                 4: fn.MAX, 104: fn.MAX,
5784                 5: fn.MIN, 105: fn.MIN,
5785                 6: fn.PRODUCT, 106: fn.PRODUCT,
5786                 7: fn.STDEV, 107: fn.STDEV,
5787                 8: fn.STDEVP, 108: fn.STDEVP,
5788                 9: fn.SUM, 109: fn.SUM,
5789                 10: fn.VAR, 110: fn.VAR,
5790                 11: fn.VARP, 111: fn.VARP,
5791         }[int(fnNum.Number)]
5792         if !ok {
5793                 return newErrorFormulaArg(formulaErrorVALUE, "SUBTOTAL has invalid function_num")
5794         }
5795         subArgList := list.New().Init()
5796         for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() {
5797                 subArgList.PushBack(arg.Value.(formulaArg))
5798         }
5799         return subFn(subArgList)
5800 }
5801
5802 // SUM function adds together a supplied set of numbers and returns the sum of
5803 // these values. The syntax of the function is:
5804 //
5805 //      SUM(number1,[number2],...)
5806 func (fn *formulaFuncs) SUM(argsList *list.List) formulaArg {
5807         var sum float64
5808         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
5809                 token := arg.Value.(formulaArg)
5810                 switch token.Type {
5811                 case ArgError:
5812                         return token
5813                 case ArgString:
5814                         if num := token.ToNumber(); num.Type == ArgNumber {
5815                                 sum += num.Number
5816                         }
5817                 case ArgNumber:
5818                         sum += token.Number
5819                 case ArgMatrix:
5820                         for _, row := range token.Matrix {
5821                                 for _, value := range row {
5822                                         if num := value.ToNumber(); num.Type == ArgNumber {
5823                                                 sum += num.Number
5824                                         }
5825                                 }
5826                         }
5827                 }
5828         }
5829         return newNumberFormulaArg(sum)
5830 }
5831
5832 // SUMIF function finds the values in a supplied array, that satisfy a given
5833 // criteria, and returns the sum of the corresponding values in a second
5834 // supplied array. The syntax of the function is:
5835 //
5836 //      SUMIF(range,criteria,[sum_range])
5837 func (fn *formulaFuncs) SUMIF(argsList *list.List) formulaArg {
5838         if argsList.Len() < 2 {
5839                 return newErrorFormulaArg(formulaErrorVALUE, "SUMIF requires at least 2 arguments")
5840         }
5841         criteria := formulaCriteriaParser(argsList.Front().Next().Value.(formulaArg))
5842         rangeMtx := argsList.Front().Value.(formulaArg).Matrix
5843         var sumRange [][]formulaArg
5844         if argsList.Len() == 3 {
5845                 sumRange = argsList.Back().Value.(formulaArg).Matrix
5846         }
5847         var sum float64
5848         var arg formulaArg
5849         for rowIdx, row := range rangeMtx {
5850                 for colIdx, cell := range row {
5851                         arg = cell
5852                         if arg.Type == ArgEmpty {
5853                                 continue
5854                         }
5855                         if ok, _ := formulaCriteriaEval(arg, criteria); ok {
5856                                 if argsList.Len() == 3 {
5857                                         if len(sumRange) > rowIdx && len(sumRange[rowIdx]) > colIdx {
5858                                                 arg = sumRange[rowIdx][colIdx]
5859                                         }
5860                                 }
5861                                 if arg.Type == ArgNumber {
5862                                         sum += arg.Number
5863                                 }
5864                         }
5865                 }
5866         }
5867         return newNumberFormulaArg(sum)
5868 }
5869
5870 // SUMIFS function finds values in one or more supplied arrays, that satisfy a
5871 // set of criteria, and returns the sum of the corresponding values in a
5872 // further supplied array. The syntax of the function is:
5873 //
5874 //      SUMIFS(sum_range,criteria_range1,criteria1,[criteria_range2,criteria2],...)
5875 func (fn *formulaFuncs) SUMIFS(argsList *list.List) formulaArg {
5876         if argsList.Len() < 3 {
5877                 return newErrorFormulaArg(formulaErrorVALUE, "SUMIFS requires at least 3 arguments")
5878         }
5879         if argsList.Len()%2 != 1 {
5880                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
5881         }
5882         var args []formulaArg
5883         sum, sumRange := 0.0, argsList.Front().Value.(formulaArg).Matrix
5884         for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() {
5885                 args = append(args, arg.Value.(formulaArg))
5886         }
5887         for _, ref := range formulaIfsMatch(args) {
5888                 if ref.Row >= len(sumRange) || ref.Col >= len(sumRange[ref.Row]) {
5889                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
5890                 }
5891                 if num := sumRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber {
5892                         sum += num.Number
5893                 }
5894         }
5895         return newNumberFormulaArg(sum)
5896 }
5897
5898 // sumproduct is an implementation of the formula function SUMPRODUCT.
5899 func (fn *formulaFuncs) sumproduct(argsList *list.List) formulaArg {
5900         var (
5901                 argType ArgType
5902                 n       int
5903                 res     []float64
5904                 sum     float64
5905         )
5906         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
5907                 token := arg.Value.(formulaArg)
5908                 if argType == ArgUnknown {
5909                         argType = token.Type
5910                 }
5911                 if token.Type != argType {
5912                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
5913                 }
5914                 switch token.Type {
5915                 case ArgString, ArgNumber:
5916                         if num := token.ToNumber(); num.Type == ArgNumber {
5917                                 sum = fn.PRODUCT(argsList).Number
5918                                 continue
5919                         }
5920                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
5921                 case ArgMatrix:
5922                         args := token.ToList()
5923                         if res == nil {
5924                                 n = len(args)
5925                                 res = make([]float64, n)
5926                                 for i := range res {
5927                                         res[i] = 1.0
5928                                 }
5929                         }
5930                         if len(args) != n {
5931                                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
5932                         }
5933                         for i, value := range args {
5934                                 num := value.ToNumber()
5935                                 if num.Type != ArgNumber && value.Value() != "" {
5936                                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
5937                                 }
5938                                 res[i] = res[i] * num.Number
5939                         }
5940                 }
5941         }
5942         for _, r := range res {
5943                 sum += r
5944         }
5945         return newNumberFormulaArg(sum)
5946 }
5947
5948 // SUMPRODUCT function returns the sum of the products of the corresponding
5949 // values in a set of supplied arrays. The syntax of the function is:
5950 //
5951 //      SUMPRODUCT(array1,[array2],[array3],...)
5952 func (fn *formulaFuncs) SUMPRODUCT(argsList *list.List) formulaArg {
5953         if argsList.Len() < 1 {
5954                 return newErrorFormulaArg(formulaErrorVALUE, "SUMPRODUCT requires at least 1 argument")
5955         }
5956         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
5957                 if token := arg.Value.(formulaArg); token.Type == ArgError {
5958                         return token
5959                 }
5960         }
5961         return fn.sumproduct(argsList)
5962 }
5963
5964 // SUMSQ function returns the sum of squares of a supplied set of values. The
5965 // syntax of the function is:
5966 //
5967 //      SUMSQ(number1,[number2],...)
5968 func (fn *formulaFuncs) SUMSQ(argsList *list.List) formulaArg {
5969         var val, sq float64
5970         var err error
5971         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
5972                 token := arg.Value.(formulaArg)
5973                 switch token.Type {
5974                 case ArgString:
5975                         if token.String == "" {
5976                                 continue
5977                         }
5978                         if val, err = strconv.ParseFloat(token.String, 64); err != nil {
5979                                 return newErrorFormulaArg(formulaErrorVALUE, err.Error())
5980                         }
5981                         sq += val * val
5982                 case ArgNumber:
5983                         sq += token.Number * token.Number
5984                 case ArgMatrix:
5985                         for _, row := range token.Matrix {
5986                                 for _, value := range row {
5987                                         if value.Value() == "" {
5988                                                 continue
5989                                         }
5990                                         if val, err = strconv.ParseFloat(value.Value(), 64); err != nil {
5991                                                 return newErrorFormulaArg(formulaErrorVALUE, err.Error())
5992                                         }
5993                                         sq += val * val
5994                                 }
5995                         }
5996                 }
5997         }
5998         return newNumberFormulaArg(sq)
5999 }
6000
6001 // sumx is an implementation of the formula functions SUMX2MY2, SUMX2PY2 and
6002 // SUMXMY2.
6003 func (fn *formulaFuncs) sumx(name string, argsList *list.List) formulaArg {
6004         if argsList.Len() != 2 {
6005                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 arguments", name))
6006         }
6007         array1 := argsList.Front().Value.(formulaArg)
6008         array2 := argsList.Back().Value.(formulaArg)
6009         left, right := array1.ToList(), array2.ToList()
6010         n := len(left)
6011         if n != len(right) {
6012                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
6013         }
6014         result := 0.0
6015         for i := 0; i < n; i++ {
6016                 if lhs, rhs := left[i].ToNumber(), right[i].ToNumber(); lhs.Number != 0 && rhs.Number != 0 {
6017                         switch name {
6018                         case "SUMX2MY2":
6019                                 result += lhs.Number*lhs.Number - rhs.Number*rhs.Number
6020                         case "SUMX2PY2":
6021                                 result += lhs.Number*lhs.Number + rhs.Number*rhs.Number
6022                         default:
6023                                 result += (lhs.Number - rhs.Number) * (lhs.Number - rhs.Number)
6024                         }
6025                 }
6026         }
6027         return newNumberFormulaArg(result)
6028 }
6029
6030 // SUMX2MY2 function returns the sum of the differences of squares of two
6031 // supplied sets of values. The syntax of the function is:
6032 //
6033 //      SUMX2MY2(array_x,array_y)
6034 func (fn *formulaFuncs) SUMX2MY2(argsList *list.List) formulaArg {
6035         return fn.sumx("SUMX2MY2", argsList)
6036 }
6037
6038 // SUMX2PY2 function returns the sum of the sum of squares of two supplied sets
6039 // of values. The syntax of the function is:
6040 //
6041 //      SUMX2PY2(array_x,array_y)
6042 func (fn *formulaFuncs) SUMX2PY2(argsList *list.List) formulaArg {
6043         return fn.sumx("SUMX2PY2", argsList)
6044 }
6045
6046 // SUMXMY2 function returns the sum of the squares of differences between
6047 // corresponding values in two supplied arrays. The syntax of the function
6048 // is:
6049 //
6050 //      SUMXMY2(array_x,array_y)
6051 func (fn *formulaFuncs) SUMXMY2(argsList *list.List) formulaArg {
6052         return fn.sumx("SUMXMY2", argsList)
6053 }
6054
6055 // TAN function calculates the tangent of a given angle. The syntax of the
6056 // function is:
6057 //
6058 //      TAN(number)
6059 func (fn *formulaFuncs) TAN(argsList *list.List) formulaArg {
6060         if argsList.Len() != 1 {
6061                 return newErrorFormulaArg(formulaErrorVALUE, "TAN requires 1 numeric argument")
6062         }
6063         number := argsList.Front().Value.(formulaArg).ToNumber()
6064         if number.Type == ArgError {
6065                 return number
6066         }
6067         return newNumberFormulaArg(math.Tan(number.Number))
6068 }
6069
6070 // TANH function calculates the hyperbolic tangent (tanh) of a supplied
6071 // number. The syntax of the function is:
6072 //
6073 //      TANH(number)
6074 func (fn *formulaFuncs) TANH(argsList *list.List) formulaArg {
6075         if argsList.Len() != 1 {
6076                 return newErrorFormulaArg(formulaErrorVALUE, "TANH requires 1 numeric argument")
6077         }
6078         number := argsList.Front().Value.(formulaArg).ToNumber()
6079         if number.Type == ArgError {
6080                 return number
6081         }
6082         return newNumberFormulaArg(math.Tanh(number.Number))
6083 }
6084
6085 // TRUNC function truncates a supplied number to a specified number of decimal
6086 // places. The syntax of the function is:
6087 //
6088 //      TRUNC(number,[number_digits])
6089 func (fn *formulaFuncs) TRUNC(argsList *list.List) formulaArg {
6090         if argsList.Len() == 0 {
6091                 return newErrorFormulaArg(formulaErrorVALUE, "TRUNC requires at least 1 argument")
6092         }
6093         var digits, adjust, rtrim float64
6094         var err error
6095         number := argsList.Front().Value.(formulaArg).ToNumber()
6096         if number.Type == ArgError {
6097                 return number
6098         }
6099         if argsList.Len() > 1 {
6100                 d := argsList.Back().Value.(formulaArg).ToNumber()
6101                 if d.Type == ArgError {
6102                         return d
6103                 }
6104                 digits = d.Number
6105                 digits = math.Floor(digits)
6106         }
6107         adjust = math.Pow(10, digits)
6108         x := int((math.Abs(number.Number) - math.Abs(float64(int(number.Number)))) * adjust)
6109         if x != 0 {
6110                 if rtrim, err = strconv.ParseFloat(strings.TrimRight(strconv.Itoa(x), "0"), 64); err != nil {
6111                         return newErrorFormulaArg(formulaErrorVALUE, err.Error())
6112                 }
6113         }
6114         if (digits > 0) && (rtrim < adjust/10) {
6115                 return newNumberFormulaArg(number.Number)
6116         }
6117         return newNumberFormulaArg(float64(int(number.Number*adjust)) / adjust)
6118 }
6119
6120 // Statistical Functions
6121
6122 // AVEDEV function calculates the average deviation of a supplied set of
6123 // values. The syntax of the function is:
6124 //
6125 //      AVEDEV(number1,[number2],...)
6126 func (fn *formulaFuncs) AVEDEV(argsList *list.List) formulaArg {
6127         if argsList.Len() == 0 {
6128                 return newErrorFormulaArg(formulaErrorVALUE, "AVEDEV requires at least 1 argument")
6129         }
6130         average := fn.AVERAGE(argsList)
6131         if average.Type != ArgNumber {
6132                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
6133         }
6134         result, count := 0.0, 0.0
6135         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
6136                 num := arg.Value.(formulaArg).ToNumber()
6137                 if num.Type != ArgNumber {
6138                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
6139                 }
6140                 result += math.Abs(num.Number - average.Number)
6141                 count++
6142         }
6143         return newNumberFormulaArg(result / count)
6144 }
6145
6146 // AVERAGE function returns the arithmetic mean of a list of supplied numbers.
6147 // The syntax of the function is:
6148 //
6149 //      AVERAGE(number1,[number2],...)
6150 func (fn *formulaFuncs) AVERAGE(argsList *list.List) formulaArg {
6151         var args []formulaArg
6152         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
6153                 args = append(args, arg.Value.(formulaArg))
6154         }
6155         count, sum := fn.countSum(false, args)
6156         if count == 0 {
6157                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
6158         }
6159         return newNumberFormulaArg(sum / count)
6160 }
6161
6162 // AVERAGEA function returns the arithmetic mean of a list of supplied numbers
6163 // with text cell and zero values. The syntax of the function is:
6164 //
6165 //      AVERAGEA(number1,[number2],...)
6166 func (fn *formulaFuncs) AVERAGEA(argsList *list.List) formulaArg {
6167         var args []formulaArg
6168         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
6169                 args = append(args, arg.Value.(formulaArg))
6170         }
6171         count, sum := fn.countSum(true, args)
6172         if count == 0 {
6173                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
6174         }
6175         return newNumberFormulaArg(sum / count)
6176 }
6177
6178 // AVERAGEIF function finds the values in a supplied array that satisfy a
6179 // specified criteria, and returns the average (i.e. the statistical mean) of
6180 // the corresponding values in a second supplied array. The syntax of the
6181 // function is:
6182 //
6183 //      AVERAGEIF(range,criteria,[average_range])
6184 func (fn *formulaFuncs) AVERAGEIF(argsList *list.List) formulaArg {
6185         if argsList.Len() < 2 {
6186                 return newErrorFormulaArg(formulaErrorVALUE, "AVERAGEIF requires at least 2 arguments")
6187         }
6188         var (
6189                 criteria  = formulaCriteriaParser(argsList.Front().Next().Value.(formulaArg))
6190                 rangeMtx  = argsList.Front().Value.(formulaArg).Matrix
6191                 cellRange [][]formulaArg
6192                 args      []formulaArg
6193                 val       float64
6194                 err       error
6195                 ok        bool
6196         )
6197         if argsList.Len() == 3 {
6198                 cellRange = argsList.Back().Value.(formulaArg).Matrix
6199         }
6200         for rowIdx, row := range rangeMtx {
6201                 for colIdx, col := range row {
6202                         fromVal := col.Value()
6203                         if fromVal == "" {
6204                                 continue
6205                         }
6206                         if col.Type == ArgString && criteria.Condition.Type != ArgString {
6207                                 continue
6208                         }
6209                         ok, _ = formulaCriteriaEval(col, criteria)
6210                         if ok {
6211                                 if argsList.Len() == 3 {
6212                                         if len(cellRange) > rowIdx && len(cellRange[rowIdx]) > colIdx {
6213                                                 fromVal = cellRange[rowIdx][colIdx].Value()
6214                                         }
6215                                 }
6216                                 if val, err = strconv.ParseFloat(fromVal, 64); err != nil {
6217                                         continue
6218                                 }
6219                                 args = append(args, newNumberFormulaArg(val))
6220                         }
6221                 }
6222         }
6223         count, sum := fn.countSum(false, args)
6224         if count == 0 {
6225                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
6226         }
6227         return newNumberFormulaArg(sum / count)
6228 }
6229
6230 // AVERAGEIFS function finds entries in one or more arrays, that satisfy a set
6231 // of supplied criteria, and returns the average (i.e. the statistical mean)
6232 // of the corresponding values in a further supplied array. The syntax of the
6233 // function is:
6234 //
6235 //      AVERAGEIFS(average_range,criteria_range1,criteria1,[criteria_range2,criteria2],...)
6236 func (fn *formulaFuncs) AVERAGEIFS(argsList *list.List) formulaArg {
6237         if argsList.Len() < 3 {
6238                 return newErrorFormulaArg(formulaErrorVALUE, "AVERAGEIFS requires at least 3 arguments")
6239         }
6240         if argsList.Len()%2 != 1 {
6241                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
6242         }
6243         var args []formulaArg
6244         sum, sumRange := 0.0, argsList.Front().Value.(formulaArg).Matrix
6245         for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() {
6246                 args = append(args, arg.Value.(formulaArg))
6247         }
6248         count := 0.0
6249         for _, ref := range formulaIfsMatch(args) {
6250                 if num := sumRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber {
6251                         sum += num.Number
6252                         count++
6253                 }
6254         }
6255         if count == 0 {
6256                 return newErrorFormulaArg(formulaErrorDIV, "AVERAGEIF divide by zero")
6257         }
6258         return newNumberFormulaArg(sum / count)
6259 }
6260
6261 // getBetaHelperContFrac continued fractions for the beta function.
6262 func getBetaHelperContFrac(fX, fA, fB float64) float64 {
6263         var a1, b1, a2, b2, fnorm, cfnew, cf, rm float64
6264         a1, b1, b2 = 1, 1, 1-(fA+fB)/(fA+1)*fX
6265         if b2 == 0 {
6266                 a2, fnorm, cf = 0, 1, 1
6267         } else {
6268                 a2, fnorm = 1, 1/b2
6269                 cf = a2 * fnorm
6270         }
6271         cfnew, rm = 1, 1
6272         fMaxIter, fMachEps := 50000.0, 2.22045e-016
6273         bfinished := false
6274         for rm < fMaxIter && !bfinished {
6275                 apl2m := fA + 2*rm
6276                 d2m := rm * (fB - rm) * fX / ((apl2m - 1) * apl2m)
6277                 d2m1 := -(fA + rm) * (fA + fB + rm) * fX / (apl2m * (apl2m + 1))
6278                 a1 = (a2 + d2m*a1) * fnorm
6279                 b1 = (b2 + d2m*b1) * fnorm
6280                 a2 = a1 + d2m1*a2*fnorm
6281                 b2 = b1 + d2m1*b2*fnorm
6282                 if b2 != 0 {
6283                         fnorm = 1 / b2
6284                         cfnew = a2 * fnorm
6285                         bfinished = math.Abs(cf-cfnew) < math.Abs(cf)*fMachEps
6286                 }
6287                 cf = cfnew
6288                 rm++
6289         }
6290         return cf
6291 }
6292
6293 // getLanczosSum uses a variant of the Lanczos sum with a rational function.
6294 func getLanczosSum(fZ float64) float64 {
6295         num := []float64{
6296                 23531376880.41075968857200767445163675473,
6297                 42919803642.64909876895789904700198885093,
6298                 35711959237.35566804944018545154716670596,
6299                 17921034426.03720969991975575445893111267,
6300                 6039542586.35202800506429164430729792107,
6301                 1439720407.311721673663223072794912393972,
6302                 248874557.8620541565114603864132294232163,
6303                 31426415.58540019438061423162831820536287,
6304                 2876370.628935372441225409051620849613599,
6305                 186056.2653952234950402949897160456992822,
6306                 8071.672002365816210638002902272250613822,
6307                 210.8242777515793458725097339207133627117,
6308                 2.506628274631000270164908177133837338626,
6309         }
6310         denom := []float64{
6311                 0,
6312                 39916800,
6313                 120543840,
6314                 150917976,
6315                 105258076,
6316                 45995730,
6317                 13339535,
6318                 2637558,
6319                 357423,
6320                 32670,
6321                 1925,
6322                 66,
6323                 1,
6324         }
6325         var sumNum, sumDenom, zInv float64
6326         if fZ <= 1 {
6327                 sumNum = num[12]
6328                 sumDenom = denom[12]
6329                 for i := 11; i >= 0; i-- {
6330                         sumNum *= fZ
6331                         sumNum += num[i]
6332                         sumDenom *= fZ
6333                         sumDenom += denom[i]
6334                 }
6335         } else {
6336                 zInv = 1 / fZ
6337                 sumNum = num[0]
6338                 sumDenom = denom[0]
6339                 for i := 1; i <= 12; i++ {
6340                         sumNum *= zInv
6341                         sumNum += num[i]
6342                         sumDenom *= zInv
6343                         sumDenom += denom[i]
6344                 }
6345         }
6346         return sumNum / sumDenom
6347 }
6348
6349 // getBeta return beta distribution.
6350 func getBeta(fAlpha, fBeta float64) float64 {
6351         var fA, fB float64
6352         if fAlpha > fBeta {
6353                 fA = fAlpha
6354                 fB = fBeta
6355         } else {
6356                 fA = fBeta
6357                 fB = fAlpha
6358         }
6359         const maxGammaArgument = 171.624376956302
6360         if fA+fB < maxGammaArgument {
6361                 return math.Gamma(fA) / math.Gamma(fA+fB) * math.Gamma(fB)
6362         }
6363         fg := 6.024680040776729583740234375
6364         fgm := fg - 0.5
6365         fLanczos := getLanczosSum(fA)
6366         fLanczos /= getLanczosSum(fA + fB)
6367         fLanczos *= getLanczosSum(fB)
6368         fABgm := fA + fB + fgm
6369         fLanczos *= math.Sqrt((fABgm / (fA + fgm)) / (fB + fgm))
6370         fTempA := fB / (fA + fgm)
6371         fTempB := fA / (fB + fgm)
6372         fResult := math.Exp(-fA*math.Log1p(fTempA) - fB*math.Log1p(fTempB) - fgm)
6373         fResult *= fLanczos
6374         return fResult
6375 }
6376
6377 // getBetaDistPDF is an implementation for the Beta probability density
6378 // function.
6379 func getBetaDistPDF(fX, fA, fB float64) float64 {
6380         if fX <= 0 || fX >= 1 {
6381                 return 0
6382         }
6383         fLogDblMax, fLogDblMin := math.Log(1.79769e+308), math.Log(2.22507e-308)
6384         fLogY := math.Log(0.5 - fX + 0.5)
6385         if fX < 0.1 {
6386                 fLogY = math.Log1p(-fX)
6387         }
6388         fLogX := math.Log(fX)
6389         fAm1LogX := (fA - 1) * fLogX
6390         fBm1LogY := (fB - 1) * fLogY
6391         fLogBeta := getLogBeta(fA, fB)
6392         if fAm1LogX < fLogDblMax && fAm1LogX > fLogDblMin && fBm1LogY < fLogDblMax &&
6393                 fBm1LogY > fLogDblMin && fLogBeta < fLogDblMax && fLogBeta > fLogDblMin &&
6394                 fAm1LogX+fBm1LogY < fLogDblMax && fAm1LogX+fBm1LogY > fLogDblMin {
6395                 return math.Pow(fX, fA-1) * math.Pow(0.5-fX+0.5, fB-1) / getBeta(fA, fB)
6396         }
6397         return math.Exp(fAm1LogX + fBm1LogY - fLogBeta)
6398 }
6399
6400 // getLogBeta return beta with logarithm.
6401 func getLogBeta(fAlpha, fBeta float64) float64 {
6402         var fA, fB float64
6403         if fAlpha > fBeta {
6404                 fA, fB = fAlpha, fBeta
6405         } else {
6406                 fA, fB = fBeta, fAlpha
6407         }
6408         fg := 6.024680040776729583740234375
6409         fgm := fg - 0.5
6410         fLanczos := getLanczosSum(fA)
6411         fLanczos /= getLanczosSum(fA + fB)
6412         fLanczos *= getLanczosSum(fB)
6413         fLogLanczos := math.Log(fLanczos)
6414         fABgm := fA + fB + fgm
6415         fLogLanczos += 0.5 * (math.Log(fABgm) - math.Log(fA+fgm) - math.Log(fB+fgm))
6416         fTempA := fB / (fA + fgm)
6417         fTempB := fA / (fB + fgm)
6418         fResult := -fA*math.Log1p(fTempA) - fB*math.Log1p(fTempB) - fgm
6419         fResult += fLogLanczos
6420         return fResult
6421 }
6422
6423 // getBetaDist is an implementation for the beta distribution function.
6424 func getBetaDist(fXin, fAlpha, fBeta float64) float64 {
6425         if fXin <= 0 {
6426                 return 0
6427         }
6428         if fXin >= 1 {
6429                 return 1
6430         }
6431         if fBeta == 1 {
6432                 return math.Pow(fXin, fAlpha)
6433         }
6434         if fAlpha == 1 {
6435                 return -math.Expm1(fBeta * math.Log1p(-fXin))
6436         }
6437         var fResult float64
6438         fY, flnY := (0.5-fXin)+0.5, math.Log1p(-fXin)
6439         fX, flnX := fXin, math.Log(fXin)
6440         fA, fB := fAlpha, fBeta
6441         bReflect := fXin > fAlpha/(fAlpha+fBeta)
6442         if bReflect {
6443                 fA = fBeta
6444                 fB = fAlpha
6445                 fX = fY
6446                 fY = fXin
6447                 flnX = flnY
6448                 flnY = math.Log(fXin)
6449         }
6450         fResult = getBetaHelperContFrac(fX, fA, fB) / fA
6451         fP, fQ := fA/(fA+fB), fB/(fA+fB)
6452         var fTemp float64
6453         if fA > 1 && fB > 1 && fP < 0.97 && fQ < 0.97 {
6454                 fTemp = getBetaDistPDF(fX, fA, fB) * fX * fY
6455         } else {
6456                 fTemp = math.Exp(fA*flnX + fB*flnY - getLogBeta(fA, fB))
6457         }
6458         fResult *= fTemp
6459         if bReflect {
6460                 fResult = 0.5 - fResult + 0.5
6461         }
6462         return fResult
6463 }
6464
6465 // prepareBETAdotDISTArgs checking and prepare arguments for the formula
6466 // function BETA.DIST.
6467 func (fn *formulaFuncs) prepareBETAdotDISTArgs(argsList *list.List) formulaArg {
6468         if argsList.Len() < 4 {
6469                 return newErrorFormulaArg(formulaErrorVALUE, "BETA.DIST requires at least 4 arguments")
6470         }
6471         if argsList.Len() > 6 {
6472                 return newErrorFormulaArg(formulaErrorVALUE, "BETA.DIST requires at most 6 arguments")
6473         }
6474         x := argsList.Front().Value.(formulaArg).ToNumber()
6475         if x.Type != ArgNumber {
6476                 return x
6477         }
6478         alpha := argsList.Front().Next().Value.(formulaArg).ToNumber()
6479         if alpha.Type != ArgNumber {
6480                 return alpha
6481         }
6482         beta := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
6483         if beta.Type != ArgNumber {
6484                 return beta
6485         }
6486         if alpha.Number <= 0 || beta.Number <= 0 {
6487                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6488         }
6489         cumulative := argsList.Front().Next().Next().Next().Value.(formulaArg).ToBool()
6490         if cumulative.Type != ArgNumber {
6491                 return cumulative
6492         }
6493         a, b := newNumberFormulaArg(0), newNumberFormulaArg(1)
6494         if argsList.Len() > 4 {
6495                 if a = argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber(); a.Type != ArgNumber {
6496                         return a
6497                 }
6498         }
6499         if argsList.Len() == 6 {
6500                 if b = argsList.Back().Value.(formulaArg).ToNumber(); b.Type != ArgNumber {
6501                         return b
6502                 }
6503         }
6504         return newListFormulaArg([]formulaArg{x, alpha, beta, cumulative, a, b})
6505 }
6506
6507 // BETAdotDIST function calculates the cumulative beta distribution function
6508 // or the probability density function of the Beta distribution, for a
6509 // supplied set of parameters. The syntax of the function is:
6510 //
6511 //      BETA.DIST(x,alpha,beta,cumulative,[A],[B])
6512 func (fn *formulaFuncs) BETAdotDIST(argsList *list.List) formulaArg {
6513         args := fn.prepareBETAdotDISTArgs(argsList)
6514         if args.Type != ArgList {
6515                 return args
6516         }
6517         x, alpha, beta, cumulative, a, b := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5]
6518         if x.Number < a.Number || x.Number > b.Number {
6519                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6520         }
6521         if a.Number == b.Number {
6522                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6523         }
6524         scale := b.Number - a.Number
6525         x.Number = (x.Number - a.Number) / scale
6526         if cumulative.Number == 1 {
6527                 return newNumberFormulaArg(getBetaDist(x.Number, alpha.Number, beta.Number))
6528         }
6529         return newNumberFormulaArg(getBetaDistPDF(x.Number, alpha.Number, beta.Number) / scale)
6530 }
6531
6532 // BETADIST function calculates the cumulative beta probability density
6533 // function for a supplied set of parameters. The syntax of the function is:
6534 //
6535 //      BETADIST(x,alpha,beta,[A],[B])
6536 func (fn *formulaFuncs) BETADIST(argsList *list.List) formulaArg {
6537         if argsList.Len() < 3 {
6538                 return newErrorFormulaArg(formulaErrorVALUE, "BETADIST requires at least 3 arguments")
6539         }
6540         if argsList.Len() > 5 {
6541                 return newErrorFormulaArg(formulaErrorVALUE, "BETADIST requires at most 5 arguments")
6542         }
6543         x := argsList.Front().Value.(formulaArg).ToNumber()
6544         if x.Type != ArgNumber {
6545                 return x
6546         }
6547         alpha := argsList.Front().Next().Value.(formulaArg).ToNumber()
6548         if alpha.Type != ArgNumber {
6549                 return alpha
6550         }
6551         beta := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
6552         if beta.Type != ArgNumber {
6553                 return beta
6554         }
6555         if alpha.Number <= 0 || beta.Number <= 0 {
6556                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6557         }
6558         a, b := newNumberFormulaArg(0), newNumberFormulaArg(1)
6559         if argsList.Len() > 3 {
6560                 if a = argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber(); a.Type != ArgNumber {
6561                         return a
6562                 }
6563         }
6564         if argsList.Len() == 5 {
6565                 if b = argsList.Back().Value.(formulaArg).ToNumber(); b.Type != ArgNumber {
6566                         return b
6567                 }
6568         }
6569         if x.Number < a.Number || x.Number > b.Number {
6570                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6571         }
6572         if a.Number == b.Number {
6573                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6574         }
6575         return newNumberFormulaArg(getBetaDist((x.Number-a.Number)/(b.Number-a.Number), alpha.Number, beta.Number))
6576 }
6577
6578 // d1mach returns double precision real machine constants.
6579 func d1mach(i int) float64 {
6580         arr := []float64{
6581                 2.2250738585072014e-308,
6582                 1.7976931348623158e+308,
6583                 1.1102230246251565e-16,
6584                 2.2204460492503131e-16,
6585                 0.301029995663981195,
6586         }
6587         if i > len(arr) {
6588                 return 0
6589         }
6590         return arr[i-1]
6591 }
6592
6593 // chebyshevInit determines the number of terms for the double precision
6594 // orthogonal series "dos" needed to insure the error is no larger
6595 // than "eta". Ordinarily eta will be chosen to be one-tenth machine
6596 // precision.
6597 func chebyshevInit(nos int, eta float64, dos []float64) int {
6598         i, e := 0, 0.0
6599         if nos < 1 {
6600                 return 0
6601         }
6602         for ii := 1; ii <= nos; ii++ {
6603                 i = nos - ii
6604                 e += math.Abs(dos[i])
6605                 if e > eta {
6606                         return i
6607                 }
6608         }
6609         return i
6610 }
6611
6612 // chebyshevEval evaluates the n-term Chebyshev series "a" at "x".
6613 func chebyshevEval(n int, x float64, a []float64) float64 {
6614         if n < 1 || n > 1000 || x < -1.1 || x > 1.1 {
6615                 return math.NaN()
6616         }
6617         twox, b0, b1, b2 := x*2, 0.0, 0.0, 0.0
6618         for i := 1; i <= n; i++ {
6619                 b2 = b1
6620                 b1 = b0
6621                 b0 = twox*b1 - b2 + a[n-i]
6622         }
6623         return (b0 - b2) * 0.5
6624 }
6625
6626 // lgammacor is an implementation for the log(gamma) correction.
6627 func lgammacor(x float64) float64 {
6628         algmcs := []float64{
6629                 0.1666389480451863247205729650822, -0.1384948176067563840732986059135e-4,
6630                 0.9810825646924729426157171547487e-8, -0.1809129475572494194263306266719e-10,
6631                 0.6221098041892605227126015543416e-13, -0.3399615005417721944303330599666e-15,
6632                 0.2683181998482698748957538846666e-17, -0.2868042435334643284144622399999e-19,
6633                 0.3962837061046434803679306666666e-21, -0.6831888753985766870111999999999e-23,
6634                 0.1429227355942498147573333333333e-24, -0.3547598158101070547199999999999e-26,
6635                 0.1025680058010470912000000000000e-27, -0.3401102254316748799999999999999e-29,
6636                 0.1276642195630062933333333333333e-30,
6637         }
6638         nalgm := chebyshevInit(15, d1mach(3), algmcs)
6639         xbig := 1.0 / math.Sqrt(d1mach(3))
6640         xmax := math.Exp(math.Min(math.Log(d1mach(2)/12.0), -math.Log(12.0*d1mach(1))))
6641         if x < 10.0 {
6642                 return math.NaN()
6643         } else if x >= xmax {
6644                 return 4.930380657631324e-32
6645         } else if x < xbig {
6646                 tmp := 10.0 / x
6647                 return chebyshevEval(nalgm, tmp*tmp*2.0-1.0, algmcs) / x
6648         }
6649         return 1.0 / (x * 12.0)
6650 }
6651
6652 // logrelerr compute the relative error logarithm.
6653 func logrelerr(x float64) float64 {
6654         alnrcs := []float64{
6655                 0.10378693562743769800686267719098e+1, -0.13364301504908918098766041553133,
6656                 0.19408249135520563357926199374750e-1, -0.30107551127535777690376537776592e-2,
6657                 0.48694614797154850090456366509137e-3, -0.81054881893175356066809943008622e-4,
6658                 0.13778847799559524782938251496059e-4, -0.23802210894358970251369992914935e-5,
6659                 0.41640416213865183476391859901989e-6, -0.73595828378075994984266837031998e-7,
6660                 0.13117611876241674949152294345011e-7, -0.23546709317742425136696092330175e-8,
6661                 0.42522773276034997775638052962567e-9, -0.77190894134840796826108107493300e-10,
6662                 0.14075746481359069909215356472191e-10, -0.25769072058024680627537078627584e-11,
6663                 0.47342406666294421849154395005938e-12, -0.87249012674742641745301263292675e-13,
6664                 0.16124614902740551465739833119115e-13, -0.29875652015665773006710792416815e-14,
6665                 0.55480701209082887983041321697279e-15, -0.10324619158271569595141333961932e-15,
6666                 0.19250239203049851177878503244868e-16, -0.35955073465265150011189707844266e-17,
6667                 0.67264542537876857892194574226773e-18, -0.12602624168735219252082425637546e-18,
6668                 0.23644884408606210044916158955519e-19, -0.44419377050807936898878389179733e-20,
6669                 0.83546594464034259016241293994666e-21, -0.15731559416479562574899253521066e-21,
6670                 0.29653128740247422686154369706666e-22, -0.55949583481815947292156013226666e-23,
6671                 0.10566354268835681048187284138666e-23, -0.19972483680670204548314999466666e-24,
6672                 0.37782977818839361421049855999999e-25, -0.71531586889081740345038165333333e-26,
6673                 0.13552488463674213646502024533333e-26, -0.25694673048487567430079829333333e-27,
6674                 0.48747756066216949076459519999999e-28, -0.92542112530849715321132373333333e-29,
6675                 0.17578597841760239233269760000000e-29, -0.33410026677731010351377066666666e-30,
6676                 0.63533936180236187354180266666666e-31,
6677         }
6678         nlnrel := chebyshevInit(43, 0.1*d1mach(3), alnrcs)
6679         if x <= -1 {
6680                 return math.NaN()
6681         }
6682         if math.Abs(x) <= 0.375 {
6683                 return x * (1.0 - x*chebyshevEval(nlnrel, x/0.375, alnrcs))
6684         }
6685         return math.Log(x + 1.0)
6686 }
6687
6688 // logBeta is an implementation for the log of the beta distribution
6689 // function.
6690 func logBeta(a, b float64) float64 {
6691         corr, p, q := 0.0, a, a
6692         if b < p {
6693                 p = b
6694         }
6695         if b > q {
6696                 q = b
6697         }
6698         if p < 0 {
6699                 return math.NaN()
6700         }
6701         if p == 0 {
6702                 return math.MaxFloat64
6703         }
6704         if p >= 10.0 {
6705                 corr = lgammacor(p) + lgammacor(q) - lgammacor(p+q)
6706                 f1 := q * logrelerr(-p/(p+q))
6707                 return math.Log(q)*-0.5 + 0.918938533204672741780329736406 + corr + (p-0.5)*math.Log(p/(p+q)) + math.Nextafter(f1, f1)
6708         }
6709         if q >= 10 {
6710                 corr = lgammacor(q) - lgammacor(p+q)
6711                 val, _ := math.Lgamma(p)
6712                 return val + corr + p - p*math.Log(p+q) + (q-0.5)*logrelerr(-p/(p+q))
6713         }
6714         return math.Log(math.Gamma(p) * (math.Gamma(q) / math.Gamma(p+q)))
6715 }
6716
6717 // pbetaRaw is a part of pbeta for the beta distribution.
6718 func pbetaRaw(alnsml, ans, eps, p, pin, q, sml, x, y float64) float64 {
6719         if q > 1.0 {
6720                 xb := p*math.Log(y) + q*math.Log(1.0-y) - logBeta(p, q) - math.Log(q)
6721                 ib := int(math.Max(xb/alnsml, 0.0))
6722                 term := math.Exp(xb - float64(ib)*alnsml)
6723                 c := 1.0 / (1.0 - y)
6724                 p1 := q * c / (p + q - 1.0)
6725                 finsum := 0.0
6726                 n := int(q)
6727                 if q == float64(n) {
6728                         n = n - 1
6729                 }
6730                 for i := 1; i <= n; i++ {
6731                         if p1 <= 1 && term/eps <= finsum {
6732                                 break
6733                         }
6734                         xi := float64(i)
6735                         term = (q - xi + 1.0) * c * term / (p + q - xi)
6736                         if term > 1.0 {
6737                                 ib = ib - 1
6738                                 term = term * sml
6739                         }
6740                         if ib == 0 {
6741                                 finsum = finsum + term
6742                         }
6743                 }
6744                 ans = ans + finsum
6745         }
6746         if y != x || p != pin {
6747                 ans = 1.0 - ans
6748         }
6749         ans = math.Max(math.Min(ans, 1.0), 0.0)
6750         return ans
6751 }
6752
6753 // pbeta returns distribution function of the beta distribution.
6754 func pbeta(x, pin, qin float64) (ans float64) {
6755         eps := d1mach(3)
6756         alneps := math.Log(eps)
6757         sml := d1mach(1)
6758         alnsml := math.Log(sml)
6759         y := x
6760         p := pin
6761         q := qin
6762         if p/(p+q) < x {
6763                 y = 1.0 - y
6764                 p = qin
6765                 q = pin
6766         }
6767         if (p+q)*y/(p+1.0) < eps {
6768                 xb := p*math.Log(math.Max(y, sml)) - math.Log(p) - logBeta(p, q)
6769                 if xb > alnsml && y != 0.0 {
6770                         ans = math.Exp(xb)
6771                 }
6772                 if y != x || p != pin {
6773                         ans = 1.0 - ans
6774                 }
6775         } else {
6776                 ps := q - math.Floor(q)
6777                 if ps == 0.0 {
6778                         ps = 1.0
6779                 }
6780                 xb := p*math.Log(y) - logBeta(ps, p) - math.Log(p)
6781                 if xb >= alnsml {
6782                         ans = math.Exp(xb)
6783                         term := ans * p
6784                         if ps != 1.0 {
6785                                 n := int(math.Max(alneps/math.Log(y), 4.0))
6786                                 for i := 1; i <= n; i++ {
6787                                         xi := float64(i)
6788                                         term = term * (xi - ps) * y / xi
6789                                         ans = ans + term/(p+xi)
6790                                 }
6791                         }
6792                 }
6793                 ans = pbetaRaw(alnsml, ans, eps, p, pin, q, sml, x, y)
6794         }
6795         return ans
6796 }
6797
6798 // betainvProbIterator is a part of betainv for the inverse of the beta
6799 // function.
6800 func betainvProbIterator(alpha1, alpha3, beta1, beta2, beta3, logBeta, maxCumulative, prob1, prob2 float64) float64 {
6801         var i, j, prev, prop4 float64
6802         j = 1
6803         for prob := 0; prob < 1000; prob++ {
6804                 prop3 := pbeta(beta3, alpha1, beta1)
6805                 prop3 = (prop3 - prob1) * math.Exp(logBeta+prob2*math.Log(beta3)+beta2*math.Log(1.0-beta3))
6806                 if prop3*prop4 <= 0 {
6807                         prev = math.Max(math.Abs(j), maxCumulative)
6808                 }
6809                 h := 1.0
6810                 for iteratorCount := 0; iteratorCount < 1000; iteratorCount++ {
6811                         j = h * prop3
6812                         if math.Abs(j) < prev {
6813                                 i = beta3 - j
6814                                 if i >= 0 && i <= 1.0 {
6815                                         if prev <= alpha3 {
6816                                                 return beta3
6817                                         }
6818                                         if math.Abs(prop3) <= alpha3 {
6819                                                 return beta3
6820                                         }
6821                                         if i != 0 && i != 1.0 {
6822                                                 break
6823                                         }
6824                                 }
6825                         }
6826                         h /= 3.0
6827                 }
6828                 if i == beta3 {
6829                         return beta3
6830                 }
6831                 beta3, prop4 = i, prop3
6832         }
6833         return beta3
6834 }
6835
6836 // calcBetainv is an implementation for the quantile of the beta
6837 // distribution.
6838 func calcBetainv(probability, alpha, beta, lower, upper float64) float64 {
6839         minCumulative, maxCumulative := 1.0e-300, 3.0e-308
6840         lowerBound, upperBound := maxCumulative, 1.0-2.22e-16
6841         needSwap := false
6842         var alpha1, alpha2, beta1, beta2, beta3, prob1, x, y float64
6843         if probability <= 0.5 {
6844                 prob1, alpha1, beta1 = probability, alpha, beta
6845         } else {
6846                 prob1, alpha1, beta1, needSwap = 1.0-probability, beta, alpha, true
6847         }
6848         logBetaNum := logBeta(alpha, beta)
6849         prob2 := math.Sqrt(-math.Log(prob1 * prob1))
6850         prob3 := prob2 - (prob2*0.27061+2.3075)/(prob2*(prob2*0.04481+0.99229)+1)
6851         if alpha1 > 1 && beta1 > 1 {
6852                 alpha2, beta2, prob2 = 1/(alpha1+alpha1-1), 1/(beta1+beta1-1), (prob3*prob3-3)/6
6853                 x = 2 / (alpha2 + beta2)
6854                 y = prob3*math.Sqrt(x+prob2)/x - (beta2-alpha2)*(prob2+5/6.0-2/(x*3))
6855                 beta3 = alpha1 / (alpha1 + beta1*math.Exp(y+y))
6856         } else {
6857                 beta2, prob2 = 1/(beta1*9), beta1+beta1
6858                 beta2 = prob2 * math.Pow(1-beta2+prob3*math.Sqrt(beta2), 3)
6859                 if beta2 <= 0 {
6860                         beta3 = 1 - math.Exp((math.Log((1-prob1)*beta1)+logBetaNum)/beta1)
6861                 } else {
6862                         beta2 = (prob2 + alpha1*4 - 2) / beta2
6863                         if beta2 <= 1 {
6864                                 beta3 = math.Exp((logBetaNum + math.Log(alpha1*prob1)) / alpha1)
6865                         } else {
6866                                 beta3 = 1 - 2/(beta2+1)
6867                         }
6868                 }
6869         }
6870         beta2, prob2 = 1-beta1, 1-alpha1
6871         if beta3 < lowerBound {
6872                 beta3 = lowerBound
6873         } else if beta3 > upperBound {
6874                 beta3 = upperBound
6875         }
6876         alpha3 := math.Max(minCumulative, math.Pow(10.0, -13.0-2.5/(alpha1*alpha1)-0.5/(prob1*prob1)))
6877         beta3 = betainvProbIterator(alpha1, alpha3, beta1, beta2, beta3, logBetaNum, maxCumulative, prob1, prob2)
6878         if needSwap {
6879                 beta3 = 1.0 - beta3
6880         }
6881         return (upper-lower)*beta3 + lower
6882 }
6883
6884 // betainv is an implementation of the formula functions BETAINV and
6885 // BETA.INV.
6886 func (fn *formulaFuncs) betainv(name string, argsList *list.List) formulaArg {
6887         if argsList.Len() < 3 {
6888                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 3 arguments", name))
6889         }
6890         if argsList.Len() > 5 {
6891                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at most 5 arguments", name))
6892         }
6893         probability := argsList.Front().Value.(formulaArg).ToNumber()
6894         if probability.Type != ArgNumber {
6895                 return probability
6896         }
6897         if probability.Number <= 0 || probability.Number >= 1 {
6898                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6899         }
6900         alpha := argsList.Front().Next().Value.(formulaArg).ToNumber()
6901         if alpha.Type != ArgNumber {
6902                 return alpha
6903         }
6904         beta := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
6905         if beta.Type != ArgNumber {
6906                 return beta
6907         }
6908         if alpha.Number <= 0 || beta.Number <= 0 {
6909                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6910         }
6911         a, b := newNumberFormulaArg(0), newNumberFormulaArg(1)
6912         if argsList.Len() > 3 {
6913                 if a = argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber(); a.Type != ArgNumber {
6914                         return a
6915                 }
6916         }
6917         if argsList.Len() == 5 {
6918                 if b = argsList.Back().Value.(formulaArg).ToNumber(); b.Type != ArgNumber {
6919                         return b
6920                 }
6921         }
6922         if a.Number == b.Number {
6923                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
6924         }
6925         return newNumberFormulaArg(calcBetainv(probability.Number, alpha.Number, beta.Number, a.Number, b.Number))
6926 }
6927
6928 // BETAINV function uses an iterative procedure to calculate the inverse of
6929 // the cumulative beta probability density function for a supplied
6930 // probability. The syntax of the function is:
6931 //
6932 //      BETAINV(probability,alpha,beta,[A],[B])
6933 func (fn *formulaFuncs) BETAINV(argsList *list.List) formulaArg {
6934         return fn.betainv("BETAINV", argsList)
6935 }
6936
6937 // BETAdotINV function uses an iterative procedure to calculate the inverse of
6938 // the cumulative beta probability density function for a supplied
6939 // probability. The syntax of the function is:
6940 //
6941 //      BETA.INV(probability,alpha,beta,[A],[B])
6942 func (fn *formulaFuncs) BETAdotINV(argsList *list.List) formulaArg {
6943         return fn.betainv("BETA.INV", argsList)
6944 }
6945
6946 // incompleteGamma is an implementation of the incomplete gamma function.
6947 func incompleteGamma(a, x float64) float64 {
6948         max := 32
6949         summer := 0.0
6950         for n := 0; n <= max; n++ {
6951                 divisor := a
6952                 for i := 1; i <= n; i++ {
6953                         divisor *= a + float64(i)
6954                 }
6955                 summer += math.Pow(x, float64(n)) / divisor
6956         }
6957         return math.Pow(x, a) * math.Exp(0-x) * summer
6958 }
6959
6960 // binomCoeff implement binomial coefficient calculation.
6961 func binomCoeff(n, k float64) float64 {
6962         return fact(n) / (fact(k) * fact(n-k))
6963 }
6964
6965 // binomdist implement binomial distribution calculation.
6966 func binomdist(x, n, p float64) float64 {
6967         return binomCoeff(n, x) * math.Pow(p, x) * math.Pow(1-p, n-x)
6968 }
6969
6970 // BINOMdotDIST function returns the Binomial Distribution probability for a
6971 // given number of successes from a specified number of trials. The syntax of
6972 // the function is:
6973 //
6974 //      BINOM.DIST(number_s,trials,probability_s,cumulative)
6975 func (fn *formulaFuncs) BINOMdotDIST(argsList *list.List) formulaArg {
6976         if argsList.Len() != 4 {
6977                 return newErrorFormulaArg(formulaErrorVALUE, "BINOM.DIST requires 4 arguments")
6978         }
6979         return fn.BINOMDIST(argsList)
6980 }
6981
6982 // BINOMDIST function returns the Binomial Distribution probability of a
6983 // specified number of successes out of a specified number of trials. The
6984 // syntax of the function is:
6985 //
6986 //      BINOMDIST(number_s,trials,probability_s,cumulative)
6987 func (fn *formulaFuncs) BINOMDIST(argsList *list.List) formulaArg {
6988         if argsList.Len() != 4 {
6989                 return newErrorFormulaArg(formulaErrorVALUE, "BINOMDIST requires 4 arguments")
6990         }
6991         var s, trials, probability, cumulative formulaArg
6992         if s = argsList.Front().Value.(formulaArg).ToNumber(); s.Type != ArgNumber {
6993                 return s
6994         }
6995         if trials = argsList.Front().Next().Value.(formulaArg).ToNumber(); trials.Type != ArgNumber {
6996                 return trials
6997         }
6998         if s.Number < 0 || s.Number > trials.Number {
6999                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7000         }
7001         if probability = argsList.Back().Prev().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
7002                 return probability
7003         }
7004
7005         if probability.Number < 0 || probability.Number > 1 {
7006                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7007         }
7008         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
7009                 return cumulative
7010         }
7011         if cumulative.Number == 1 {
7012                 bm := 0.0
7013                 for i := 0; i <= int(s.Number); i++ {
7014                         bm += binomdist(float64(i), trials.Number, probability.Number)
7015                 }
7016                 return newNumberFormulaArg(bm)
7017         }
7018         return newNumberFormulaArg(binomdist(s.Number, trials.Number, probability.Number))
7019 }
7020
7021 // BINOMdotDISTdotRANGE function returns the Binomial Distribution probability
7022 // for the number of successes from a specified number of trials falling into
7023 // a specified range.
7024 //
7025 //      BINOM.DIST.RANGE(trials,probability_s,number_s,[number_s2])
7026 func (fn *formulaFuncs) BINOMdotDISTdotRANGE(argsList *list.List) formulaArg {
7027         if argsList.Len() < 3 {
7028                 return newErrorFormulaArg(formulaErrorVALUE, "BINOM.DIST.RANGE requires at least 3 arguments")
7029         }
7030         if argsList.Len() > 4 {
7031                 return newErrorFormulaArg(formulaErrorVALUE, "BINOM.DIST.RANGE requires at most 4 arguments")
7032         }
7033         trials := argsList.Front().Value.(formulaArg).ToNumber()
7034         if trials.Type != ArgNumber {
7035                 return trials
7036         }
7037         probability := argsList.Front().Next().Value.(formulaArg).ToNumber()
7038         if probability.Type != ArgNumber {
7039                 return probability
7040         }
7041         if probability.Number < 0 || probability.Number > 1 {
7042                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7043         }
7044         num1 := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
7045         if num1.Type != ArgNumber {
7046                 return num1
7047         }
7048         if num1.Number < 0 || num1.Number > trials.Number {
7049                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7050         }
7051         num2 := num1
7052         if argsList.Len() > 3 {
7053                 if num2 = argsList.Back().Value.(formulaArg).ToNumber(); num2.Type != ArgNumber {
7054                         return num2
7055                 }
7056         }
7057         if num2.Number < 0 || num2.Number > trials.Number {
7058                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7059         }
7060         sum := 0.0
7061         for i := num1.Number; i <= num2.Number; i++ {
7062                 sum += binomdist(i, trials.Number, probability.Number)
7063         }
7064         return newNumberFormulaArg(sum)
7065 }
7066
7067 // binominv implement inverse of the binomial distribution calculation.
7068 func binominv(n, p, alpha float64) float64 {
7069         q, i, sum, max := 1-p, 0.0, 0.0, 0.0
7070         n = math.Floor(n)
7071         if q > p {
7072                 factor := math.Pow(q, n)
7073                 sum = factor
7074                 for i = 0; i < n && sum < alpha; i++ {
7075                         factor *= (n - i) / (i + 1) * p / q
7076                         sum += factor
7077                 }
7078                 return i
7079         }
7080         factor := math.Pow(p, n)
7081         sum, max = 1-factor, n
7082         for i = 0; i < max && sum >= alpha; i++ {
7083                 factor *= (n - i) / (i + 1) * q / p
7084                 sum -= factor
7085         }
7086         return n - i
7087 }
7088
7089 // BINOMdotINV function returns the inverse of the Cumulative Binomial
7090 // Distribution. The syntax of the function is:
7091 //
7092 //      BINOM.INV(trials,probability_s,alpha)
7093 func (fn *formulaFuncs) BINOMdotINV(argsList *list.List) formulaArg {
7094         if argsList.Len() != 3 {
7095                 return newErrorFormulaArg(formulaErrorVALUE, "BINOM.INV requires 3 numeric arguments")
7096         }
7097         trials := argsList.Front().Value.(formulaArg).ToNumber()
7098         if trials.Type != ArgNumber {
7099                 return trials
7100         }
7101         if trials.Number < 0 {
7102                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7103         }
7104         probability := argsList.Front().Next().Value.(formulaArg).ToNumber()
7105         if probability.Type != ArgNumber {
7106                 return probability
7107         }
7108         if probability.Number <= 0 || probability.Number >= 1 {
7109                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7110         }
7111         alpha := argsList.Back().Value.(formulaArg).ToNumber()
7112         if alpha.Type != ArgNumber {
7113                 return alpha
7114         }
7115         if alpha.Number <= 0 || alpha.Number >= 1 {
7116                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7117         }
7118         return newNumberFormulaArg(binominv(trials.Number, probability.Number, alpha.Number))
7119 }
7120
7121 // CHIDIST function calculates the right-tailed probability of the chi-square
7122 // distribution. The syntax of the function is:
7123 //
7124 //      CHIDIST(x,degrees_freedom)
7125 func (fn *formulaFuncs) CHIDIST(argsList *list.List) formulaArg {
7126         if argsList.Len() != 2 {
7127                 return newErrorFormulaArg(formulaErrorVALUE, "CHIDIST requires 2 numeric arguments")
7128         }
7129         x := argsList.Front().Value.(formulaArg).ToNumber()
7130         if x.Type != ArgNumber {
7131                 return x
7132         }
7133         degrees := argsList.Back().Value.(formulaArg).ToNumber()
7134         if degrees.Type != ArgNumber {
7135                 return degrees
7136         }
7137         logSqrtPi, sqrtPi := math.Log(math.Sqrt(math.Pi)), 1/math.Sqrt(math.Pi)
7138         var e, s, z, c, y float64
7139         a, x1, even := x.Number/2, x.Number, int(degrees.Number)%2 == 0
7140         if degrees.Number > 1 {
7141                 y = math.Exp(-a)
7142         }
7143         args := list.New()
7144         args.PushBack(newNumberFormulaArg(-math.Sqrt(x1)))
7145         o := fn.NORMSDIST(args)
7146         s = 2 * o.Number
7147         if even {
7148                 s = y
7149         }
7150         if degrees.Number > 2 {
7151                 x1 = (degrees.Number - 1) / 2
7152                 z = 0.5
7153                 if even {
7154                         z = 1
7155                 }
7156                 if a > 20 {
7157                         e = logSqrtPi
7158                         if even {
7159                                 e = 0
7160                         }
7161                         c = math.Log(a)
7162                         for z <= x1 {
7163                                 e = math.Log(z) + e
7164                                 s += math.Exp(c*z - a - e)
7165                                 z++
7166                         }
7167                         return newNumberFormulaArg(s)
7168                 }
7169                 e = sqrtPi / math.Sqrt(a)
7170                 if even {
7171                         e = 1
7172                 }
7173                 c = 0
7174                 for z <= x1 {
7175                         e = e * (a / z)
7176                         c = c + e
7177                         z++
7178                 }
7179                 return newNumberFormulaArg(c*y + s)
7180         }
7181         return newNumberFormulaArg(s)
7182 }
7183
7184 // CHIINV function calculates the inverse of the right-tailed probability of
7185 // the Chi-Square Distribution. The syntax of the function is:
7186 //
7187 //      CHIINV(probability,deg_freedom)
7188 func (fn *formulaFuncs) CHIINV(argsList *list.List) formulaArg {
7189         if argsList.Len() != 2 {
7190                 return newErrorFormulaArg(formulaErrorVALUE, "CHIINV requires 2 numeric arguments")
7191         }
7192         probability := argsList.Front().Value.(formulaArg).ToNumber()
7193         if probability.Type != ArgNumber {
7194                 return probability
7195         }
7196         if probability.Number <= 0 || probability.Number > 1 {
7197                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7198         }
7199         deg := argsList.Back().Value.(formulaArg).ToNumber()
7200         if deg.Type != ArgNumber {
7201                 return deg
7202         }
7203         if deg.Number < 1 {
7204                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7205         }
7206         return newNumberFormulaArg(gammainv(1-probability.Number, 0.5*deg.Number, 2.0))
7207 }
7208
7209 // CHITEST function uses the chi-square test to calculate the probability that
7210 // the differences between two supplied data sets (of observed and expected
7211 // frequencies), are likely to be simply due to sampling error, or if they are
7212 // likely to be real. The syntax of the function is:
7213 //
7214 //      CHITEST(actual_range,expected_range)
7215 func (fn *formulaFuncs) CHITEST(argsList *list.List) formulaArg {
7216         if argsList.Len() != 2 {
7217                 return newErrorFormulaArg(formulaErrorVALUE, "CHITEST requires 2 arguments")
7218         }
7219         actual, expected := argsList.Front().Value.(formulaArg), argsList.Back().Value.(formulaArg)
7220         actualList, expectedList := actual.ToList(), expected.ToList()
7221         rows := len(actual.Matrix)
7222         if rows == 0 {
7223                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
7224         }
7225         columns := len(actualList) / rows
7226         if len(actualList) != len(expectedList) || len(actualList) == 1 {
7227                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
7228         }
7229         var result float64
7230         var degrees int
7231         for i := 0; i < len(actualList); i++ {
7232                 a, e := actualList[i].ToNumber(), expectedList[i].ToNumber()
7233                 if a.Type == ArgNumber && e.Type == ArgNumber {
7234                         if e.Number == 0 {
7235                                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
7236                         }
7237                         if e.Number < 0 {
7238                                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7239                         }
7240                         result += (a.Number - e.Number) * (a.Number - e.Number) / e.Number
7241                 }
7242         }
7243         if rows == 1 {
7244                 degrees = columns - 1
7245         } else if columns == 1 {
7246                 degrees = rows - 1
7247         } else {
7248                 degrees = (columns - 1) * (rows - 1)
7249         }
7250         args := list.New()
7251         args.PushBack(newNumberFormulaArg(result))
7252         args.PushBack(newNumberFormulaArg(float64(degrees)))
7253         return fn.CHIDIST(args)
7254 }
7255
7256 // getGammaSeries calculates a power-series of the gamma function.
7257 func getGammaSeries(fA, fX float64) float64 {
7258         var (
7259                 fHalfMachEps = 2.22045e-016 / 2
7260                 fDenomfactor = fA
7261                 fSummand     = 1 / fA
7262                 fSum         = fSummand
7263                 nCount       = 1
7264         )
7265         for fSummand/fSum > fHalfMachEps && nCount <= 10000 {
7266                 fDenomfactor = fDenomfactor + 1
7267                 fSummand = fSummand * fX / fDenomfactor
7268                 fSum = fSum + fSummand
7269                 nCount = nCount + 1
7270         }
7271         return fSum
7272 }
7273
7274 // getGammaContFraction returns continued fraction with odd items of the gamma
7275 // function.
7276 func getGammaContFraction(fA, fX float64) float64 {
7277         var (
7278                 fBigInv      = 2.22045e-016
7279                 fHalfMachEps = fBigInv / 2
7280                 fBig         = 1 / fBigInv
7281                 fCount       = 0.0
7282                 fY           = 1 - fA
7283                 fDenom       = fX + 2 - fA
7284                 fPkm1        = fX + 1
7285                 fPkm2        = 1.0
7286                 fQkm1        = fDenom * fX
7287                 fQkm2        = fX
7288                 fApprox      = fPkm1 / fQkm1
7289                 bFinished    = false
7290         )
7291         for !bFinished && fCount < 10000 {
7292                 fCount = fCount + 1
7293                 fY = fY + 1
7294                 fDenom = fDenom + 2
7295                 var (
7296                         fNum = fY * fCount
7297                         f1   = fPkm1 * fDenom
7298                         f2   = fPkm2 * fNum
7299                         fPk  = math.Nextafter(f1, f1) - math.Nextafter(f2, f2)
7300                         f3   = fQkm1 * fDenom
7301                         f4   = fQkm2 * fNum
7302                         fQk  = math.Nextafter(f3, f3) - math.Nextafter(f4, f4)
7303                 )
7304                 if fQk != 0 {
7305                         fR := fPk / fQk
7306                         bFinished = math.Abs((fApprox-fR)/fR) <= fHalfMachEps
7307                         fApprox = fR
7308                 }
7309                 fPkm2, fPkm1, fQkm2, fQkm1 = fPkm1, fPk, fQkm1, fQk
7310                 if math.Abs(fPk) > fBig {
7311                         // reduce a fraction does not change the value
7312                         fPkm2 = fPkm2 * fBigInv
7313                         fPkm1 = fPkm1 * fBigInv
7314                         fQkm2 = fQkm2 * fBigInv
7315                         fQkm1 = fQkm1 * fBigInv
7316                 }
7317         }
7318         return fApprox
7319 }
7320
7321 // getLogGammaHelper is a part of implementation of the function getLogGamma.
7322 func getLogGammaHelper(fZ float64) float64 {
7323         _fg := 6.024680040776729583740234375
7324         zgHelp := fZ + _fg - 0.5
7325         return math.Log(getLanczosSum(fZ)) + (fZ-0.5)*math.Log(zgHelp) - zgHelp
7326 }
7327
7328 // getGammaHelper is a part of implementation of the function getLogGamma.
7329 func getGammaHelper(fZ float64) float64 {
7330         var (
7331                 gamma  = getLanczosSum(fZ)
7332                 fg     = 6.024680040776729583740234375
7333                 zgHelp = fZ + fg - 0.5
7334                 // avoid intermediate overflow
7335                 halfpower = math.Pow(zgHelp, fZ/2-0.25)
7336         )
7337         gamma *= halfpower
7338         gamma /= math.Exp(zgHelp)
7339         gamma *= halfpower
7340         if fZ <= 20 && fZ == math.Floor(fZ) {
7341                 gamma = math.Round(gamma)
7342         }
7343         return gamma
7344 }
7345
7346 // getLogGamma calculates the natural logarithm of the gamma function.
7347 func getLogGamma(fZ float64) float64 {
7348         fMaxGammaArgument := 171.624376956302
7349         if fZ >= fMaxGammaArgument {
7350                 return getLogGammaHelper(fZ)
7351         }
7352         if fZ >= 1.0 {
7353                 return math.Log(getGammaHelper(fZ))
7354         }
7355         if fZ >= 0.5 {
7356                 return math.Log(getGammaHelper(fZ+1) / fZ)
7357         }
7358         return getLogGammaHelper(fZ+2) - math.Log(fZ+1) - math.Log(fZ)
7359 }
7360
7361 // getLowRegIGamma returns lower regularized incomplete gamma function.
7362 func getLowRegIGamma(fA, fX float64) float64 {
7363         lnFactor := fA*math.Log(fX) - fX - getLogGamma(fA)
7364         factor := math.Exp(lnFactor)
7365         if fX > fA+1 {
7366                 return 1 - factor*getGammaContFraction(fA, fX)
7367         }
7368         return factor * getGammaSeries(fA, fX)
7369 }
7370
7371 // getChiSqDistCDF returns left tail for the Chi-Square distribution.
7372 func getChiSqDistCDF(fX, fDF float64) float64 {
7373         if fX <= 0 {
7374                 return 0
7375         }
7376         return getLowRegIGamma(fDF/2, fX/2)
7377 }
7378
7379 // getChiSqDistPDF calculates the probability density function for the
7380 // Chi-Square distribution.
7381 func getChiSqDistPDF(fX, fDF float64) float64 {
7382         if fDF*fX > 1391000 {
7383                 return math.Exp((0.5*fDF-1)*math.Log(fX*0.5) - 0.5*fX - math.Log(2) - getLogGamma(0.5*fDF))
7384         }
7385         var fCount, fValue float64
7386         if math.Mod(fDF, 2) < 0.5 {
7387                 fValue = 0.5
7388                 fCount = 2
7389         } else {
7390                 fValue = 1 / math.Sqrt(fX*2*math.Pi)
7391                 fCount = 1
7392         }
7393         for fCount < fDF {
7394                 fValue *= fX / fCount
7395                 fCount += 2
7396         }
7397         if fX >= 1425 {
7398                 fValue = math.Exp(math.Log(fValue) - fX/2)
7399         } else {
7400                 fValue *= math.Exp(-fX / 2)
7401         }
7402         return fValue
7403 }
7404
7405 // CHISQdotDIST function calculates the Probability Density Function or the
7406 // Cumulative Distribution Function for the Chi-Square Distribution. The
7407 // syntax of the function is:
7408 //
7409 //      CHISQ.DIST(x,degrees_freedom,cumulative)
7410 func (fn *formulaFuncs) CHISQdotDIST(argsList *list.List) formulaArg {
7411         if argsList.Len() != 3 {
7412                 return newErrorFormulaArg(formulaErrorVALUE, "CHISQ.DIST requires 3 arguments")
7413         }
7414         var x, degrees, cumulative formulaArg
7415         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
7416                 return x
7417         }
7418         if degrees = argsList.Front().Next().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
7419                 return degrees
7420         }
7421         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
7422                 return cumulative
7423         }
7424         if x.Number < 0 {
7425                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7426         }
7427         maxDeg := math.Pow10(10)
7428         if degrees.Number < 1 || degrees.Number >= maxDeg {
7429                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7430         }
7431         if cumulative.Number == 1 {
7432                 return newNumberFormulaArg(getChiSqDistCDF(x.Number, degrees.Number))
7433         }
7434         return newNumberFormulaArg(getChiSqDistPDF(x.Number, degrees.Number))
7435 }
7436
7437 // CHISQdotDISTdotRT function calculates the right-tailed probability of the
7438 // Chi-Square Distribution. The syntax of the function is:
7439 //
7440 //      CHISQ.DIST.RT(x,degrees_freedom)
7441 func (fn *formulaFuncs) CHISQdotDISTdotRT(argsList *list.List) formulaArg {
7442         if argsList.Len() != 2 {
7443                 return newErrorFormulaArg(formulaErrorVALUE, "CHISQ.DIST.RT requires 2 numeric arguments")
7444         }
7445         return fn.CHIDIST(argsList)
7446 }
7447
7448 // CHISQdotTEST function performs the chi-square test on two supplied data sets
7449 // (of observed and expected frequencies), and returns the probability that
7450 // the differences between the sets are simply due to sampling error. The
7451 // syntax of the function is:
7452 //
7453 //      CHISQ.TEST(actual_range,expected_range)
7454 func (fn *formulaFuncs) CHISQdotTEST(argsList *list.List) formulaArg {
7455         if argsList.Len() != 2 {
7456                 return newErrorFormulaArg(formulaErrorVALUE, "CHISQ.TEST requires 2 arguments")
7457         }
7458         return fn.CHITEST(argsList)
7459 }
7460
7461 // hasChangeOfSign check if the sign has been changed.
7462 func hasChangeOfSign(u, w float64) bool {
7463         return (u < 0 && w > 0) || (u > 0 && w < 0)
7464 }
7465
7466 // calcInverseIterator directly maps the required parameters for inverse
7467 // distribution functions.
7468 type calcInverseIterator struct {
7469         name        string
7470         fp, fDF, nT float64
7471 }
7472
7473 // callBack implements the callback function for the inverse iterator.
7474 func (iterator *calcInverseIterator) callBack(x float64) float64 {
7475         if iterator.name == "CHISQ.INV" {
7476                 return iterator.fp - getChiSqDistCDF(x, iterator.fDF)
7477         }
7478         return iterator.fp - getTDist(x, iterator.fDF, iterator.nT)
7479 }
7480
7481 // inverseQuadraticInterpolation inverse quadratic interpolation with
7482 // additional brackets.
7483 func inverseQuadraticInterpolation(iterator calcInverseIterator, fAx, fAy, fBx, fBy float64) float64 {
7484         fYEps := 1.0e-307
7485         fXEps := 2.22045e-016
7486         fPx, fPy, fQx, fQy, fRx, fRy := fAx, fAy, fBx, fBy, fAx, fAy
7487         fSx := 0.5 * (fAx + fBx)
7488         bHasToInterpolate := true
7489         nCount := 0
7490         for nCount < 500 && math.Abs(fRy) > fYEps && (fBx-fAx) > math.Max(math.Abs(fAx), math.Abs(fBx))*fXEps {
7491                 if bHasToInterpolate {
7492                         if fPy != fQy && fQy != fRy && fRy != fPy {
7493                                 fSx = fPx*fRy*fQy/(fRy-fPy)/(fQy-fPy) + fRx*fQy*fPy/(fQy-fRy)/(fPy-fRy) +
7494                                         fQx*fPy*fRy/(fPy-fQy)/(fRy-fQy)
7495                                 bHasToInterpolate = (fAx < fSx) && (fSx < fBx)
7496                         } else {
7497                                 bHasToInterpolate = false
7498                         }
7499                 }
7500                 if !bHasToInterpolate {
7501                         fSx = 0.5 * (fAx + fBx)
7502                         fQx, fQy = fBx, fBy
7503                         bHasToInterpolate = true
7504                 }
7505                 fPx, fQx, fRx, fPy, fQy = fQx, fRx, fSx, fQy, fRy
7506                 fRy = iterator.callBack(fSx)
7507                 if hasChangeOfSign(fAy, fRy) {
7508                         fBx, fBy = fRx, fRy
7509                 } else {
7510                         fAx, fAy = fRx, fRy
7511                 }
7512                 bHasToInterpolate = bHasToInterpolate && (math.Abs(fRy)*2 <= math.Abs(fQy))
7513                 nCount++
7514         }
7515         return fRx
7516 }
7517
7518 // calcIterateInverse function calculates the iteration for inverse
7519 // distributions.
7520 func calcIterateInverse(iterator calcInverseIterator, fAx, fBx float64) float64 {
7521         fAy, fBy := iterator.callBack(fAx), iterator.callBack(fBx)
7522         var fTemp float64
7523         var nCount int
7524         for nCount = 0; nCount < 1000 && !hasChangeOfSign(fAy, fBy); nCount++ {
7525                 if math.Abs(fAy) <= math.Abs(fBy) {
7526                         fTemp = fAx
7527                         fAx += 2 * (fAx - fBx)
7528                         if fAx < 0 {
7529                                 fAx = 0
7530                         }
7531                         fBx = fTemp
7532                         fBy = fAy
7533                         fAy = iterator.callBack(fAx)
7534                 } else {
7535                         fTemp = fBx
7536                         fBx += 2 * (fBx - fAx)
7537                         fAx = fTemp
7538                         fAy = fBy
7539                         fBy = iterator.callBack(fBx)
7540                 }
7541         }
7542         if fAy == 0 || fBy == 0 {
7543                 return 0
7544         }
7545         return inverseQuadraticInterpolation(iterator, fAx, fAy, fBx, fBy)
7546 }
7547
7548 // CHISQdotINV function calculates the inverse of the left-tailed probability
7549 // of the Chi-Square Distribution. The syntax of the function is:
7550 //
7551 //      CHISQ.INV(probability,degrees_freedom)
7552 func (fn *formulaFuncs) CHISQdotINV(argsList *list.List) formulaArg {
7553         if argsList.Len() != 2 {
7554                 return newErrorFormulaArg(formulaErrorVALUE, "CHISQ.INV requires 2 numeric arguments")
7555         }
7556         var probability, degrees formulaArg
7557         if probability = argsList.Front().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
7558                 return probability
7559         }
7560         if degrees = argsList.Back().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
7561                 return degrees
7562         }
7563         if probability.Number < 0 || probability.Number >= 1 {
7564                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7565         }
7566         if degrees.Number < 1 || degrees.Number > math.Pow10(10) {
7567                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7568         }
7569         return newNumberFormulaArg(calcIterateInverse(calcInverseIterator{
7570                 name: "CHISQ.INV",
7571                 fp:   probability.Number,
7572                 fDF:  degrees.Number,
7573         }, degrees.Number/2, degrees.Number))
7574 }
7575
7576 // CHISQdotINVdotRT function calculates the inverse of the right-tailed
7577 // probability of the Chi-Square Distribution. The syntax of the function is:
7578 //
7579 //      CHISQ.INV.RT(probability,degrees_freedom)
7580 func (fn *formulaFuncs) CHISQdotINVdotRT(argsList *list.List) formulaArg {
7581         if argsList.Len() != 2 {
7582                 return newErrorFormulaArg(formulaErrorVALUE, "CHISQ.INV.RT requires 2 numeric arguments")
7583         }
7584         return fn.CHIINV(argsList)
7585 }
7586
7587 // confidence is an implementation of the formula functions CONFIDENCE and
7588 // CONFIDENCE.NORM.
7589 func (fn *formulaFuncs) confidence(name string, argsList *list.List) formulaArg {
7590         if argsList.Len() != 3 {
7591                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 numeric arguments", name))
7592         }
7593         alpha := argsList.Front().Value.(formulaArg).ToNumber()
7594         if alpha.Type != ArgNumber {
7595                 return alpha
7596         }
7597         if alpha.Number <= 0 || alpha.Number >= 1 {
7598                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7599         }
7600         stdDev := argsList.Front().Next().Value.(formulaArg).ToNumber()
7601         if stdDev.Type != ArgNumber {
7602                 return stdDev
7603         }
7604         if stdDev.Number <= 0 {
7605                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7606         }
7607         size := argsList.Back().Value.(formulaArg).ToNumber()
7608         if size.Type != ArgNumber {
7609                 return size
7610         }
7611         if size.Number < 1 {
7612                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7613         }
7614         args := list.New()
7615         args.Init()
7616         args.PushBack(newNumberFormulaArg(alpha.Number / 2))
7617         args.PushBack(newNumberFormulaArg(0))
7618         args.PushBack(newNumberFormulaArg(1))
7619         return newNumberFormulaArg(-fn.NORMINV(args).Number * (stdDev.Number / math.Sqrt(size.Number)))
7620 }
7621
7622 // CONFIDENCE function uses a Normal Distribution to calculate a confidence
7623 // value that can be used to construct the Confidence Interval for a
7624 // population mean, for a supplied probability and sample size. It is assumed
7625 // that the standard deviation of the population is known. The syntax of the
7626 // function is:
7627 //
7628 //      CONFIDENCE(alpha,standard_dev,size)
7629 func (fn *formulaFuncs) CONFIDENCE(argsList *list.List) formulaArg {
7630         return fn.confidence("CONFIDENCE", argsList)
7631 }
7632
7633 // CONFIDENCEdotNORM function uses a Normal Distribution to calculate a
7634 // confidence value that can be used to construct the confidence interval for
7635 // a population mean, for a supplied probability and sample size. It is
7636 // assumed that the standard deviation of the population is known. The syntax
7637 // of the function is:
7638 //
7639 //      CONFIDENCE.NORM(alpha,standard_dev,size)
7640 func (fn *formulaFuncs) CONFIDENCEdotNORM(argsList *list.List) formulaArg {
7641         return fn.confidence("CONFIDENCE.NORM", argsList)
7642 }
7643
7644 // CONFIDENCEdotT function uses a Student's T-Distribution to calculate a
7645 // confidence value that can be used to construct the confidence interval for
7646 // a population mean, for a supplied probablity and supplied sample size. It
7647 // is assumed that the standard deviation of the population is known. The
7648 // syntax of the function is:
7649 //
7650 //      CONFIDENCE.T(alpha,standard_dev,size)
7651 func (fn *formulaFuncs) CONFIDENCEdotT(argsList *list.List) formulaArg {
7652         if argsList.Len() != 3 {
7653                 return newErrorFormulaArg(formulaErrorVALUE, "CONFIDENCE.T requires 3 arguments")
7654         }
7655         var alpha, standardDev, size formulaArg
7656         if alpha = argsList.Front().Value.(formulaArg).ToNumber(); alpha.Type != ArgNumber {
7657                 return alpha
7658         }
7659         if standardDev = argsList.Front().Next().Value.(formulaArg).ToNumber(); standardDev.Type != ArgNumber {
7660                 return standardDev
7661         }
7662         if size = argsList.Back().Value.(formulaArg).ToNumber(); size.Type != ArgNumber {
7663                 return size
7664         }
7665         if alpha.Number <= 0 || alpha.Number >= 1 || standardDev.Number <= 0 || size.Number < 1 {
7666                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
7667         }
7668         if size.Number == 1 {
7669                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
7670         }
7671         return newNumberFormulaArg(standardDev.Number * calcIterateInverse(calcInverseIterator{
7672                 name: "CONFIDENCE.T",
7673                 fp:   alpha.Number,
7674                 fDF:  size.Number - 1,
7675                 nT:   2,
7676         }, size.Number/2, size.Number) / math.Sqrt(size.Number))
7677 }
7678
7679 // covar is an implementation of the formula functions COVAR, COVARIANCE.P and
7680 // COVARIANCE.S.
7681 func (fn *formulaFuncs) covar(name string, argsList *list.List) formulaArg {
7682         if argsList.Len() != 2 {
7683                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 arguments", name))
7684         }
7685         array1 := argsList.Front().Value.(formulaArg)
7686         array2 := argsList.Back().Value.(formulaArg)
7687         left, right := array1.ToList(), array2.ToList()
7688         n := len(left)
7689         if n != len(right) {
7690                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
7691         }
7692         l1, l2 := list.New(), list.New()
7693         l1.PushBack(array1)
7694         l2.PushBack(array2)
7695         result, skip := 0.0, 0
7696         mean1, mean2 := fn.AVERAGE(l1), fn.AVERAGE(l2)
7697         for i := 0; i < n; i++ {
7698                 arg1 := left[i].ToNumber()
7699                 arg2 := right[i].ToNumber()
7700                 if arg1.Type == ArgError || arg2.Type == ArgError {
7701                         skip++
7702                         continue
7703                 }
7704                 result += (arg1.Number - mean1.Number) * (arg2.Number - mean2.Number)
7705         }
7706         if name == "COVARIANCE.S" {
7707                 return newNumberFormulaArg(result / float64(n-skip-1))
7708         }
7709         return newNumberFormulaArg(result / float64(n-skip))
7710 }
7711
7712 // COVAR function calculates the covariance of two supplied sets of values. The
7713 // syntax of the function is:
7714 //
7715 //      COVAR(array1,array2)
7716 func (fn *formulaFuncs) COVAR(argsList *list.List) formulaArg {
7717         return fn.covar("COVAR", argsList)
7718 }
7719
7720 // COVARIANCEdotP function calculates the population covariance of two supplied
7721 // sets of values. The syntax of the function is:
7722 //
7723 //      COVARIANCE.P(array1,array2)
7724 func (fn *formulaFuncs) COVARIANCEdotP(argsList *list.List) formulaArg {
7725         return fn.covar("COVARIANCE.P", argsList)
7726 }
7727
7728 // COVARIANCEdotS function calculates the sample covariance of two supplied
7729 // sets of values. The syntax of the function is:
7730 //
7731 //      COVARIANCE.S(array1,array2)
7732 func (fn *formulaFuncs) COVARIANCEdotS(argsList *list.List) formulaArg {
7733         return fn.covar("COVARIANCE.S", argsList)
7734 }
7735
7736 // calcStringCountSum is part of the implementation countSum.
7737 func calcStringCountSum(countText bool, count, sum float64, num, arg formulaArg) (float64, float64) {
7738         if countText && num.Type == ArgError && arg.String != "" {
7739                 count++
7740         }
7741         if num.Type == ArgNumber {
7742                 sum += num.Number
7743                 count++
7744         }
7745         return count, sum
7746 }
7747
7748 // countSum get count and sum for a formula arguments array.
7749 func (fn *formulaFuncs) countSum(countText bool, args []formulaArg) (count, sum float64) {
7750         for _, arg := range args {
7751                 switch arg.Type {
7752                 case ArgNumber:
7753                         if countText || !arg.Boolean {
7754                                 sum += arg.Number
7755                                 count++
7756                         }
7757                 case ArgString:
7758                         if !countText && (arg.Value() == "TRUE" || arg.Value() == "FALSE") {
7759                                 continue
7760                         } else if countText && (arg.Value() == "TRUE" || arg.Value() == "FALSE") {
7761                                 num := arg.ToBool()
7762                                 if num.Type == ArgNumber {
7763                                         count++
7764                                         sum += num.Number
7765                                         continue
7766                                 }
7767                         }
7768                         num := arg.ToNumber()
7769                         count, sum = calcStringCountSum(countText, count, sum, num, arg)
7770                 case ArgList, ArgMatrix:
7771                         cnt, summary := fn.countSum(countText, arg.ToList())
7772                         sum += summary
7773                         count += cnt
7774                 }
7775         }
7776         return
7777 }
7778
7779 // CORREL function calculates the Pearson Product-Moment Correlation
7780 // Coefficient for two sets of values. The syntax of the function is:
7781 //
7782 //      CORREL(array1,array2)
7783 func (fn *formulaFuncs) CORREL(argsList *list.List) formulaArg {
7784         if argsList.Len() != 2 {
7785                 return newErrorFormulaArg(formulaErrorVALUE, "CORREL requires 2 arguments")
7786         }
7787         array1 := argsList.Front().Value.(formulaArg)
7788         array2 := argsList.Back().Value.(formulaArg)
7789         left, right := array1.ToList(), array2.ToList()
7790         n := len(left)
7791         if n != len(right) {
7792                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
7793         }
7794         l1, l2, l3 := list.New(), list.New(), list.New()
7795         for i := 0; i < n; i++ {
7796                 if lhs, rhs := left[i].ToNumber(), right[i].ToNumber(); lhs.Number != 0 && rhs.Number != 0 {
7797                         l1.PushBack(lhs)
7798                         l2.PushBack(rhs)
7799                 }
7800         }
7801         stdev1, stdev2 := fn.STDEV(l1), fn.STDEV(l2)
7802         if stdev1.Number == 0 || stdev2.Number == 0 {
7803                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
7804         }
7805         mean1, mean2, skip := fn.AVERAGE(l1), fn.AVERAGE(l2), 0
7806         for i := 0; i < n; i++ {
7807                 lhs, rhs := left[i].ToNumber(), right[i].ToNumber()
7808                 if lhs.Number == 0 || rhs.Number == 0 {
7809                         skip++
7810                         continue
7811                 }
7812                 l3.PushBack(newNumberFormulaArg((lhs.Number - mean1.Number) * (rhs.Number - mean2.Number)))
7813         }
7814         return newNumberFormulaArg(fn.SUM(l3).Number / float64(n-skip-1) / stdev1.Number / stdev2.Number)
7815 }
7816
7817 // COUNT function returns the count of numeric values in a supplied set of
7818 // cells or values. This count includes both numbers and dates. The syntax of
7819 // the function is:
7820 //
7821 //      COUNT(value1,[value2],...)
7822 func (fn *formulaFuncs) COUNT(argsList *list.List) formulaArg {
7823         var count int
7824         for token := argsList.Front(); token != nil; token = token.Next() {
7825                 arg := token.Value.(formulaArg)
7826                 switch arg.Type {
7827                 case ArgString:
7828                         if num := arg.ToNumber(); num.Type == ArgNumber {
7829                                 count++
7830                         }
7831                 case ArgNumber:
7832                         count++
7833                 case ArgMatrix:
7834                         for _, row := range arg.Matrix {
7835                                 for _, cell := range row {
7836                                         if cell.Type == ArgNumber {
7837                                                 count++
7838                                         }
7839                                 }
7840                         }
7841                 }
7842         }
7843         return newNumberFormulaArg(float64(count))
7844 }
7845
7846 // COUNTA function returns the number of non-blanks within a supplied set of
7847 // cells or values. The syntax of the function is:
7848 //
7849 //      COUNTA(value1,[value2],...)
7850 func (fn *formulaFuncs) COUNTA(argsList *list.List) formulaArg {
7851         var count int
7852         for token := argsList.Front(); token != nil; token = token.Next() {
7853                 arg := token.Value.(formulaArg)
7854                 switch arg.Type {
7855                 case ArgString:
7856                         if arg.String != "" {
7857                                 count++
7858                         }
7859                 case ArgNumber:
7860                         count++
7861                 case ArgMatrix:
7862                         for _, row := range arg.ToList() {
7863                                 switch row.Type {
7864                                 case ArgString:
7865                                         if row.String != "" {
7866                                                 count++
7867                                         }
7868                                 case ArgNumber:
7869                                         count++
7870                                 }
7871                         }
7872                 }
7873         }
7874         return newNumberFormulaArg(float64(count))
7875 }
7876
7877 // COUNTBLANK function returns the number of blank cells in a supplied range.
7878 // The syntax of the function is:
7879 //
7880 //      COUNTBLANK(range)
7881 func (fn *formulaFuncs) COUNTBLANK(argsList *list.List) formulaArg {
7882         if argsList.Len() != 1 {
7883                 return newErrorFormulaArg(formulaErrorVALUE, "COUNTBLANK requires 1 argument")
7884         }
7885         var count float64
7886         for _, cell := range argsList.Front().Value.(formulaArg).ToList() {
7887                 if cell.Type == ArgEmpty {
7888                         count++
7889                 }
7890         }
7891         return newNumberFormulaArg(count)
7892 }
7893
7894 // COUNTIF function returns the number of cells within a supplied range, that
7895 // satisfy a given criteria. The syntax of the function is:
7896 //
7897 //      COUNTIF(range,criteria)
7898 func (fn *formulaFuncs) COUNTIF(argsList *list.List) formulaArg {
7899         if argsList.Len() != 2 {
7900                 return newErrorFormulaArg(formulaErrorVALUE, "COUNTIF requires 2 arguments")
7901         }
7902         var (
7903                 criteria = formulaCriteriaParser(argsList.Front().Next().Value.(formulaArg))
7904                 count    float64
7905         )
7906         for _, cell := range argsList.Front().Value.(formulaArg).ToList() {
7907                 if cell.Type == ArgString && criteria.Condition.Type != ArgString {
7908                         continue
7909                 }
7910                 if ok, _ := formulaCriteriaEval(cell, criteria); ok {
7911                         count++
7912                 }
7913         }
7914         return newNumberFormulaArg(count)
7915 }
7916
7917 // formulaIfsMatch function returns cells reference array which match criteria.
7918 func formulaIfsMatch(args []formulaArg) (cellRefs []cellRef) {
7919         for i := 0; i < len(args)-1; i += 2 {
7920                 var match []cellRef
7921                 matrix, criteria := args[i].Matrix, formulaCriteriaParser(args[i+1])
7922                 if i == 0 {
7923                         for rowIdx, row := range matrix {
7924                                 for colIdx, col := range row {
7925                                         if ok, _ := formulaCriteriaEval(col, criteria); ok {
7926                                                 match = append(match, cellRef{Col: colIdx, Row: rowIdx})
7927                                         }
7928                                 }
7929                         }
7930                 } else {
7931                         match = []cellRef{}
7932                         for _, ref := range cellRefs {
7933                                 value := matrix[ref.Row][ref.Col]
7934                                 if ok, _ := formulaCriteriaEval(value, criteria); ok {
7935                                         match = append(match, ref)
7936                                 }
7937                         }
7938                 }
7939                 cellRefs = match[:]
7940         }
7941         return
7942 }
7943
7944 // COUNTIFS function returns the number of rows within a table, that satisfy a
7945 // set of given criteria. The syntax of the function is:
7946 //
7947 //      COUNTIFS(criteria_range1,criteria1,[criteria_range2,criteria2],...)
7948 func (fn *formulaFuncs) COUNTIFS(argsList *list.List) formulaArg {
7949         if argsList.Len() < 2 {
7950                 return newErrorFormulaArg(formulaErrorVALUE, "COUNTIFS requires at least 2 arguments")
7951         }
7952         if argsList.Len()%2 != 0 {
7953                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
7954         }
7955         var args []formulaArg
7956         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
7957                 args = append(args, arg.Value.(formulaArg))
7958         }
7959         return newNumberFormulaArg(float64(len(formulaIfsMatch(args))))
7960 }
7961
7962 // CRITBINOM function returns the inverse of the Cumulative Binomial
7963 // Distribution. I.e. for a specific number of independent trials, the
7964 // function returns the smallest value (number of successes) for which the
7965 // cumulative binomial distribution is greater than or equal to a specified
7966 // value. The syntax of the function is:
7967 //
7968 //      CRITBINOM(trials,probability_s,alpha)
7969 func (fn *formulaFuncs) CRITBINOM(argsList *list.List) formulaArg {
7970         if argsList.Len() != 3 {
7971                 return newErrorFormulaArg(formulaErrorVALUE, "CRITBINOM requires 3 numeric arguments")
7972         }
7973         return fn.BINOMdotINV(argsList)
7974 }
7975
7976 // DEVSQ function calculates the sum of the squared deviations from the sample
7977 // mean. The syntax of the function is:
7978 //
7979 //      DEVSQ(number1,[number2],...)
7980 func (fn *formulaFuncs) DEVSQ(argsList *list.List) formulaArg {
7981         if argsList.Len() < 1 {
7982                 return newErrorFormulaArg(formulaErrorVALUE, "DEVSQ requires at least 1 numeric argument")
7983         }
7984         avg, count, result := fn.AVERAGE(argsList), -1, 0.0
7985         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
7986                 for _, cell := range arg.Value.(formulaArg).ToList() {
7987                         if cell.Type != ArgNumber {
7988                                 continue
7989                         }
7990                         count++
7991                         if count == 0 {
7992                                 result = math.Pow(cell.Number-avg.Number, 2)
7993                                 continue
7994                         }
7995                         result += math.Pow(cell.Number-avg.Number, 2)
7996                 }
7997         }
7998         if count == -1 {
7999                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
8000         }
8001         return newNumberFormulaArg(result)
8002 }
8003
8004 // FISHER function calculates the Fisher Transformation for a supplied value.
8005 // The syntax of the function is:
8006 //
8007 //      FISHER(x)
8008 func (fn *formulaFuncs) FISHER(argsList *list.List) formulaArg {
8009         if argsList.Len() != 1 {
8010                 return newErrorFormulaArg(formulaErrorVALUE, "FISHER requires 1 numeric argument")
8011         }
8012         token := argsList.Front().Value.(formulaArg)
8013         switch token.Type {
8014         case ArgString:
8015                 arg := token.ToNumber()
8016                 if arg.Type == ArgNumber {
8017                         if arg.Number <= -1 || arg.Number >= 1 {
8018                                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
8019                         }
8020                         return newNumberFormulaArg(0.5 * math.Log((1+arg.Number)/(1-arg.Number)))
8021                 }
8022         case ArgNumber:
8023                 if token.Number <= -1 || token.Number >= 1 {
8024                         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
8025                 }
8026                 return newNumberFormulaArg(0.5 * math.Log((1+token.Number)/(1-token.Number)))
8027         }
8028         return newErrorFormulaArg(formulaErrorVALUE, "FISHER requires 1 numeric argument")
8029 }
8030
8031 // FISHERINV function calculates the inverse of the Fisher Transformation and
8032 // returns a value between -1 and +1. The syntax of the function is:
8033 //
8034 //      FISHERINV(y)
8035 func (fn *formulaFuncs) FISHERINV(argsList *list.List) formulaArg {
8036         if argsList.Len() != 1 {
8037                 return newErrorFormulaArg(formulaErrorVALUE, "FISHERINV requires 1 numeric argument")
8038         }
8039         token := argsList.Front().Value.(formulaArg)
8040         switch token.Type {
8041         case ArgString:
8042                 arg := token.ToNumber()
8043                 if arg.Type == ArgNumber {
8044                         return newNumberFormulaArg((math.Exp(2*arg.Number) - 1) / (math.Exp(2*arg.Number) + 1))
8045                 }
8046         case ArgNumber:
8047                 return newNumberFormulaArg((math.Exp(2*token.Number) - 1) / (math.Exp(2*token.Number) + 1))
8048         }
8049         return newErrorFormulaArg(formulaErrorVALUE, "FISHERINV requires 1 numeric argument")
8050 }
8051
8052 // FORECAST function predicts a future point on a linear trend line fitted to a
8053 // supplied set of x- and y- values. The syntax of the function is:
8054 //
8055 //      FORECAST(x,known_y's,known_x's)
8056 func (fn *formulaFuncs) FORECAST(argsList *list.List) formulaArg {
8057         return fn.pearsonProduct("FORECAST", 3, argsList)
8058 }
8059
8060 // FORECASTdotLINEAR function predicts a future point on a linear trend line
8061 // fitted to a supplied set of x- and y- values. The syntax of the function is:
8062 //
8063 //      FORECAST.LINEAR(x,known_y's,known_x's)
8064 func (fn *formulaFuncs) FORECASTdotLINEAR(argsList *list.List) formulaArg {
8065         return fn.pearsonProduct("FORECAST.LINEAR", 3, argsList)
8066 }
8067
8068 // maritxToSortedColumnList convert matrix formula arguments to a ascending
8069 // order list by column.
8070 func maritxToSortedColumnList(arg formulaArg) formulaArg {
8071         mtx, cols := []formulaArg{}, len(arg.Matrix[0])
8072         for colIdx := 0; colIdx < cols; colIdx++ {
8073                 for _, row := range arg.Matrix {
8074                         cell := row[colIdx]
8075                         if cell.Type == ArgError {
8076                                 return cell
8077                         }
8078                         if cell.Type == ArgNumber {
8079                                 mtx = append(mtx, cell)
8080                         }
8081                 }
8082         }
8083         argsList := newListFormulaArg(mtx)
8084         sort.Slice(argsList.List, func(i, j int) bool {
8085                 return argsList.List[i].Number < argsList.List[j].Number
8086         })
8087         return argsList
8088 }
8089
8090 // FREQUENCY function to count how many children fall into different age
8091 // ranges. The syntax of the function is:
8092 //
8093 //      FREQUENCY(data_array,bins_array)
8094 func (fn *formulaFuncs) FREQUENCY(argsList *list.List) formulaArg {
8095         if argsList.Len() != 2 {
8096                 return newErrorFormulaArg(formulaErrorVALUE, "FREQUENCY requires 2 arguments")
8097         }
8098         data, bins := argsList.Front().Value.(formulaArg), argsList.Back().Value.(formulaArg)
8099         if len(data.Matrix) == 0 {
8100                 data.Matrix = [][]formulaArg{{data}}
8101         }
8102         if len(bins.Matrix) == 0 {
8103                 bins.Matrix = [][]formulaArg{{bins}}
8104         }
8105         var (
8106                 dataMtx, binsMtx formulaArg
8107                 c                [][]formulaArg
8108                 i, j             int
8109         )
8110         if dataMtx = maritxToSortedColumnList(data); dataMtx.Type != ArgList {
8111                 return dataMtx
8112         }
8113         if binsMtx = maritxToSortedColumnList(bins); binsMtx.Type != ArgList {
8114                 return binsMtx
8115         }
8116         for row := 0; row < len(binsMtx.List)+1; row++ {
8117                 rows := []formulaArg{}
8118                 for col := 0; col < 1; col++ {
8119                         rows = append(rows, newNumberFormulaArg(0))
8120                 }
8121                 c = append(c, rows)
8122         }
8123         for j = 0; j < len(binsMtx.List); j++ {
8124                 n := 0.0
8125                 for i < len(dataMtx.List) && dataMtx.List[i].Number <= binsMtx.List[j].Number {
8126                         n++
8127                         i++
8128                 }
8129                 c[j] = []formulaArg{newNumberFormulaArg(n)}
8130         }
8131         c[j] = []formulaArg{newNumberFormulaArg(float64(len(dataMtx.List) - i))}
8132         if len(c) > 2 {
8133                 c[1], c[2] = c[2], c[1]
8134         }
8135         return newMatrixFormulaArg(c)
8136 }
8137
8138 // GAMMA function returns the value of the Gamma Function, Î“(n), for a
8139 // specified number, n. The syntax of the function is:
8140 //
8141 //      GAMMA(number)
8142 func (fn *formulaFuncs) GAMMA(argsList *list.List) formulaArg {
8143         if argsList.Len() != 1 {
8144                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMA requires 1 numeric argument")
8145         }
8146         number := argsList.Front().Value.(formulaArg).ToNumber()
8147         if number.Type != ArgNumber {
8148                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMA requires 1 numeric argument")
8149         }
8150         if number.Number <= 0 {
8151                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
8152         }
8153         return newNumberFormulaArg(math.Gamma(number.Number))
8154 }
8155
8156 // GAMMAdotDIST function returns the Gamma Distribution, which is frequently
8157 // used to provide probabilities for values that may have a skewed
8158 // distribution, such as queuing analysis.
8159 //
8160 //      GAMMA.DIST(x,alpha,beta,cumulative)
8161 func (fn *formulaFuncs) GAMMAdotDIST(argsList *list.List) formulaArg {
8162         if argsList.Len() != 4 {
8163                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMA.DIST requires 4 arguments")
8164         }
8165         return fn.GAMMADIST(argsList)
8166 }
8167
8168 // GAMMADIST function returns the Gamma Distribution, which is frequently used
8169 // to provide probabilities for values that may have a skewed distribution,
8170 // such as queuing analysis.
8171 //
8172 //      GAMMADIST(x,alpha,beta,cumulative)
8173 func (fn *formulaFuncs) GAMMADIST(argsList *list.List) formulaArg {
8174         if argsList.Len() != 4 {
8175                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMADIST requires 4 arguments")
8176         }
8177         var x, alpha, beta, cumulative formulaArg
8178         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
8179                 return x
8180         }
8181         if x.Number < 0 {
8182                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
8183         }
8184         if alpha = argsList.Front().Next().Value.(formulaArg).ToNumber(); alpha.Type != ArgNumber {
8185                 return alpha
8186         }
8187         if beta = argsList.Back().Prev().Value.(formulaArg).ToNumber(); beta.Type != ArgNumber {
8188                 return beta
8189         }
8190         if alpha.Number <= 0 || beta.Number <= 0 {
8191                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
8192         }
8193         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
8194                 return cumulative
8195         }
8196         if cumulative.Number == 1 {
8197                 return newNumberFormulaArg(incompleteGamma(alpha.Number, x.Number/beta.Number) / math.Gamma(alpha.Number))
8198         }
8199         return newNumberFormulaArg((1 / (math.Pow(beta.Number, alpha.Number) * math.Gamma(alpha.Number))) * math.Pow(x.Number, alpha.Number-1) * math.Exp(0-(x.Number/beta.Number)))
8200 }
8201
8202 // gammainv returns the inverse of the Gamma distribution for the specified
8203 // value.
8204 func gammainv(probability, alpha, beta float64) float64 {
8205         xLo, xHi := 0.0, alpha*beta*5
8206         dx, x, xNew, result := 1024.0, 1.0, 1.0, 0.0
8207         for i := 0; math.Abs(dx) > 8.88e-016 && i <= 256; i++ {
8208                 result = incompleteGamma(alpha, x/beta) / math.Gamma(alpha)
8209                 e := result - probability
8210                 if e == 0 {
8211                         dx = 0
8212                 } else if e < 0 {
8213                         xLo = x
8214                 } else {
8215                         xHi = x
8216                 }
8217                 pdf := (1 / (math.Pow(beta, alpha) * math.Gamma(alpha))) * math.Pow(x, alpha-1) * math.Exp(0-(x/beta))
8218                 if pdf != 0 {
8219                         dx = e / pdf
8220                         xNew = x - dx
8221                 }
8222                 if xNew < xLo || xNew > xHi || pdf == 0 {
8223                         xNew = (xLo + xHi) / 2
8224                         dx = xNew - x
8225                 }
8226                 x = xNew
8227         }
8228         return x
8229 }
8230
8231 // GAMMAdotINV function returns the inverse of the Gamma Cumulative
8232 // Distribution. The syntax of the function is:
8233 //
8234 //      GAMMA.INV(probability,alpha,beta)
8235 func (fn *formulaFuncs) GAMMAdotINV(argsList *list.List) formulaArg {
8236         if argsList.Len() != 3 {
8237                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMA.INV requires 3 arguments")
8238         }
8239         return fn.GAMMAINV(argsList)
8240 }
8241
8242 // GAMMAINV function returns the inverse of the Gamma Cumulative Distribution.
8243 // The syntax of the function is:
8244 //
8245 //      GAMMAINV(probability,alpha,beta)
8246 func (fn *formulaFuncs) GAMMAINV(argsList *list.List) formulaArg {
8247         if argsList.Len() != 3 {
8248                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMAINV requires 3 arguments")
8249         }
8250         var probability, alpha, beta formulaArg
8251         if probability = argsList.Front().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
8252                 return probability
8253         }
8254         if probability.Number < 0 || probability.Number >= 1 {
8255                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
8256         }
8257         if alpha = argsList.Front().Next().Value.(formulaArg).ToNumber(); alpha.Type != ArgNumber {
8258                 return alpha
8259         }
8260         if beta = argsList.Back().Value.(formulaArg).ToNumber(); beta.Type != ArgNumber {
8261                 return beta
8262         }
8263         if alpha.Number <= 0 || beta.Number <= 0 {
8264                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
8265         }
8266         return newNumberFormulaArg(gammainv(probability.Number, alpha.Number, beta.Number))
8267 }
8268
8269 // GAMMALN function returns the natural logarithm of the Gamma Function, Î“
8270 // (n). The syntax of the function is:
8271 //
8272 //      GAMMALN(x)
8273 func (fn *formulaFuncs) GAMMALN(argsList *list.List) formulaArg {
8274         if argsList.Len() != 1 {
8275                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMALN requires 1 numeric argument")
8276         }
8277         x := argsList.Front().Value.(formulaArg).ToNumber()
8278         if x.Type != ArgNumber {
8279                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMALN requires 1 numeric argument")
8280         }
8281         if x.Number <= 0 {
8282                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
8283         }
8284         return newNumberFormulaArg(math.Log(math.Gamma(x.Number)))
8285 }
8286
8287 // GAMMALNdotPRECISE function returns the natural logarithm of the Gamma
8288 // Function, Î“(n). The syntax of the function is:
8289 //
8290 //      GAMMALN.PRECISE(x)
8291 func (fn *formulaFuncs) GAMMALNdotPRECISE(argsList *list.List) formulaArg {
8292         if argsList.Len() != 1 {
8293                 return newErrorFormulaArg(formulaErrorVALUE, "GAMMALN.PRECISE requires 1 numeric argument")
8294         }
8295         x := argsList.Front().Value.(formulaArg).ToNumber()
8296         if x.Type != ArgNumber {
8297                 return x
8298         }
8299         if x.Number <= 0 {
8300                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
8301         }
8302         return newNumberFormulaArg(getLogGamma(x.Number))
8303 }
8304
8305 // GAUSS function returns the probability that a member of a standard normal
8306 // population will fall between the mean and a specified number of standard
8307 // deviations from the mean. The syntax of the function is:
8308 //
8309 //      GAUSS(z)
8310 func (fn *formulaFuncs) GAUSS(argsList *list.List) formulaArg {
8311         if argsList.Len() != 1 {
8312                 return newErrorFormulaArg(formulaErrorVALUE, "GAUSS requires 1 numeric argument")
8313         }
8314         args := list.New().Init()
8315         args.PushBack(argsList.Front().Value.(formulaArg))
8316         args.PushBack(formulaArg{Type: ArgNumber, Number: 0})
8317         args.PushBack(formulaArg{Type: ArgNumber, Number: 1})
8318         args.PushBack(newBoolFormulaArg(true))
8319         normdist := fn.NORMDIST(args)
8320         if normdist.Type != ArgNumber {
8321                 return normdist
8322         }
8323         return newNumberFormulaArg(normdist.Number - 0.5)
8324 }
8325
8326 // GEOMEAN function calculates the geometric mean of a supplied set of values.
8327 // The syntax of the function is:
8328 //
8329 //      GEOMEAN(number1,[number2],...)
8330 func (fn *formulaFuncs) GEOMEAN(argsList *list.List) formulaArg {
8331         if argsList.Len() < 1 {
8332                 return newErrorFormulaArg(formulaErrorVALUE, "GEOMEAN requires at least 1 numeric argument")
8333         }
8334         product := fn.PRODUCT(argsList)
8335         if product.Type != ArgNumber {
8336                 return product
8337         }
8338         count := fn.COUNT(argsList)
8339         min := fn.MIN(argsList)
8340         if product.Number > 0 && min.Number > 0 {
8341                 return newNumberFormulaArg(math.Pow(product.Number, 1/count.Number))
8342         }
8343         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
8344 }
8345
8346 // getNewMatrix create matrix by given columns and rows.
8347 func getNewMatrix(c, r int) (matrix [][]float64) {
8348         for i := 0; i < c; i++ {
8349                 for j := 0; j < r; j++ {
8350                         for x := len(matrix); x <= i; x++ {
8351                                 matrix = append(matrix, []float64{})
8352                         }
8353                         for y := len(matrix[i]); y <= j; y++ {
8354                                 matrix[i] = append(matrix[i], 0)
8355                         }
8356                         matrix[i][j] = 0
8357                 }
8358         }
8359         return
8360 }
8361
8362 // approxSub subtract two values, if signs are identical and the values are
8363 // equal, will be returns 0 instead of calculating the subtraction.
8364 func approxSub(a, b float64) float64 {
8365         if ((a < 0 && b < 0) || (a > 0 && b > 0)) && math.Abs(a-b) < 2.22045e-016 {
8366                 return 0
8367         }
8368         return a - b
8369 }
8370
8371 // matrixClone return a copy of all elements of the original matrix.
8372 func matrixClone(matrix [][]float64) (cloneMatrix [][]float64) {
8373         for i := 0; i < len(matrix); i++ {
8374                 for j := 0; j < len(matrix[i]); j++ {
8375                         for x := len(cloneMatrix); x <= i; x++ {
8376                                 cloneMatrix = append(cloneMatrix, []float64{})
8377                         }
8378                         for k := len(cloneMatrix[i]); k <= j; k++ {
8379                                 cloneMatrix[i] = append(cloneMatrix[i], 0)
8380                         }
8381                         cloneMatrix[i][j] = matrix[i][j]
8382                 }
8383         }
8384         return
8385 }
8386
8387 // trendGrowthMatrixInfo defined matrix checking result.
8388 type trendGrowthMatrixInfo struct {
8389         trendType, nCX, nCY, nRX, nRY, M, N int
8390         mtxX, mtxY                          [][]float64
8391 }
8392
8393 // prepareTrendGrowthMtxX is a part of implementation of the trend growth prepare.
8394 func prepareTrendGrowthMtxX(mtxX [][]float64) [][]float64 {
8395         var mtx [][]float64
8396         for i := 0; i < len(mtxX); i++ {
8397                 for j := 0; j < len(mtxX[i]); j++ {
8398                         if mtxX[i][j] == 0 {
8399                                 return nil
8400                         }
8401                         for x := len(mtx); x <= j; x++ {
8402                                 mtx = append(mtx, []float64{})
8403                         }
8404                         for y := len(mtx[j]); y <= i; y++ {
8405                                 mtx[j] = append(mtx[j], 0)
8406                         }
8407                         mtx[j][i] = mtxX[i][j]
8408                 }
8409         }
8410         return mtx
8411 }
8412
8413 // prepareTrendGrowthMtxY is a part of implementation of the trend growth prepare.
8414 func prepareTrendGrowthMtxY(bLOG bool, mtxY [][]float64) [][]float64 {
8415         var mtx [][]float64
8416         for i := 0; i < len(mtxY); i++ {
8417                 for j := 0; j < len(mtxY[i]); j++ {
8418                         if mtxY[i][j] == 0 {
8419                                 return nil
8420                         }
8421                         for x := len(mtx); x <= j; x++ {
8422                                 mtx = append(mtx, []float64{})
8423                         }
8424                         for y := len(mtx[j]); y <= i; y++ {
8425                                 mtx[j] = append(mtx[j], 0)
8426                         }
8427                         mtx[j][i] = mtxY[i][j]
8428                 }
8429         }
8430         if bLOG {
8431                 var pNewY [][]float64
8432                 for i := 0; i < len(mtxY); i++ {
8433                         for j := 0; j < len(mtxY[i]); j++ {
8434                                 fVal := mtxY[i][j]
8435                                 if fVal <= 0 {
8436                                         return nil
8437                                 }
8438                                 for x := len(pNewY); x <= j; x++ {
8439                                         pNewY = append(pNewY, []float64{})
8440                                 }
8441                                 for y := len(pNewY[j]); y <= i; y++ {
8442                                         pNewY[j] = append(pNewY[j], 0)
8443                                 }
8444                                 pNewY[j][i] = math.Log(fVal)
8445                         }
8446                 }
8447                 mtx = pNewY
8448         }
8449         return mtx
8450 }
8451
8452 // prepareTrendGrowth check and return the result.
8453 func prepareTrendGrowth(bLOG bool, mtxX, mtxY [][]float64) (*trendGrowthMatrixInfo, formulaArg) {
8454         var nCX, nRX, M, N, trendType int
8455         nRY, nCY := len(mtxY), len(mtxY[0])
8456         cntY := nCY * nRY
8457         newY := prepareTrendGrowthMtxY(bLOG, mtxY)
8458         if newY == nil {
8459                 return nil, newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
8460         }
8461         var newX [][]float64
8462         if len(mtxX) != 0 {
8463                 nRX, nCX = len(mtxX), len(mtxX[0])
8464                 if newX = prepareTrendGrowthMtxX(mtxX); newX == nil {
8465                         return nil, newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
8466                 }
8467                 if nCX == nCY && nRX == nRY {
8468                         trendType, M, N = 1, 1, cntY // simple regression
8469                 } else if nCY != 1 && nRY != 1 {
8470                         return nil, newErrorFormulaArg(formulaErrorREF, formulaErrorREF)
8471                 } else if nCY == 1 {
8472                         if nRX != nRY {
8473                                 return nil, newErrorFormulaArg(formulaErrorREF, formulaErrorREF)
8474                         }
8475                         trendType, M, N = 2, nCX, nRY
8476                 } else if nCX != nCY {
8477                         return nil, newErrorFormulaArg(formulaErrorREF, formulaErrorREF)
8478                 } else {
8479                         trendType, M, N = 3, nRX, nCY
8480                 }
8481         } else {
8482                 newX = getNewMatrix(nCY, nRY)
8483                 nCX, nRX = nCY, nRY
8484                 num := 1.0
8485                 for i := 0; i < nRY; i++ {
8486                         for j := 0; j < nCY; j++ {
8487                                 newX[j][i] = num
8488                                 num++
8489                         }
8490                 }
8491                 trendType, M, N = 1, 1, cntY
8492         }
8493         return &trendGrowthMatrixInfo{
8494                 trendType: trendType,
8495                 nCX:       nCX,
8496                 nCY:       nCY,
8497                 nRX:       nRX,
8498                 nRY:       nRY,
8499                 M:         M,
8500                 N:         N,
8501                 mtxX:      newX,
8502                 mtxY:      newY,
8503         }, newEmptyFormulaArg()
8504 }
8505
8506 // calcPosition calculate position for matrix by given index.
8507 func calcPosition(mtx [][]float64, idx int) (row, col int) {
8508         rowSize := len(mtx[0])
8509         col = idx
8510         if rowSize > 1 {
8511                 col = idx / rowSize
8512         }
8513         row = idx - col*rowSize
8514         return
8515 }
8516
8517 // getDouble returns float64 data type value in the matrix by given index.
8518 func getDouble(mtx [][]float64, idx int) float64 {
8519         row, col := calcPosition(mtx, idx)
8520         return mtx[col][row]
8521 }
8522
8523 // putDouble set a float64 data type value in the matrix by given index.
8524 func putDouble(mtx [][]float64, idx int, val float64) {
8525         row, col := calcPosition(mtx, idx)
8526         mtx[col][row] = val
8527 }
8528
8529 // calcMeanOverAll returns mean of the given matrix by over all element.
8530 func calcMeanOverAll(mtx [][]float64, n int) float64 {
8531         var sum float64
8532         for i := 0; i < len(mtx); i++ {
8533                 for j := 0; j < len(mtx[i]); j++ {
8534                         sum += mtx[i][j]
8535                 }
8536         }
8537         return sum / float64(n)
8538 }
8539
8540 // calcSumProduct returns uses the matrices as vectors of length M over all
8541 // element.
8542 func calcSumProduct(mtxA, mtxB [][]float64, m int) float64 {
8543         sum := 0.0
8544         for i := 0; i < m; i++ {
8545                 sum += getDouble(mtxA, i) * getDouble(mtxB, i)
8546         }
8547         return sum
8548 }
8549
8550 // calcColumnMeans calculates means of the columns of matrix.
8551 func calcColumnMeans(mtxX, mtxRes [][]float64, c, r int) {
8552         for i := 0; i < c; i++ {
8553                 var sum float64
8554                 for k := 0; k < r; k++ {
8555                         sum += mtxX[i][k]
8556                 }
8557                 putDouble(mtxRes, i, sum/float64(r))
8558         }
8559 }
8560
8561 // calcColumnsDelta calculates subtract of the columns of matrix.
8562 func calcColumnsDelta(mtx, columnMeans [][]float64, c, r int) {
8563         for i := 0; i < c; i++ {
8564                 for k := 0; k < r; k++ {
8565                         mtx[i][k] = approxSub(mtx[i][k], getDouble(columnMeans, i))
8566                 }
8567         }
8568 }
8569
8570 // calcSign returns sign by given value, no mathematical signum, but used to
8571 // switch between adding and subtracting.
8572 func calcSign(val float64) float64 {
8573         if val > 0 {
8574                 return 1
8575         }
8576         return -1
8577 }
8578
8579 // calcColsMaximumNorm is a special version for use within QR
8580 // decomposition. Maximum norm of column index c starting in row index r;
8581 // matrix A has count n rows.
8582 func calcColsMaximumNorm(mtxA [][]float64, c, r, n int) float64 {
8583         var norm float64
8584         for row := r; row < n; row++ {
8585                 if norm < math.Abs(mtxA[c][row]) {
8586                         norm = math.Abs(mtxA[c][row])
8587                 }
8588         }
8589         return norm
8590 }
8591
8592 // calcFastMult returns multiply n x m matrix A with m x l matrix B to n x l matrix R.
8593 func calcFastMult(mtxA, mtxB, mtxR [][]float64, n, m, l int) {
8594         var sum float64
8595         for row := 0; row < n; row++ {
8596                 for col := 0; col < l; col++ {
8597                         sum = 0.0
8598                         for k := 0; k < m; k++ {
8599                                 sum += mtxA[k][row] * mtxB[col][k]
8600                         }
8601                         mtxR[col][row] = sum
8602                 }
8603         }
8604 }
8605
8606 // calcRowsEuclideanNorm is a special version for use within QR
8607 // decomposition. Euclidean norm of column index c starting in row index r;
8608 // matrix a has count n rows.
8609 func calcRowsEuclideanNorm(mtxA [][]float64, c, r, n int) float64 {
8610         var norm float64
8611         for row := r; row < n; row++ {
8612                 norm += mtxA[c][row] * mtxA[c][row]
8613         }
8614         return math.Sqrt(norm)
8615 }
8616
8617 // calcRowsSumProduct is a special version for use within QR decomposition.
8618 // <A(a);B(b)> starting in row index r;
8619 // a and b are indices of columns, matrices A and B have count n rows.
8620 func calcRowsSumProduct(mtxA [][]float64, a int, mtxB [][]float64, b, r, n int) float64 {
8621         var result float64
8622         for row := r; row < n; row++ {
8623                 result += mtxA[a][row] * mtxB[b][row]
8624         }
8625         return result
8626 }
8627
8628 // calcSolveWithUpperRightTriangle solve for X in R*X=S using back substitution.
8629 func calcSolveWithUpperRightTriangle(mtxA [][]float64, vecR []float64, mtxS [][]float64, k int, bIsTransposed bool) {
8630         var row int
8631         for rowp1 := k; rowp1 > 0; rowp1-- {
8632                 row = rowp1 - 1
8633                 sum := getDouble(mtxS, row)
8634                 for col := rowp1; col < k; col++ {
8635                         if bIsTransposed {
8636                                 sum -= mtxA[row][col] * getDouble(mtxS, col)
8637                         } else {
8638                                 sum -= mtxA[col][row] * getDouble(mtxS, col)
8639                         }
8640                 }
8641                 putDouble(mtxS, row, sum/vecR[row])
8642         }
8643 }
8644
8645 // calcRowQRDecomposition calculates a QR decomposition with Householder
8646 // reflection.
8647 func calcRowQRDecomposition(mtxA [][]float64, vecR []float64, k, n int) bool {
8648         for col := 0; col < k; col++ {
8649                 scale := calcColsMaximumNorm(mtxA, col, col, n)
8650                 if scale == 0 {
8651                         return false
8652                 }
8653                 for row := col; row < n; row++ {
8654                         mtxA[col][row] = mtxA[col][row] / scale
8655                 }
8656                 euclid := calcRowsEuclideanNorm(mtxA, col, col, n)
8657                 factor := 1.0 / euclid / (euclid + math.Abs(mtxA[col][col]))
8658                 signum := calcSign(mtxA[col][col])
8659                 mtxA[col][col] = mtxA[col][col] + signum*euclid
8660                 vecR[col] = -signum * scale * euclid
8661                 // apply Householder transformation to A
8662                 for c := col + 1; c < k; c++ {
8663                         sum := calcRowsSumProduct(mtxA, col, mtxA, c, col, n)
8664                         for row := col; row < n; row++ {
8665                                 mtxA[c][row] = mtxA[c][row] - sum*factor*mtxA[col][row]
8666                         }
8667                 }
8668         }
8669         return true
8670 }
8671
8672 // calcApplyColsHouseholderTransformation transposed matrices A and Y.
8673 func calcApplyColsHouseholderTransformation(mtxA [][]float64, r int, mtxY [][]float64, n int) {
8674         denominator := calcColsSumProduct(mtxA, r, mtxA, r, r, n)
8675         numerator := calcColsSumProduct(mtxA, r, mtxY, 0, r, n)
8676         factor := 2 * (numerator / denominator)
8677         for col := r; col < n; col++ {
8678                 putDouble(mtxY, col, getDouble(mtxY, col)-factor*mtxA[col][r])
8679         }
8680 }
8681
8682 // calcRowMeans calculates means of the rows of matrix.
8683 func calcRowMeans(mtxX, mtxRes [][]float64, c, r int) {
8684         for k := 0; k < r; k++ {
8685                 var fSum float64
8686                 for i := 0; i < c; i++ {
8687                         fSum += mtxX[i][k]
8688                 }
8689                 mtxRes[k][0] = fSum / float64(c)
8690         }
8691 }
8692
8693 // calcRowsDelta calculates subtract of the rows of matrix.
8694 func calcRowsDelta(mtx, rowMeans [][]float64, c, r int) {
8695         for k := 0; k < r; k++ {
8696                 for i := 0; i < c; i++ {
8697                         mtx[i][k] = approxSub(mtx[i][k], rowMeans[k][0])
8698                 }
8699         }
8700 }
8701
8702 // calcColumnMaximumNorm returns maximum norm of row index R starting in col
8703 // index C; matrix A has count N columns.
8704 func calcColumnMaximumNorm(mtxA [][]float64, r, c, n int) float64 {
8705         var norm float64
8706         for col := c; col < n; col++ {
8707                 if norm < math.Abs(mtxA[col][r]) {
8708                         norm = math.Abs(mtxA[col][r])
8709                 }
8710         }
8711         return norm
8712 }
8713
8714 // calcColsEuclideanNorm returns euclidean norm of row index R starting in
8715 // column index C; matrix A has count N columns.
8716 func calcColsEuclideanNorm(mtxA [][]float64, r, c, n int) float64 {
8717         var norm float64
8718         for col := c; col < n; col++ {
8719                 norm += (mtxA[col][r]) * (mtxA[col][r])
8720         }
8721         return math.Sqrt(norm)
8722 }
8723
8724 // calcColsSumProduct returns sum product for given matrix.
8725 func calcColsSumProduct(mtxA [][]float64, a int, mtxB [][]float64, b, c, n int) float64 {
8726         var result float64
8727         for col := c; col < n; col++ {
8728                 result += mtxA[col][a] * mtxB[col][b]
8729         }
8730         return result
8731 }
8732
8733 // calcColQRDecomposition same with transposed matrix A, N is count of
8734 // columns, k count of rows.
8735 func calcColQRDecomposition(mtxA [][]float64, vecR []float64, k, n int) bool {
8736         var sum float64
8737         for row := 0; row < k; row++ {
8738                 // calculate vector u of the householder transformation
8739                 scale := calcColumnMaximumNorm(mtxA, row, row, n)
8740                 if scale == 0 {
8741                         return false
8742                 }
8743                 for col := row; col < n; col++ {
8744                         mtxA[col][row] = mtxA[col][row] / scale
8745                 }
8746                 euclid := calcColsEuclideanNorm(mtxA, row, row, n)
8747                 factor := 1 / euclid / (euclid + math.Abs(mtxA[row][row]))
8748                 signum := calcSign(mtxA[row][row])
8749                 mtxA[row][row] = mtxA[row][row] + signum*euclid
8750                 vecR[row] = -signum * scale * euclid
8751                 // apply Householder transformation to A
8752                 for r := row + 1; r < k; r++ {
8753                         sum = calcColsSumProduct(mtxA, row, mtxA, r, row, n)
8754                         for col := row; col < n; col++ {
8755                                 mtxA[col][r] = mtxA[col][r] - sum*factor*mtxA[col][row]
8756                         }
8757                 }
8758         }
8759         return true
8760 }
8761
8762 // calcApplyRowsHouseholderTransformation applies a Householder transformation to a
8763 // column vector Y with is given as Nx1 Matrix. The vector u, from which the
8764 // Householder transformation is built, is the column part in matrix A, with
8765 // column index c, starting with row index c. A is the result of the QR
8766 // decomposition as obtained from calcRowQRDecomposition.
8767 func calcApplyRowsHouseholderTransformation(mtxA [][]float64, c int, mtxY [][]float64, n int) {
8768         denominator := calcRowsSumProduct(mtxA, c, mtxA, c, c, n)
8769         numerator := calcRowsSumProduct(mtxA, c, mtxY, 0, c, n)
8770         factor := 2 * (numerator / denominator)
8771         for row := c; row < n; row++ {
8772                 putDouble(mtxY, row, getDouble(mtxY, row)-factor*mtxA[c][row])
8773         }
8774 }
8775
8776 // calcTrendGrowthSimpleRegression calculate simple regression for the calcTrendGrowth.
8777 func calcTrendGrowthSimpleRegression(bConstant, bGrowth bool, mtxY, mtxX, newX, mtxRes [][]float64, meanY float64, N int) {
8778         var meanX float64
8779         if bConstant {
8780                 meanX = calcMeanOverAll(mtxX, N)
8781                 for i := 0; i < len(mtxX); i++ {
8782                         for j := 0; j < len(mtxX[i]); j++ {
8783                                 mtxX[i][j] = approxSub(mtxX[i][j], meanX)
8784                         }
8785                 }
8786         }
8787         sumXY := calcSumProduct(mtxX, mtxY, N)
8788         sumX2 := calcSumProduct(mtxX, mtxX, N)
8789         slope := sumXY / sumX2
8790         var help float64
8791         var intercept float64
8792         if bConstant {
8793                 intercept = meanY - slope*meanX
8794                 for i := 0; i < len(mtxRes); i++ {
8795                         for j := 0; j < len(mtxRes[i]); j++ {
8796                                 help = newX[i][j]*slope + intercept
8797                                 if bGrowth {
8798                                         mtxRes[i][j] = math.Exp(help)
8799                                 } else {
8800                                         mtxRes[i][j] = help
8801                                 }
8802                         }
8803                 }
8804         } else {
8805                 for i := 0; i < len(mtxRes); i++ {
8806                         for j := 0; j < len(mtxRes[i]); j++ {
8807                                 help = newX[i][j] * slope
8808                                 if bGrowth {
8809                                         mtxRes[i][j] = math.Exp(help)
8810                                 } else {
8811                                         mtxRes[i][j] = help
8812                                 }
8813                         }
8814                 }
8815         }
8816 }
8817
8818 // calcTrendGrowthMultipleRegressionPart1 calculate multiple regression for the
8819 // calcTrendGrowth.
8820 func calcTrendGrowthMultipleRegressionPart1(bConstant, bGrowth bool, mtxY, mtxX, newX, mtxRes [][]float64, meanY float64, RXN, K, N int) {
8821         vecR := make([]float64, N)   // for QR decomposition
8822         means := getNewMatrix(K, 1)  // mean of each column
8823         slopes := getNewMatrix(1, K) // from b1 to bK
8824         if len(means) == 0 || len(slopes) == 0 {
8825                 return
8826         }
8827         if bConstant {
8828                 calcColumnMeans(mtxX, means, K, N)
8829                 calcColumnsDelta(mtxX, means, K, N)
8830         }
8831         if !calcRowQRDecomposition(mtxX, vecR, K, N) {
8832                 return
8833         }
8834         // Later on we will divide by elements of vecR, so make sure that they aren't zero.
8835         bIsSingular := false
8836         for row := 0; row < K && !bIsSingular; row++ {
8837                 bIsSingular = bIsSingular || vecR[row] == 0
8838         }
8839         if bIsSingular {
8840                 return
8841         }
8842         for col := 0; col < K; col++ {
8843                 calcApplyRowsHouseholderTransformation(mtxX, col, mtxY, N)
8844         }
8845         for col := 0; col < K; col++ {
8846                 putDouble(slopes, col, getDouble(mtxY, col))
8847         }
8848         calcSolveWithUpperRightTriangle(mtxX, vecR, slopes, K, false)
8849         // Fill result matrix
8850         calcFastMult(newX, slopes, mtxRes, RXN, K, 1)
8851         if bConstant {
8852                 intercept := meanY - calcSumProduct(means, slopes, K)
8853                 for row := 0; row < RXN; row++ {
8854                         mtxRes[0][row] = mtxRes[0][row] + intercept
8855                 }
8856         }
8857         if bGrowth {
8858                 for i := 0; i < RXN; i++ {
8859                         putDouble(mtxRes, i, math.Exp(getDouble(mtxRes, i)))
8860                 }
8861         }
8862 }
8863
8864 // calcTrendGrowthMultipleRegressionPart2 calculate multiple regression for the
8865 // calcTrendGrowth.
8866 func calcTrendGrowthMultipleRegressionPart2(bConstant, bGrowth bool, mtxY, mtxX, newX, mtxRes [][]float64, meanY float64, nCXN, K, N int) {
8867         vecR := make([]float64, N)   // for QR decomposition
8868         means := getNewMatrix(K, 1)  // mean of each row
8869         slopes := getNewMatrix(K, 1) // row from b1 to bK
8870         if len(means) == 0 || len(slopes) == 0 {
8871                 return
8872         }
8873         if bConstant {
8874                 calcRowMeans(mtxX, means, N, K)
8875                 calcRowsDelta(mtxX, means, N, K)
8876         }
8877         if !calcColQRDecomposition(mtxX, vecR, K, N) {
8878                 return
8879         }
8880         // later on we will divide by elements of vecR, so make sure that they aren't zero
8881         bIsSingular := false
8882         for row := 0; row < K && !bIsSingular; row++ {
8883                 bIsSingular = bIsSingular || vecR[row] == 0
8884         }
8885         if bIsSingular {
8886                 return
8887         }
8888         for row := 0; row < K; row++ {
8889                 calcApplyColsHouseholderTransformation(mtxX, row, mtxY, N)
8890         }
8891         for col := 0; col < K; col++ {
8892                 putDouble(slopes, col, getDouble(mtxY, col))
8893         }
8894         calcSolveWithUpperRightTriangle(mtxX, vecR, slopes, K, true)
8895         // fill result matrix
8896         calcFastMult(slopes, newX, mtxRes, 1, K, nCXN)
8897         if bConstant {
8898                 fIntercept := meanY - calcSumProduct(means, slopes, K)
8899                 for col := 0; col < nCXN; col++ {
8900                         mtxRes[col][0] = mtxRes[col][0] + fIntercept
8901                 }
8902         }
8903         if bGrowth {
8904                 for i := 0; i < nCXN; i++ {
8905                         putDouble(mtxRes, i, math.Exp(getDouble(mtxRes, i)))
8906                 }
8907         }
8908 }
8909
8910 // calcTrendGrowthRegression is a part of implementation of the calcTrendGrowth.
8911 func calcTrendGrowthRegression(bConstant, bGrowth bool, trendType, nCXN, nRXN, K, N int, mtxY, mtxX, newX, mtxRes [][]float64) {
8912         if len(mtxRes) == 0 {
8913                 return
8914         }
8915         var meanY float64
8916         if bConstant {
8917                 copyX, copyY := matrixClone(mtxX), matrixClone(mtxY)
8918                 mtxX, mtxY = copyX, copyY
8919                 meanY = calcMeanOverAll(mtxY, N)
8920                 for i := 0; i < len(mtxY); i++ {
8921                         for j := 0; j < len(mtxY[i]); j++ {
8922                                 mtxY[i][j] = approxSub(mtxY[i][j], meanY)
8923                         }
8924                 }
8925         }
8926         switch trendType {
8927         case 1:
8928                 calcTrendGrowthSimpleRegression(bConstant, bGrowth, mtxY, mtxX, newX, mtxRes, meanY, N)
8929         case 2:
8930                 calcTrendGrowthMultipleRegressionPart1(bConstant, bGrowth, mtxY, mtxX, newX, mtxRes, meanY, nRXN, K, N)
8931         default:
8932                 calcTrendGrowthMultipleRegressionPart2(bConstant, bGrowth, mtxY, mtxX, newX, mtxRes, meanY, nCXN, K, N)
8933         }
8934 }
8935
8936 // calcTrendGrowth returns values along a predicted exponential trend.
8937 func calcTrendGrowth(mtxY, mtxX, newX [][]float64, bConstant, bGrowth bool) ([][]float64, formulaArg) {
8938         getMatrixParams, errArg := prepareTrendGrowth(bGrowth, mtxX, mtxY)
8939         if errArg.Type != ArgEmpty {
8940                 return nil, errArg
8941         }
8942         trendType := getMatrixParams.trendType
8943         nCX := getMatrixParams.nCX
8944         nRX := getMatrixParams.nRX
8945         K := getMatrixParams.M
8946         N := getMatrixParams.N
8947         mtxX = getMatrixParams.mtxX
8948         mtxY = getMatrixParams.mtxY
8949         // checking if data samples are enough
8950         if (bConstant && (N < K+1)) || (!bConstant && (N < K)) || (N < 1) || (K < 1) {
8951                 return nil, errArg
8952         }
8953         // set the default newX if necessary
8954         nCXN, nRXN := nCX, nRX
8955         if len(newX) == 0 {
8956                 newX = matrixClone(mtxX) // mtxX will be changed to X-meanX
8957         } else {
8958                 nRXN, nCXN = len(newX[0]), len(newX)
8959                 if (trendType == 2 && K != nCXN) || (trendType == 3 && K != nRXN) {
8960                         return nil, errArg
8961                 }
8962         }
8963         var mtxRes [][]float64
8964         switch trendType {
8965         case 1:
8966                 mtxRes = getNewMatrix(nCXN, nRXN)
8967         case 2:
8968                 mtxRes = getNewMatrix(1, nRXN)
8969         default:
8970                 mtxRes = getNewMatrix(nCXN, 1)
8971         }
8972         calcTrendGrowthRegression(bConstant, bGrowth, trendType, nCXN, nRXN, K, N, mtxY, mtxX, newX, mtxRes)
8973         return mtxRes, errArg
8974 }
8975
8976 // trendGrowth is an implementation of the formula functions GROWTH and TREND.
8977 func (fn *formulaFuncs) trendGrowth(name string, argsList *list.List) formulaArg {
8978         if argsList.Len() < 1 {
8979                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
8980         }
8981         if argsList.Len() > 4 {
8982                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s allows at most 4 arguments", name))
8983         }
8984         var knowY, knowX, newX [][]float64
8985         var errArg formulaArg
8986         constArg := newBoolFormulaArg(true)
8987         knowY, errArg = newNumberMatrix(argsList.Front().Value.(formulaArg), false)
8988         if errArg.Type == ArgError {
8989                 return errArg
8990         }
8991         if argsList.Len() > 1 {
8992                 knowX, errArg = newNumberMatrix(argsList.Front().Next().Value.(formulaArg), false)
8993                 if errArg.Type == ArgError {
8994                         return errArg
8995                 }
8996         }
8997         if argsList.Len() > 2 {
8998                 newX, errArg = newNumberMatrix(argsList.Front().Next().Next().Value.(formulaArg), false)
8999                 if errArg.Type == ArgError {
9000                         return errArg
9001                 }
9002         }
9003         if argsList.Len() > 3 {
9004                 if constArg = argsList.Back().Value.(formulaArg).ToBool(); constArg.Type != ArgNumber {
9005                         return constArg
9006                 }
9007         }
9008         var mtxNewX [][]float64
9009         for i := 0; i < len(newX); i++ {
9010                 for j := 0; j < len(newX[i]); j++ {
9011                         for x := len(mtxNewX); x <= j; x++ {
9012                                 mtxNewX = append(mtxNewX, []float64{})
9013                         }
9014                         for k := len(mtxNewX[j]); k <= i; k++ {
9015                                 mtxNewX[j] = append(mtxNewX[j], 0)
9016                         }
9017                         mtxNewX[j][i] = newX[i][j]
9018                 }
9019         }
9020         mtx, errArg := calcTrendGrowth(knowY, knowX, mtxNewX, constArg.Number == 1, name == "GROWTH")
9021         if errArg.Type != ArgEmpty {
9022                 return errArg
9023         }
9024         return newMatrixFormulaArg(newFormulaArgMatrix(mtx))
9025 }
9026
9027 // GROWTH function calculates the exponential growth curve through a given set
9028 // of y-values and (optionally), one or more sets of x-values. The function
9029 // then extends the curve to calculate additional y-values for a further
9030 // supplied set of new x-values. The syntax of the function is:
9031 //
9032 //      GROWTH(known_y's,[known_x's],[new_x's],[const])
9033 func (fn *formulaFuncs) GROWTH(argsList *list.List) formulaArg {
9034         return fn.trendGrowth("GROWTH", argsList)
9035 }
9036
9037 // HARMEAN function calculates the harmonic mean of a supplied set of values.
9038 // The syntax of the function is:
9039 //
9040 //      HARMEAN(number1,[number2],...)
9041 func (fn *formulaFuncs) HARMEAN(argsList *list.List) formulaArg {
9042         if argsList.Len() < 1 {
9043                 return newErrorFormulaArg(formulaErrorVALUE, "HARMEAN requires at least 1 argument")
9044         }
9045         if min := fn.MIN(argsList); min.Number < 0 {
9046                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
9047         }
9048         number, val, cnt := 0.0, 0.0, 0.0
9049         for token := argsList.Front(); token != nil; token = token.Next() {
9050                 arg := token.Value.(formulaArg)
9051                 switch arg.Type {
9052                 case ArgString:
9053                         num := arg.ToNumber()
9054                         if num.Type != ArgNumber {
9055                                 continue
9056                         }
9057                         number = num.Number
9058                 case ArgNumber:
9059                         number = arg.Number
9060                 }
9061                 if number <= 0 {
9062                         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
9063                 }
9064                 val += 1 / number
9065                 cnt++
9066         }
9067         return newNumberFormulaArg(1 / (val / cnt))
9068 }
9069
9070 // checkHYPGEOMDISTArgs checking arguments for the formula function HYPGEOMDIST
9071 // and HYPGEOM.DIST.
9072 func checkHYPGEOMDISTArgs(sampleS, numberSample, populationS, numberPop formulaArg) bool {
9073         return sampleS.Number < 0 ||
9074                 sampleS.Number > math.Min(numberSample.Number, populationS.Number) ||
9075                 sampleS.Number < math.Max(0, numberSample.Number-numberPop.Number+populationS.Number) ||
9076                 numberSample.Number <= 0 ||
9077                 numberSample.Number > numberPop.Number ||
9078                 populationS.Number <= 0 ||
9079                 populationS.Number > numberPop.Number ||
9080                 numberPop.Number <= 0
9081 }
9082
9083 // prepareHYPGEOMDISTArgs prepare arguments for the formula function
9084 // HYPGEOMDIST and HYPGEOM.DIST.
9085 func (fn *formulaFuncs) prepareHYPGEOMDISTArgs(name string, argsList *list.List) formulaArg {
9086         if name == "HYPGEOMDIST" && argsList.Len() != 4 {
9087                 return newErrorFormulaArg(formulaErrorVALUE, "HYPGEOMDIST requires 4 numeric arguments")
9088         }
9089         if name == "HYPGEOM.DIST" && argsList.Len() != 5 {
9090                 return newErrorFormulaArg(formulaErrorVALUE, "HYPGEOM.DIST requires 5 arguments")
9091         }
9092         var sampleS, numberSample, populationS, numberPop, cumulative formulaArg
9093         if sampleS = argsList.Front().Value.(formulaArg).ToNumber(); sampleS.Type != ArgNumber {
9094                 return sampleS
9095         }
9096         if numberSample = argsList.Front().Next().Value.(formulaArg).ToNumber(); numberSample.Type != ArgNumber {
9097                 return numberSample
9098         }
9099         if populationS = argsList.Front().Next().Next().Value.(formulaArg).ToNumber(); populationS.Type != ArgNumber {
9100                 return populationS
9101         }
9102         if numberPop = argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber(); numberPop.Type != ArgNumber {
9103                 return numberPop
9104         }
9105         if checkHYPGEOMDISTArgs(sampleS, numberSample, populationS, numberPop) {
9106                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9107         }
9108         if name == "HYPGEOM.DIST" {
9109                 if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type != ArgNumber {
9110                         return cumulative
9111                 }
9112         }
9113         return newListFormulaArg([]formulaArg{sampleS, numberSample, populationS, numberPop, cumulative})
9114 }
9115
9116 // HYPGEOMdotDIST function returns the value of the hypergeometric distribution
9117 // for a specified number of successes from a population sample. The function
9118 // can calculate the cumulative distribution or the probability density
9119 // function. The syntax of the function is:
9120 //
9121 //      HYPGEOM.DIST(sample_s,number_sample,population_s,number_pop,cumulative)
9122 func (fn *formulaFuncs) HYPGEOMdotDIST(argsList *list.List) formulaArg {
9123         args := fn.prepareHYPGEOMDISTArgs("HYPGEOM.DIST", argsList)
9124         if args.Type != ArgList {
9125                 return args
9126         }
9127         sampleS, numberSample, populationS, numberPop, cumulative := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4]
9128         if cumulative.Number == 1 {
9129                 var res float64
9130                 for i := 0; i <= int(sampleS.Number); i++ {
9131                         res += binomCoeff(populationS.Number, float64(i)) *
9132                                 binomCoeff(numberPop.Number-populationS.Number, numberSample.Number-float64(i)) /
9133                                 binomCoeff(numberPop.Number, numberSample.Number)
9134                 }
9135                 return newNumberFormulaArg(res)
9136         }
9137         return newNumberFormulaArg(binomCoeff(populationS.Number, sampleS.Number) *
9138                 binomCoeff(numberPop.Number-populationS.Number, numberSample.Number-sampleS.Number) /
9139                 binomCoeff(numberPop.Number, numberSample.Number))
9140 }
9141
9142 // HYPGEOMDIST function returns the value of the hypergeometric distribution
9143 // for a given number of successes from a sample of a population. The syntax
9144 // of the function is:
9145 //
9146 //      HYPGEOMDIST(sample_s,number_sample,population_s,number_pop)
9147 func (fn *formulaFuncs) HYPGEOMDIST(argsList *list.List) formulaArg {
9148         args := fn.prepareHYPGEOMDISTArgs("HYPGEOMDIST", argsList)
9149         if args.Type != ArgList {
9150                 return args
9151         }
9152         sampleS, numberSample, populationS, numberPop := args.List[0], args.List[1], args.List[2], args.List[3]
9153         return newNumberFormulaArg(binomCoeff(populationS.Number, sampleS.Number) *
9154                 binomCoeff(numberPop.Number-populationS.Number, numberSample.Number-sampleS.Number) /
9155                 binomCoeff(numberPop.Number, numberSample.Number))
9156 }
9157
9158 // INTERCEPT function calculates the intercept (the value at the intersection
9159 // of the y axis) of the linear regression line through a supplied set of x-
9160 // and y- values. The syntax of the function is:
9161 //
9162 //      INTERCEPT(known_y's,known_x's)
9163 func (fn *formulaFuncs) INTERCEPT(argsList *list.List) formulaArg {
9164         return fn.pearsonProduct("INTERCEPT", 2, argsList)
9165 }
9166
9167 // KURT function calculates the kurtosis of a supplied set of values. The
9168 // syntax of the function is:
9169 //
9170 //      KURT(number1,[number2],...)
9171 func (fn *formulaFuncs) KURT(argsList *list.List) formulaArg {
9172         if argsList.Len() < 1 {
9173                 return newErrorFormulaArg(formulaErrorVALUE, "KURT requires at least 1 argument")
9174         }
9175         mean, stdev := fn.AVERAGE(argsList), fn.STDEV(argsList)
9176         if stdev.Number > 0 {
9177                 count, summer := 0.0, 0.0
9178                 for arg := argsList.Front(); arg != nil; arg = arg.Next() {
9179                         token := arg.Value.(formulaArg)
9180                         switch token.Type {
9181                         case ArgString, ArgNumber:
9182                                 num := token.ToNumber()
9183                                 if num.Type == ArgError {
9184                                         continue
9185                                 }
9186                                 summer += math.Pow((num.Number-mean.Number)/stdev.Number, 4)
9187                                 count++
9188                         case ArgList, ArgMatrix:
9189                                 for _, row := range token.ToList() {
9190                                         if row.Type == ArgNumber || row.Type == ArgString {
9191                                                 num := row.ToNumber()
9192                                                 if num.Type == ArgError {
9193                                                         continue
9194                                                 }
9195                                                 summer += math.Pow((num.Number-mean.Number)/stdev.Number, 4)
9196                                                 count++
9197                                         }
9198                                 }
9199                         }
9200                 }
9201                 if count > 3 {
9202                         return newNumberFormulaArg(summer*(count*(count+1)/((count-1)*(count-2)*(count-3))) - (3 * math.Pow(count-1, 2) / ((count - 2) * (count - 3))))
9203                 }
9204         }
9205         return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
9206 }
9207
9208 // EXPONdotDIST function returns the value of the exponential distribution for
9209 // a give value of x. The user can specify whether the probability density
9210 // function or the cumulative distribution function is used. The syntax of the
9211 // Expondist function is:
9212 //
9213 //      EXPON.DIST(x,lambda,cumulative)
9214 func (fn *formulaFuncs) EXPONdotDIST(argsList *list.List) formulaArg {
9215         if argsList.Len() != 3 {
9216                 return newErrorFormulaArg(formulaErrorVALUE, "EXPON.DIST requires 3 arguments")
9217         }
9218         return fn.EXPONDIST(argsList)
9219 }
9220
9221 // EXPONDIST function returns the value of the exponential distribution for a
9222 // give value of x. The user can specify whether the probability density
9223 // function or the cumulative distribution function is used. The syntax of the
9224 // Expondist function is:
9225 //
9226 //      EXPONDIST(x,lambda,cumulative)
9227 func (fn *formulaFuncs) EXPONDIST(argsList *list.List) formulaArg {
9228         if argsList.Len() != 3 {
9229                 return newErrorFormulaArg(formulaErrorVALUE, "EXPONDIST requires 3 arguments")
9230         }
9231         var x, lambda, cumulative formulaArg
9232         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
9233                 return x
9234         }
9235         if lambda = argsList.Front().Next().Value.(formulaArg).ToNumber(); lambda.Type != ArgNumber {
9236                 return lambda
9237         }
9238         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
9239                 return cumulative
9240         }
9241         if x.Number < 0 {
9242                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9243         }
9244         if lambda.Number <= 0 {
9245                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9246         }
9247         if cumulative.Number == 1 {
9248                 return newNumberFormulaArg(1 - math.Exp(-lambda.Number*x.Number))
9249         }
9250         return newNumberFormulaArg(lambda.Number * math.Exp(-lambda.Number*x.Number))
9251 }
9252
9253 // FdotDIST function calculates the Probability Density Function or the
9254 // Cumulative Distribution Function for the F Distribution. This function is
9255 // frequently used to measure the degree of diversity between two data
9256 // sets. The syntax of the function is:
9257 //
9258 //      F.DIST(x,deg_freedom1,deg_freedom2,cumulative)
9259 func (fn *formulaFuncs) FdotDIST(argsList *list.List) formulaArg {
9260         if argsList.Len() != 4 {
9261                 return newErrorFormulaArg(formulaErrorVALUE, "F.DIST requires 4 arguments")
9262         }
9263         var x, deg1, deg2, cumulative formulaArg
9264         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
9265                 return x
9266         }
9267         if deg1 = argsList.Front().Next().Value.(formulaArg).ToNumber(); deg1.Type != ArgNumber {
9268                 return deg1
9269         }
9270         if deg2 = argsList.Front().Next().Next().Value.(formulaArg).ToNumber(); deg2.Type != ArgNumber {
9271                 return deg2
9272         }
9273         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
9274                 return cumulative
9275         }
9276         if x.Number < 0 {
9277                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9278         }
9279         maxDeg := math.Pow10(10)
9280         if deg1.Number < 1 || deg1.Number >= maxDeg {
9281                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9282         }
9283         if deg2.Number < 1 || deg2.Number >= maxDeg {
9284                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9285         }
9286         if cumulative.Number == 1 {
9287                 return newNumberFormulaArg(1 - getBetaDist(deg2.Number/(deg2.Number+deg1.Number*x.Number), deg2.Number/2, deg1.Number/2))
9288         }
9289         return newNumberFormulaArg(math.Gamma((deg2.Number+deg1.Number)/2) / (math.Gamma(deg1.Number/2) * math.Gamma(deg2.Number/2)) * math.Pow(deg1.Number/deg2.Number, deg1.Number/2) * (math.Pow(x.Number, (deg1.Number-2)/2) / math.Pow(1+(deg1.Number/deg2.Number)*x.Number, (deg1.Number+deg2.Number)/2)))
9290 }
9291
9292 // FDIST function calculates the (right-tailed) F Probability Distribution,
9293 // which measures the degree of diversity between two data sets. The syntax
9294 // of the function is:
9295 //
9296 //      FDIST(x,deg_freedom1,deg_freedom2)
9297 func (fn *formulaFuncs) FDIST(argsList *list.List) formulaArg {
9298         if argsList.Len() != 3 {
9299                 return newErrorFormulaArg(formulaErrorVALUE, "FDIST requires 3 arguments")
9300         }
9301         var x, deg1, deg2 formulaArg
9302         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
9303                 return x
9304         }
9305         if deg1 = argsList.Front().Next().Value.(formulaArg).ToNumber(); deg1.Type != ArgNumber {
9306                 return deg1
9307         }
9308         if deg2 = argsList.Back().Value.(formulaArg).ToNumber(); deg2.Type != ArgNumber {
9309                 return deg2
9310         }
9311         if x.Number < 0 {
9312                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9313         }
9314         maxDeg := math.Pow10(10)
9315         if deg1.Number < 1 || deg1.Number >= maxDeg {
9316                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9317         }
9318         if deg2.Number < 1 || deg2.Number >= maxDeg {
9319                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9320         }
9321         args := list.New()
9322         args.PushBack(newNumberFormulaArg(deg1.Number * x.Number / (deg1.Number*x.Number + deg2.Number)))
9323         args.PushBack(newNumberFormulaArg(0.5 * deg1.Number))
9324         args.PushBack(newNumberFormulaArg(0.5 * deg2.Number))
9325         args.PushBack(newNumberFormulaArg(0))
9326         args.PushBack(newNumberFormulaArg(1))
9327         return newNumberFormulaArg(1 - fn.BETADIST(args).Number)
9328 }
9329
9330 // FdotDISTdotRT function calculates the (right-tailed) F Probability
9331 // Distribution, which measures the degree of diversity between two data sets.
9332 // The syntax of the function is:
9333 //
9334 //      F.DIST.RT(x,deg_freedom1,deg_freedom2)
9335 func (fn *formulaFuncs) FdotDISTdotRT(argsList *list.List) formulaArg {
9336         if argsList.Len() != 3 {
9337                 return newErrorFormulaArg(formulaErrorVALUE, "F.DIST.RT requires 3 arguments")
9338         }
9339         return fn.FDIST(argsList)
9340 }
9341
9342 // prepareFinvArgs checking and prepare arguments for the formula functions
9343 // F.INV, F.INV.RT and FINV.
9344 func (fn *formulaFuncs) prepareFinvArgs(name string, argsList *list.List) formulaArg {
9345         if argsList.Len() != 3 {
9346                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 arguments", name))
9347         }
9348         var probability, d1, d2 formulaArg
9349         if probability = argsList.Front().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
9350                 return probability
9351         }
9352         if d1 = argsList.Front().Next().Value.(formulaArg).ToNumber(); d1.Type != ArgNumber {
9353                 return d1
9354         }
9355         if d2 = argsList.Back().Value.(formulaArg).ToNumber(); d2.Type != ArgNumber {
9356                 return d2
9357         }
9358         if probability.Number <= 0 || probability.Number > 1 {
9359                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9360         }
9361         if d1.Number < 1 || d1.Number >= math.Pow10(10) {
9362                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9363         }
9364         if d2.Number < 1 || d2.Number >= math.Pow10(10) {
9365                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9366         }
9367         return newListFormulaArg([]formulaArg{probability, d1, d2})
9368 }
9369
9370 // FdotINV function calculates the inverse of the Cumulative F Distribution
9371 // for a supplied probability. The syntax of the F.Inv function is:
9372 //
9373 //      F.INV(probability,deg_freedom1,deg_freedom2)
9374 func (fn *formulaFuncs) FdotINV(argsList *list.List) formulaArg {
9375         args := fn.prepareFinvArgs("F.INV", argsList)
9376         if args.Type != ArgList {
9377                 return args
9378         }
9379         probability, d1, d2 := args.List[0], args.List[1], args.List[2]
9380         return newNumberFormulaArg((1/calcBetainv(1-probability.Number, d2.Number/2, d1.Number/2, 0, 1) - 1) * (d2.Number / d1.Number))
9381 }
9382
9383 // FdotINVdotRT function calculates the inverse of the (right-tailed) F
9384 // Probability Distribution for a supplied probability. The syntax of the
9385 // function is:
9386 //
9387 //      F.INV.RT(probability,deg_freedom1,deg_freedom2)
9388 func (fn *formulaFuncs) FdotINVdotRT(argsList *list.List) formulaArg {
9389         args := fn.prepareFinvArgs("F.INV.RT", argsList)
9390         if args.Type != ArgList {
9391                 return args
9392         }
9393         probability, d1, d2 := args.List[0], args.List[1], args.List[2]
9394         return newNumberFormulaArg((1/calcBetainv(1-(1-probability.Number), d2.Number/2, d1.Number/2, 0, 1) - 1) * (d2.Number / d1.Number))
9395 }
9396
9397 // FINV function calculates the inverse of the (right-tailed) F Probability
9398 // Distribution for a supplied probability. The syntax of the function is:
9399 //
9400 //      FINV(probability,deg_freedom1,deg_freedom2)
9401 func (fn *formulaFuncs) FINV(argsList *list.List) formulaArg {
9402         args := fn.prepareFinvArgs("FINV", argsList)
9403         if args.Type != ArgList {
9404                 return args
9405         }
9406         probability, d1, d2 := args.List[0], args.List[1], args.List[2]
9407         return newNumberFormulaArg((1/calcBetainv(1-(1-probability.Number), d2.Number/2, d1.Number/2, 0, 1) - 1) * (d2.Number / d1.Number))
9408 }
9409
9410 // FdotTEST function returns the F-Test for two supplied arrays. I.e. the
9411 // function returns the two-tailed probability that the variances in the two
9412 // supplied arrays are not significantly different. The syntax of the Ftest
9413 // function is:
9414 //
9415 //      F.TEST(array1,array2)
9416 func (fn *formulaFuncs) FdotTEST(argsList *list.List) formulaArg {
9417         if argsList.Len() != 2 {
9418                 return newErrorFormulaArg(formulaErrorVALUE, "F.TEST requires 2 arguments")
9419         }
9420         array1 := argsList.Front().Value.(formulaArg)
9421         array2 := argsList.Back().Value.(formulaArg)
9422         left, right := array1.ToList(), array2.ToList()
9423         collectMatrix := func(args []formulaArg) (n, accu float64) {
9424                 var p, sum float64
9425                 for _, arg := range args {
9426                         if num := arg.ToNumber(); num.Type == ArgNumber {
9427                                 x := num.Number - p
9428                                 y := x / (n + 1)
9429                                 p += y
9430                                 accu += n * x * y
9431                                 n++
9432                                 sum += num.Number
9433                         }
9434                 }
9435                 return
9436         }
9437         nums, accu := collectMatrix(left)
9438         f3 := nums - 1
9439         if nums == 1 {
9440                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
9441         }
9442         f1 := accu / (nums - 1)
9443         if f1 == 0 {
9444                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
9445         }
9446         nums, accu = collectMatrix(right)
9447         f4 := nums - 1
9448         if nums == 1 {
9449                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
9450         }
9451         f2 := accu / (nums - 1)
9452         if f2 == 0 {
9453                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
9454         }
9455         args := list.New()
9456         args.PushBack(newNumberFormulaArg(f1 / f2))
9457         args.PushBack(newNumberFormulaArg(f3))
9458         args.PushBack(newNumberFormulaArg(f4))
9459         probability := (1 - fn.FDIST(args).Number) * 2
9460         if probability > 1 {
9461                 probability = 2 - probability
9462         }
9463         return newNumberFormulaArg(probability)
9464 }
9465
9466 // FTEST function returns the F-Test for two supplied arrays. I.e. the function
9467 // returns the two-tailed probability that the variances in the two supplied
9468 // arrays are not significantly different. The syntax of the Ftest function
9469 // is:
9470 //
9471 //      FTEST(array1,array2)
9472 func (fn *formulaFuncs) FTEST(argsList *list.List) formulaArg {
9473         if argsList.Len() != 2 {
9474                 return newErrorFormulaArg(formulaErrorVALUE, "FTEST requires 2 arguments")
9475         }
9476         return fn.FdotTEST(argsList)
9477 }
9478
9479 // LOGINV function calculates the inverse of the Cumulative Log-Normal
9480 // Distribution Function of x, for a supplied probability. The syntax of the
9481 // function is:
9482 //
9483 //      LOGINV(probability,mean,standard_dev)
9484 func (fn *formulaFuncs) LOGINV(argsList *list.List) formulaArg {
9485         if argsList.Len() != 3 {
9486                 return newErrorFormulaArg(formulaErrorVALUE, "LOGINV requires 3 arguments")
9487         }
9488         var probability, mean, stdDev formulaArg
9489         if probability = argsList.Front().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
9490                 return probability
9491         }
9492         if mean = argsList.Front().Next().Value.(formulaArg).ToNumber(); mean.Type != ArgNumber {
9493                 return mean
9494         }
9495         if stdDev = argsList.Back().Value.(formulaArg).ToNumber(); stdDev.Type != ArgNumber {
9496                 return stdDev
9497         }
9498         if probability.Number <= 0 || probability.Number >= 1 {
9499                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9500         }
9501         if stdDev.Number <= 0 {
9502                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9503         }
9504         args := list.New()
9505         args.PushBack(probability)
9506         args.PushBack(newNumberFormulaArg(0))
9507         args.PushBack(newNumberFormulaArg(1))
9508         norminv := fn.NORMINV(args)
9509         return newNumberFormulaArg(math.Exp(mean.Number + stdDev.Number*norminv.Number))
9510 }
9511
9512 // LOGNORMdotINV function calculates the inverse of the Cumulative Log-Normal
9513 // Distribution Function of x, for a supplied probability. The syntax of the
9514 // function is:
9515 //
9516 //      LOGNORM.INV(probability,mean,standard_dev)
9517 func (fn *formulaFuncs) LOGNORMdotINV(argsList *list.List) formulaArg {
9518         if argsList.Len() != 3 {
9519                 return newErrorFormulaArg(formulaErrorVALUE, "LOGNORM.INV requires 3 arguments")
9520         }
9521         return fn.LOGINV(argsList)
9522 }
9523
9524 // LOGNORMdotDIST function calculates the Log-Normal Probability Density
9525 // Function or the Cumulative Log-Normal Distribution Function for a supplied
9526 // value of x. The syntax of the function is:
9527 //
9528 //      LOGNORM.DIST(x,mean,standard_dev,cumulative)
9529 func (fn *formulaFuncs) LOGNORMdotDIST(argsList *list.List) formulaArg {
9530         if argsList.Len() != 4 {
9531                 return newErrorFormulaArg(formulaErrorVALUE, "LOGNORM.DIST requires 4 arguments")
9532         }
9533         var x, mean, stdDev, cumulative formulaArg
9534         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
9535                 return x
9536         }
9537         if mean = argsList.Front().Next().Value.(formulaArg).ToNumber(); mean.Type != ArgNumber {
9538                 return mean
9539         }
9540         if stdDev = argsList.Back().Prev().Value.(formulaArg).ToNumber(); stdDev.Type != ArgNumber {
9541                 return stdDev
9542         }
9543         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
9544                 return cumulative
9545         }
9546         if x.Number <= 0 || stdDev.Number <= 0 {
9547                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9548         }
9549         if cumulative.Number == 1 {
9550                 args := list.New()
9551                 args.PushBack(newNumberFormulaArg((math.Log(x.Number) - mean.Number) / stdDev.Number))
9552                 args.PushBack(newNumberFormulaArg(0))
9553                 args.PushBack(newNumberFormulaArg(1))
9554                 args.PushBack(cumulative)
9555                 return fn.NORMDIST(args)
9556         }
9557         return newNumberFormulaArg((1 / (math.Sqrt(2*math.Pi) * stdDev.Number * x.Number)) *
9558                 math.Exp(0-(math.Pow(math.Log(x.Number)-mean.Number, 2)/(2*math.Pow(stdDev.Number, 2)))))
9559 }
9560
9561 // LOGNORMDIST function calculates the Cumulative Log-Normal Distribution
9562 // Function at a supplied value of x. The syntax of the function is:
9563 //
9564 //      LOGNORMDIST(x,mean,standard_dev)
9565 func (fn *formulaFuncs) LOGNORMDIST(argsList *list.List) formulaArg {
9566         if argsList.Len() != 3 {
9567                 return newErrorFormulaArg(formulaErrorVALUE, "LOGNORMDIST requires 3 arguments")
9568         }
9569         var x, mean, stdDev formulaArg
9570         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
9571                 return x
9572         }
9573         if mean = argsList.Front().Next().Value.(formulaArg).ToNumber(); mean.Type != ArgNumber {
9574                 return mean
9575         }
9576         if stdDev = argsList.Back().Value.(formulaArg).ToNumber(); stdDev.Type != ArgNumber {
9577                 return stdDev
9578         }
9579         if x.Number <= 0 || stdDev.Number <= 0 {
9580                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9581         }
9582         args := list.New()
9583         args.PushBack(newNumberFormulaArg((math.Log(x.Number) - mean.Number) / stdDev.Number))
9584         return fn.NORMSDIST(args)
9585 }
9586
9587 // MODE function returns the statistical mode (the most frequently occurring
9588 // value) of a list of supplied numbers. If there are 2 or more most
9589 // frequently occurring values in the supplied data, the function returns the
9590 // lowest of these values The syntax of the function is:
9591 //
9592 //      MODE(number1,[number2],...)
9593 func (fn *formulaFuncs) MODE(argsList *list.List) formulaArg {
9594         if argsList.Len() < 1 {
9595                 return newErrorFormulaArg(formulaErrorVALUE, "MODE requires at least 1 argument")
9596         }
9597         var values []float64
9598         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
9599                 cells := arg.Value.(formulaArg)
9600                 if cells.Type != ArgMatrix && cells.Type != ArgNumber {
9601                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
9602                 }
9603                 for _, cell := range cells.ToList() {
9604                         if cell.Type == ArgNumber {
9605                                 values = append(values, cell.Number)
9606                         }
9607                 }
9608         }
9609         sort.Float64s(values)
9610         cnt := len(values)
9611         var count, modeCnt int
9612         var mode float64
9613         for i := 0; i < cnt; i++ {
9614                 count = 0
9615                 for j := 0; j < cnt; j++ {
9616                         if j != i && values[j] == values[i] {
9617                                 count++
9618                         }
9619                 }
9620                 if count > modeCnt {
9621                         modeCnt = count
9622                         mode = values[i]
9623                 }
9624         }
9625         if modeCnt == 0 {
9626                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
9627         }
9628         return newNumberFormulaArg(mode)
9629 }
9630
9631 // MODEdotMULT function returns a vertical array of the statistical modes
9632 // (the most frequently occurring values) within a list of supplied numbers.
9633 // The syntax of the function is:
9634 //
9635 //      MODE.MULT(number1,[number2],...)
9636 func (fn *formulaFuncs) MODEdotMULT(argsList *list.List) formulaArg {
9637         if argsList.Len() < 1 {
9638                 return newErrorFormulaArg(formulaErrorVALUE, "MODE.MULT requires at least 1 argument")
9639         }
9640         var values []float64
9641         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
9642                 cells := arg.Value.(formulaArg)
9643                 if cells.Type != ArgMatrix && cells.Type != ArgNumber {
9644                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
9645                 }
9646                 for _, cell := range cells.ToList() {
9647                         if cell.Type == ArgNumber {
9648                                 values = append(values, cell.Number)
9649                         }
9650                 }
9651         }
9652         sort.Float64s(values)
9653         cnt := len(values)
9654         var count, modeCnt int
9655         var mtx [][]formulaArg
9656         for i := 0; i < cnt; i++ {
9657                 count = 0
9658                 for j := i + 1; j < cnt; j++ {
9659                         if values[i] == values[j] {
9660                                 count++
9661                         }
9662                 }
9663                 if count > modeCnt {
9664                         modeCnt = count
9665                         mtx = [][]formulaArg{}
9666                         mtx = append(mtx, []formulaArg{newNumberFormulaArg(values[i])})
9667                 } else if count == modeCnt {
9668                         mtx = append(mtx, []formulaArg{newNumberFormulaArg(values[i])})
9669                 }
9670         }
9671         if modeCnt == 0 {
9672                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
9673         }
9674         return newMatrixFormulaArg(mtx)
9675 }
9676
9677 // MODEdotSNGL function returns the statistical mode (the most frequently
9678 // occurring value) within a list of supplied numbers. If there are 2 or more
9679 // most frequently occurring values in the supplied data, the function returns
9680 // the lowest of these values. The syntax of the function is:
9681 //
9682 //      MODE.SNGL(number1,[number2],...)
9683 func (fn *formulaFuncs) MODEdotSNGL(argsList *list.List) formulaArg {
9684         if argsList.Len() < 1 {
9685                 return newErrorFormulaArg(formulaErrorVALUE, "MODE.SNGL requires at least 1 argument")
9686         }
9687         return fn.MODE(argsList)
9688 }
9689
9690 // NEGBINOMdotDIST function calculates the probability mass function or the
9691 // cumulative distribution function for the Negative Binomial Distribution.
9692 // This gives the probability that there will be a given number of failures
9693 // before a required number of successes is achieved. The syntax of the
9694 // function is:
9695 //
9696 //      NEGBINOM.DIST(number_f,number_s,probability_s,cumulative)
9697 func (fn *formulaFuncs) NEGBINOMdotDIST(argsList *list.List) formulaArg {
9698         if argsList.Len() != 4 {
9699                 return newErrorFormulaArg(formulaErrorVALUE, "NEGBINOM.DIST requires 4 arguments")
9700         }
9701         var f, s, probability, cumulative formulaArg
9702         if f = argsList.Front().Value.(formulaArg).ToNumber(); f.Type != ArgNumber {
9703                 return f
9704         }
9705         if s = argsList.Front().Next().Value.(formulaArg).ToNumber(); s.Type != ArgNumber {
9706                 return s
9707         }
9708         if probability = argsList.Front().Next().Next().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
9709                 return probability
9710         }
9711         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type != ArgNumber {
9712                 return cumulative
9713         }
9714         if f.Number < 0 || s.Number < 1 || probability.Number < 0 || probability.Number > 1 {
9715                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9716         }
9717         if cumulative.Number == 1 {
9718                 return newNumberFormulaArg(1 - getBetaDist(1-probability.Number, f.Number+1, s.Number))
9719         }
9720         return newNumberFormulaArg(binomCoeff(f.Number+s.Number-1, s.Number-1) * math.Pow(probability.Number, s.Number) * math.Pow(1-probability.Number, f.Number))
9721 }
9722
9723 // NEGBINOMDIST function calculates the Negative Binomial Distribution for a
9724 // given set of parameters. This gives the probability that there will be a
9725 // specified number of failures before a required number of successes is
9726 // achieved. The syntax of the function is:
9727 //
9728 //      NEGBINOMDIST(number_f,number_s,probability_s)
9729 func (fn *formulaFuncs) NEGBINOMDIST(argsList *list.List) formulaArg {
9730         if argsList.Len() != 3 {
9731                 return newErrorFormulaArg(formulaErrorVALUE, "NEGBINOMDIST requires 3 arguments")
9732         }
9733         var f, s, probability formulaArg
9734         if f = argsList.Front().Value.(formulaArg).ToNumber(); f.Type != ArgNumber {
9735                 return f
9736         }
9737         if s = argsList.Front().Next().Value.(formulaArg).ToNumber(); s.Type != ArgNumber {
9738                 return s
9739         }
9740         if probability = argsList.Back().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
9741                 return probability
9742         }
9743         if f.Number < 0 || s.Number < 1 || probability.Number < 0 || probability.Number > 1 {
9744                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
9745         }
9746         return newNumberFormulaArg(binomCoeff(f.Number+s.Number-1, s.Number-1) * math.Pow(probability.Number, s.Number) * math.Pow(1-probability.Number, f.Number))
9747 }
9748
9749 // NORMdotDIST function calculates the Normal Probability Density Function or
9750 // the Cumulative Normal Distribution. Function for a supplied set of
9751 // parameters. The syntax of the function is:
9752 //
9753 //      NORM.DIST(x,mean,standard_dev,cumulative)
9754 func (fn *formulaFuncs) NORMdotDIST(argsList *list.List) formulaArg {
9755         if argsList.Len() != 4 {
9756                 return newErrorFormulaArg(formulaErrorVALUE, "NORM.DIST requires 4 arguments")
9757         }
9758         return fn.NORMDIST(argsList)
9759 }
9760
9761 // NORMDIST function calculates the Normal Probability Density Function or the
9762 // Cumulative Normal Distribution. Function for a supplied set of parameters.
9763 // The syntax of the function is:
9764 //
9765 //      NORMDIST(x,mean,standard_dev,cumulative)
9766 func (fn *formulaFuncs) NORMDIST(argsList *list.List) formulaArg {
9767         if argsList.Len() != 4 {
9768                 return newErrorFormulaArg(formulaErrorVALUE, "NORMDIST requires 4 arguments")
9769         }
9770         var x, mean, stdDev, cumulative formulaArg
9771         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
9772                 return x
9773         }
9774         if mean = argsList.Front().Next().Value.(formulaArg).ToNumber(); mean.Type != ArgNumber {
9775                 return mean
9776         }
9777         if stdDev = argsList.Back().Prev().Value.(formulaArg).ToNumber(); stdDev.Type != ArgNumber {
9778                 return stdDev
9779         }
9780         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
9781                 return cumulative
9782         }
9783         if stdDev.Number < 0 {
9784                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
9785         }
9786         if cumulative.Number == 1 {
9787                 return newNumberFormulaArg(0.5 * (1 + math.Erf((x.Number-mean.Number)/(stdDev.Number*math.Sqrt(2)))))
9788         }
9789         return newNumberFormulaArg((1 / (math.Sqrt(2*math.Pi) * stdDev.Number)) * math.Exp(0-(math.Pow(x.Number-mean.Number, 2)/(2*(stdDev.Number*stdDev.Number)))))
9790 }
9791
9792 // NORMdotINV function calculates the inverse of the Cumulative Normal
9793 // Distribution Function for a supplied value of x, and a supplied
9794 // distribution mean & standard deviation. The syntax of the function is:
9795 //
9796 //      NORM.INV(probability,mean,standard_dev)
9797 func (fn *formulaFuncs) NORMdotINV(argsList *list.List) formulaArg {
9798         if argsList.Len() != 3 {
9799                 return newErrorFormulaArg(formulaErrorVALUE, "NORM.INV requires 3 arguments")
9800         }
9801         return fn.NORMINV(argsList)
9802 }
9803
9804 // NORMINV function calculates the inverse of the Cumulative Normal
9805 // Distribution Function for a supplied value of x, and a supplied
9806 // distribution mean & standard deviation. The syntax of the function is:
9807 //
9808 //      NORMINV(probability,mean,standard_dev)
9809 func (fn *formulaFuncs) NORMINV(argsList *list.List) formulaArg {
9810         if argsList.Len() != 3 {
9811                 return newErrorFormulaArg(formulaErrorVALUE, "NORMINV requires 3 arguments")
9812         }
9813         var prob, mean, stdDev formulaArg
9814         if prob = argsList.Front().Value.(formulaArg).ToNumber(); prob.Type != ArgNumber {
9815                 return prob
9816         }
9817         if mean = argsList.Front().Next().Value.(formulaArg).ToNumber(); mean.Type != ArgNumber {
9818                 return mean
9819         }
9820         if stdDev = argsList.Back().Value.(formulaArg).ToNumber(); stdDev.Type != ArgNumber {
9821                 return stdDev
9822         }
9823         if prob.Number < 0 || prob.Number > 1 {
9824                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
9825         }
9826         if stdDev.Number < 0 {
9827                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
9828         }
9829         inv, err := norminv(prob.Number)
9830         if err != nil {
9831                 return newErrorFormulaArg(err.Error(), err.Error())
9832         }
9833         return newNumberFormulaArg(inv*stdDev.Number + mean.Number)
9834 }
9835
9836 // NORMdotSdotDIST function calculates the Standard Normal Cumulative
9837 // Distribution Function for a supplied value. The syntax of the function
9838 // is:
9839 //
9840 //      NORM.S.DIST(z)
9841 func (fn *formulaFuncs) NORMdotSdotDIST(argsList *list.List) formulaArg {
9842         if argsList.Len() != 2 {
9843                 return newErrorFormulaArg(formulaErrorVALUE, "NORM.S.DIST requires 2 numeric arguments")
9844         }
9845         args := list.New().Init()
9846         args.PushBack(argsList.Front().Value.(formulaArg))
9847         args.PushBack(formulaArg{Type: ArgNumber, Number: 0})
9848         args.PushBack(formulaArg{Type: ArgNumber, Number: 1})
9849         args.PushBack(argsList.Back().Value.(formulaArg))
9850         return fn.NORMDIST(args)
9851 }
9852
9853 // NORMSDIST function calculates the Standard Normal Cumulative Distribution
9854 // Function for a supplied value. The syntax of the function is:
9855 //
9856 //      NORMSDIST(z)
9857 func (fn *formulaFuncs) NORMSDIST(argsList *list.List) formulaArg {
9858         if argsList.Len() != 1 {
9859                 return newErrorFormulaArg(formulaErrorVALUE, "NORMSDIST requires 1 numeric argument")
9860         }
9861         args := list.New().Init()
9862         args.PushBack(argsList.Front().Value.(formulaArg))
9863         args.PushBack(formulaArg{Type: ArgNumber, Number: 0})
9864         args.PushBack(formulaArg{Type: ArgNumber, Number: 1})
9865         args.PushBack(formulaArg{Type: ArgNumber, Number: 1, Boolean: true})
9866         return fn.NORMDIST(args)
9867 }
9868
9869 // NORMSINV function calculates the inverse of the Standard Normal Cumulative
9870 // Distribution Function for a supplied probability value. The syntax of the
9871 // function is:
9872 //
9873 //      NORMSINV(probability)
9874 func (fn *formulaFuncs) NORMSINV(argsList *list.List) formulaArg {
9875         if argsList.Len() != 1 {
9876                 return newErrorFormulaArg(formulaErrorVALUE, "NORMSINV requires 1 numeric argument")
9877         }
9878         args := list.New().Init()
9879         args.PushBack(argsList.Front().Value.(formulaArg))
9880         args.PushBack(formulaArg{Type: ArgNumber, Number: 0})
9881         args.PushBack(formulaArg{Type: ArgNumber, Number: 1})
9882         return fn.NORMINV(args)
9883 }
9884
9885 // NORMdotSdotINV function calculates the inverse of the Standard Normal
9886 // Cumulative Distribution Function for a supplied probability value. The
9887 // syntax of the function is:
9888 //
9889 //      NORM.S.INV(probability)
9890 func (fn *formulaFuncs) NORMdotSdotINV(argsList *list.List) formulaArg {
9891         if argsList.Len() != 1 {
9892                 return newErrorFormulaArg(formulaErrorVALUE, "NORM.S.INV requires 1 numeric argument")
9893         }
9894         args := list.New().Init()
9895         args.PushBack(argsList.Front().Value.(formulaArg))
9896         args.PushBack(formulaArg{Type: ArgNumber, Number: 0})
9897         args.PushBack(formulaArg{Type: ArgNumber, Number: 1})
9898         return fn.NORMINV(args)
9899 }
9900
9901 // norminv returns the inverse of the normal cumulative distribution for the
9902 // specified value.
9903 func norminv(p float64) (float64, error) {
9904         a := map[int]float64{
9905                 1: -3.969683028665376e+01, 2: 2.209460984245205e+02, 3: -2.759285104469687e+02,
9906                 4: 1.383577518672690e+02, 5: -3.066479806614716e+01, 6: 2.506628277459239e+00,
9907         }
9908         b := map[int]float64{
9909                 1: -5.447609879822406e+01, 2: 1.615858368580409e+02, 3: -1.556989798598866e+02,
9910                 4: 6.680131188771972e+01, 5: -1.328068155288572e+01,
9911         }
9912         c := map[int]float64{
9913                 1: -7.784894002430293e-03, 2: -3.223964580411365e-01, 3: -2.400758277161838e+00,
9914                 4: -2.549732539343734e+00, 5: 4.374664141464968e+00, 6: 2.938163982698783e+00,
9915         }
9916         d := map[int]float64{
9917                 1: 7.784695709041462e-03, 2: 3.224671290700398e-01, 3: 2.445134137142996e+00,
9918                 4: 3.754408661907416e+00,
9919         }
9920         pLow := 0.02425   // Use lower region approx. below this
9921         pHigh := 1 - pLow // Use upper region approx. above this
9922         if 0 < p && p < pLow {
9923                 // Rational approximation for lower region.
9924                 q := math.Sqrt(-2 * math.Log(p))
9925                 return (((((c[1]*q+c[2])*q+c[3])*q+c[4])*q+c[5])*q + c[6]) /
9926                         ((((d[1]*q+d[2])*q+d[3])*q+d[4])*q + 1), nil
9927         } else if pLow <= p && p <= pHigh {
9928                 // Rational approximation for central region.
9929                 q := p - 0.5
9930                 r := q * q
9931                 f1 := ((((a[1]*r+a[2])*r+a[3])*r+a[4])*r + a[5]) * r
9932                 f2 := (b[1]*r + b[2]) * r
9933                 f3 := ((math.Nextafter(f2, f2)+b[3])*r + b[4]) * r
9934                 f4 := (math.Nextafter(f3, f3) + b[5]) * r
9935                 return (math.Nextafter(f1, f1) + a[6]) * q /
9936                         (math.Nextafter(f4, f4) + 1), nil
9937         } else if pHigh < p && p < 1 {
9938                 // Rational approximation for upper region.
9939                 q := math.Sqrt(-2 * math.Log(1-p))
9940                 return -(((((c[1]*q+c[2])*q+c[3])*q+c[4])*q+c[5])*q + c[6]) /
9941                         ((((d[1]*q+d[2])*q+d[3])*q+d[4])*q + 1), nil
9942         }
9943         return 0, errors.New(formulaErrorNUM)
9944 }
9945
9946 // kth is an implementation of the formula functions LARGE and SMALL.
9947 func (fn *formulaFuncs) kth(name string, argsList *list.List) formulaArg {
9948         if argsList.Len() != 2 {
9949                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 arguments", name))
9950         }
9951         array := argsList.Front().Value.(formulaArg).ToList()
9952         argK := argsList.Back().Value.(formulaArg).ToNumber()
9953         if argK.Type != ArgNumber {
9954                 return argK
9955         }
9956         k := int(argK.Number)
9957         if k < 1 {
9958                 return newErrorFormulaArg(formulaErrorNUM, "k should be > 0")
9959         }
9960         var data []float64
9961         for _, arg := range array {
9962                 if arg.Type == ArgNumber {
9963                         data = append(data, arg.Number)
9964                 }
9965         }
9966         if len(data) < k {
9967                 return newErrorFormulaArg(formulaErrorNUM, "k should be <= length of array")
9968         }
9969         sort.Float64s(data)
9970         if name == "LARGE" {
9971                 return newNumberFormulaArg(data[len(data)-k])
9972         }
9973         return newNumberFormulaArg(data[k-1])
9974 }
9975
9976 // LARGE function returns the k'th largest value from an array of numeric
9977 // values. The syntax of the function is:
9978 //
9979 //      LARGE(array,k)
9980 func (fn *formulaFuncs) LARGE(argsList *list.List) formulaArg {
9981         return fn.kth("LARGE", argsList)
9982 }
9983
9984 // MAX function returns the largest value from a supplied set of numeric
9985 // values. The syntax of the function is:
9986 //
9987 //      MAX(number1,[number2],...)
9988 func (fn *formulaFuncs) MAX(argsList *list.List) formulaArg {
9989         if argsList.Len() == 0 {
9990                 return newErrorFormulaArg(formulaErrorVALUE, "MAX requires at least 1 argument")
9991         }
9992         return fn.max(false, argsList)
9993 }
9994
9995 // MAXA function returns the largest value from a supplied set of numeric
9996 // values, while counting text and the logical value FALSE as the value 0 and
9997 // counting the logical value TRUE as the value 1. The syntax of the function
9998 // is:
9999 //
10000 //      MAXA(number1,[number2],...)
10001 func (fn *formulaFuncs) MAXA(argsList *list.List) formulaArg {
10002         if argsList.Len() == 0 {
10003                 return newErrorFormulaArg(formulaErrorVALUE, "MAXA requires at least 1 argument")
10004         }
10005         return fn.max(true, argsList)
10006 }
10007
10008 // MAXIFS function returns the maximum value from a subset of values that are
10009 // specified according to one or more criteria. The syntax of the function
10010 // is:
10011 //
10012 //      MAXIFS(max_range,criteria_range1,criteria1,[criteria_range2,criteria2],...)
10013 func (fn *formulaFuncs) MAXIFS(argsList *list.List) formulaArg {
10014         if argsList.Len() < 3 {
10015                 return newErrorFormulaArg(formulaErrorVALUE, "MAXIFS requires at least 3 arguments")
10016         }
10017         if argsList.Len()%2 != 1 {
10018                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10019         }
10020         var args []formulaArg
10021         max, maxRange := -math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix
10022         for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() {
10023                 args = append(args, arg.Value.(formulaArg))
10024         }
10025         for _, ref := range formulaIfsMatch(args) {
10026                 if num := maxRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && max < num.Number {
10027                         max = num.Number
10028                 }
10029         }
10030         if max == -math.MaxFloat64 {
10031                 max = 0
10032         }
10033         return newNumberFormulaArg(max)
10034 }
10035
10036 // calcListMatrixMax is part of the implementation max.
10037 func calcListMatrixMax(maxa bool, max float64, arg formulaArg) float64 {
10038         for _, cell := range arg.ToList() {
10039                 if cell.Type == ArgNumber && cell.Number > max {
10040                         if maxa && cell.Boolean || !cell.Boolean {
10041                                 max = cell.Number
10042                         }
10043                 }
10044         }
10045         return max
10046 }
10047
10048 // max is an implementation of the formula functions MAX and MAXA.
10049 func (fn *formulaFuncs) max(maxa bool, argsList *list.List) formulaArg {
10050         max := -math.MaxFloat64
10051         for token := argsList.Front(); token != nil; token = token.Next() {
10052                 arg := token.Value.(formulaArg)
10053                 switch arg.Type {
10054                 case ArgString:
10055                         if !maxa && (arg.Value() == "TRUE" || arg.Value() == "FALSE") {
10056                                 continue
10057                         } else {
10058                                 num := arg.ToBool()
10059                                 if num.Type == ArgNumber && num.Number > max {
10060                                         max = num.Number
10061                                         continue
10062                                 }
10063                         }
10064                         num := arg.ToNumber()
10065                         if num.Type != ArgError && num.Number > max {
10066                                 max = num.Number
10067                         }
10068                 case ArgNumber:
10069                         if arg.Number > max {
10070                                 max = arg.Number
10071                         }
10072                 case ArgList, ArgMatrix:
10073                         max = calcListMatrixMax(maxa, max, arg)
10074                 case ArgError:
10075                         return arg
10076                 }
10077         }
10078         if max == -math.MaxFloat64 {
10079                 max = 0
10080         }
10081         return newNumberFormulaArg(max)
10082 }
10083
10084 // MEDIAN function returns the statistical median (the middle value) of a list
10085 // of supplied numbers. The syntax of the function is:
10086 //
10087 //      MEDIAN(number1,[number2],...)
10088 func (fn *formulaFuncs) MEDIAN(argsList *list.List) formulaArg {
10089         if argsList.Len() == 0 {
10090                 return newErrorFormulaArg(formulaErrorVALUE, "MEDIAN requires at least 1 argument")
10091         }
10092         var values []float64
10093         var median float64
10094         for token := argsList.Front(); token != nil; token = token.Next() {
10095                 arg := token.Value.(formulaArg)
10096                 switch arg.Type {
10097                 case ArgString:
10098                         value := arg.ToNumber()
10099                         if value.Type != ArgNumber {
10100                                 return value
10101                         }
10102                         values = append(values, value.Number)
10103                 case ArgNumber:
10104                         values = append(values, arg.Number)
10105                 case ArgMatrix:
10106                         for _, row := range arg.Matrix {
10107                                 for _, cell := range row {
10108                                         if cell.Type == ArgNumber {
10109                                                 values = append(values, cell.Number)
10110                                         }
10111                                 }
10112                         }
10113                 }
10114         }
10115         if len(values) == 0 {
10116                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10117         }
10118         sort.Float64s(values)
10119         if len(values)%2 == 0 {
10120                 median = (values[len(values)/2-1] + values[len(values)/2]) / 2
10121         } else {
10122                 median = values[len(values)/2]
10123         }
10124         return newNumberFormulaArg(median)
10125 }
10126
10127 // MIN function returns the smallest value from a supplied set of numeric
10128 // values. The syntax of the function is:
10129 //
10130 //      MIN(number1,[number2],...)
10131 func (fn *formulaFuncs) MIN(argsList *list.List) formulaArg {
10132         if argsList.Len() == 0 {
10133                 return newErrorFormulaArg(formulaErrorVALUE, "MIN requires at least 1 argument")
10134         }
10135         return fn.min(false, argsList)
10136 }
10137
10138 // MINA function returns the smallest value from a supplied set of numeric
10139 // values, while counting text and the logical value FALSE as the value 0 and
10140 // counting the logical value TRUE as the value 1. The syntax of the function
10141 // is:
10142 //
10143 //      MINA(number1,[number2],...)
10144 func (fn *formulaFuncs) MINA(argsList *list.List) formulaArg {
10145         if argsList.Len() == 0 {
10146                 return newErrorFormulaArg(formulaErrorVALUE, "MINA requires at least 1 argument")
10147         }
10148         return fn.min(true, argsList)
10149 }
10150
10151 // MINIFS function returns the minimum value from a subset of values that are
10152 // specified according to one or more criteria. The syntax of the function
10153 // is:
10154 //
10155 //      MINIFS(min_range,criteria_range1,criteria1,[criteria_range2,criteria2],...)
10156 func (fn *formulaFuncs) MINIFS(argsList *list.List) formulaArg {
10157         if argsList.Len() < 3 {
10158                 return newErrorFormulaArg(formulaErrorVALUE, "MINIFS requires at least 3 arguments")
10159         }
10160         if argsList.Len()%2 != 1 {
10161                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10162         }
10163         var args []formulaArg
10164         min, minRange := math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix
10165         for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() {
10166                 args = append(args, arg.Value.(formulaArg))
10167         }
10168         for _, ref := range formulaIfsMatch(args) {
10169                 if num := minRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && min > num.Number {
10170                         min = num.Number
10171                 }
10172         }
10173         if min == math.MaxFloat64 {
10174                 min = 0
10175         }
10176         return newNumberFormulaArg(min)
10177 }
10178
10179 // calcListMatrixMin is part of the implementation min.
10180 func calcListMatrixMin(mina bool, min float64, arg formulaArg) float64 {
10181         for _, cell := range arg.ToList() {
10182                 if cell.Type == ArgNumber && cell.Number < min {
10183                         if mina && cell.Boolean || !cell.Boolean {
10184                                 min = cell.Number
10185                         }
10186                 }
10187         }
10188         return min
10189 }
10190
10191 // min is an implementation of the formula functions MIN and MINA.
10192 func (fn *formulaFuncs) min(mina bool, argsList *list.List) formulaArg {
10193         min := math.MaxFloat64
10194         for token := argsList.Front(); token != nil; token = token.Next() {
10195                 arg := token.Value.(formulaArg)
10196                 switch arg.Type {
10197                 case ArgString:
10198                         if !mina && (arg.Value() == "TRUE" || arg.Value() == "FALSE") {
10199                                 continue
10200                         } else {
10201                                 num := arg.ToBool()
10202                                 if num.Type == ArgNumber && num.Number < min {
10203                                         min = num.Number
10204                                         continue
10205                                 }
10206                         }
10207                         num := arg.ToNumber()
10208                         if num.Type != ArgError && num.Number < min {
10209                                 min = num.Number
10210                         }
10211                 case ArgNumber:
10212                         if arg.Number < min {
10213                                 min = arg.Number
10214                         }
10215                 case ArgList, ArgMatrix:
10216                         min = calcListMatrixMin(mina, min, arg)
10217                 case ArgError:
10218                         return arg
10219                 }
10220         }
10221         if min == math.MaxFloat64 {
10222                 min = 0
10223         }
10224         return newNumberFormulaArg(min)
10225 }
10226
10227 // pearsonProduct is an implementation of the formula functions FORECAST,
10228 // FORECAST.LINEAR, INTERCEPT, PEARSON, RSQ and SLOPE.
10229 func (fn *formulaFuncs) pearsonProduct(name string, n int, argsList *list.List) formulaArg {
10230         if argsList.Len() != n {
10231                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires %d arguments", name, n))
10232         }
10233         var fx formulaArg
10234         array1 := argsList.Back().Value.(formulaArg).ToList()
10235         array2 := argsList.Front().Value.(formulaArg).ToList()
10236         if name == "PEARSON" || name == "RSQ" {
10237                 array1, array2 = array2, array1
10238         }
10239         if n == 3 {
10240                 if fx = argsList.Front().Value.(formulaArg).ToNumber(); fx.Type != ArgNumber {
10241                         return fx
10242                 }
10243                 array2 = argsList.Front().Next().Value.(formulaArg).ToList()
10244         }
10245         if len(array1) != len(array2) {
10246                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10247         }
10248         var sum, deltaX, deltaY, x, y, length float64
10249         for i := 0; i < len(array1); i++ {
10250                 num1, num2 := array1[i], array2[i]
10251                 if !(num1.Type == ArgNumber && num2.Type == ArgNumber) {
10252                         continue
10253                 }
10254                 x += num1.Number
10255                 y += num2.Number
10256                 length++
10257         }
10258         x /= length
10259         y /= length
10260         for i := 0; i < len(array1); i++ {
10261                 num1, num2 := array1[i], array2[i]
10262                 if !(num1.Type == ArgNumber && num2.Type == ArgNumber) {
10263                         continue
10264                 }
10265                 sum += (num1.Number - x) * (num2.Number - y)
10266                 deltaX += (num1.Number - x) * (num1.Number - x)
10267                 deltaY += (num2.Number - y) * (num2.Number - y)
10268         }
10269         if sum*deltaX*deltaY == 0 {
10270                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
10271         }
10272         return newNumberFormulaArg(map[string]float64{
10273                 "FORECAST":        y + sum/deltaX*(fx.Number-x),
10274                 "FORECAST.LINEAR": y + sum/deltaX*(fx.Number-x),
10275                 "INTERCEPT":       y - sum/deltaX*x,
10276                 "PEARSON":         sum / math.Sqrt(deltaX*deltaY),
10277                 "RSQ":             math.Pow(sum/math.Sqrt(deltaX*deltaY), 2),
10278                 "SLOPE":           sum / deltaX,
10279         }[name])
10280 }
10281
10282 // PEARSON function calculates the Pearson Product-Moment Correlation
10283 // Coefficient for two sets of values. The syntax of the function is:
10284 //
10285 //      PEARSON(array1,array2)
10286 func (fn *formulaFuncs) PEARSON(argsList *list.List) formulaArg {
10287         return fn.pearsonProduct("PEARSON", 2, argsList)
10288 }
10289
10290 // PERCENTILEdotEXC function returns the k'th percentile (i.e. the value below
10291 // which k% of the data values fall) for a supplied range of values and a
10292 // supplied k (between 0 & 1 exclusive).The syntax of the function is:
10293 //
10294 //      PERCENTILE.EXC(array,k)
10295 func (fn *formulaFuncs) PERCENTILEdotEXC(argsList *list.List) formulaArg {
10296         if argsList.Len() != 2 {
10297                 return newErrorFormulaArg(formulaErrorVALUE, "PERCENTILE.EXC requires 2 arguments")
10298         }
10299         array := argsList.Front().Value.(formulaArg).ToList()
10300         k := argsList.Back().Value.(formulaArg).ToNumber()
10301         if k.Type != ArgNumber {
10302                 return k
10303         }
10304         if k.Number <= 0 || k.Number >= 1 {
10305                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10306         }
10307         var numbers []float64
10308         for _, arg := range array {
10309                 if arg.Type == ArgError {
10310                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10311                 }
10312                 if arg.Type == ArgNumber {
10313                         numbers = append(numbers, arg.Number)
10314                 }
10315         }
10316         cnt := len(numbers)
10317         sort.Float64s(numbers)
10318         idx := k.Number * (float64(cnt) + 1)
10319         base := math.Floor(idx)
10320         next := base - 1
10321         proportion := math.Nextafter(idx, idx) - base
10322         return newNumberFormulaArg(numbers[int(next)] + ((numbers[int(base)] - numbers[int(next)]) * proportion))
10323 }
10324
10325 // PERCENTILEdotINC function returns the k'th percentile (i.e. the value below
10326 // which k% of the data values fall) for a supplied range of values and a
10327 // supplied k. The syntax of the function is:
10328 //
10329 //      PERCENTILE.INC(array,k)
10330 func (fn *formulaFuncs) PERCENTILEdotINC(argsList *list.List) formulaArg {
10331         if argsList.Len() != 2 {
10332                 return newErrorFormulaArg(formulaErrorVALUE, "PERCENTILE.INC requires 2 arguments")
10333         }
10334         return fn.PERCENTILE(argsList)
10335 }
10336
10337 // PERCENTILE function returns the k'th percentile (i.e. the value below which
10338 // k% of the data values fall) for a supplied range of values and a supplied
10339 // k. The syntax of the function is:
10340 //
10341 //      PERCENTILE(array,k)
10342 func (fn *formulaFuncs) PERCENTILE(argsList *list.List) formulaArg {
10343         if argsList.Len() != 2 {
10344                 return newErrorFormulaArg(formulaErrorVALUE, "PERCENTILE requires 2 arguments")
10345         }
10346         array := argsList.Front().Value.(formulaArg).ToList()
10347         k := argsList.Back().Value.(formulaArg).ToNumber()
10348         if k.Type != ArgNumber {
10349                 return k
10350         }
10351         if k.Number < 0 || k.Number > 1 {
10352                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10353         }
10354         var numbers []float64
10355         for _, arg := range array {
10356                 if arg.Type == ArgError {
10357                         return arg
10358                 }
10359                 if arg.Type == ArgNumber {
10360                         numbers = append(numbers, arg.Number)
10361                 }
10362         }
10363         cnt := len(numbers)
10364         sort.Float64s(numbers)
10365         idx := k.Number * (float64(cnt) - 1)
10366         base := math.Floor(idx)
10367         if idx == base {
10368                 return newNumberFormulaArg(numbers[int(idx)])
10369         }
10370         next := base + 1
10371         proportion := math.Nextafter(idx, idx) - base
10372         return newNumberFormulaArg(numbers[int(base)] + ((numbers[int(next)] - numbers[int(base)]) * proportion))
10373 }
10374
10375 // percentrank is an implementation of the formula functions PERCENTRANK and
10376 // PERCENTRANK.INC.
10377 func (fn *formulaFuncs) percentrank(name string, argsList *list.List) formulaArg {
10378         if argsList.Len() != 2 && argsList.Len() != 3 {
10379                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 or 3 arguments", name))
10380         }
10381         array := argsList.Front().Value.(formulaArg).ToList()
10382         x := argsList.Front().Next().Value.(formulaArg).ToNumber()
10383         if x.Type != ArgNumber {
10384                 return x
10385         }
10386         var numbers []float64
10387         for _, arg := range array {
10388                 if arg.Type == ArgError {
10389                         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10390                 }
10391                 if arg.Type == ArgNumber {
10392                         numbers = append(numbers, arg.Number)
10393                 }
10394         }
10395         cnt := len(numbers)
10396         sort.Float64s(numbers)
10397         if x.Number < numbers[0] || x.Number > numbers[cnt-1] {
10398                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10399         }
10400         pos, significance := float64(inFloat64Slice(numbers, x.Number)), newNumberFormulaArg(3)
10401         if argsList.Len() == 3 {
10402                 if significance = argsList.Back().Value.(formulaArg).ToNumber(); significance.Type != ArgNumber {
10403                         return significance
10404                 }
10405                 if significance.Number < 1 {
10406                         return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s arguments significance should be > 1", name))
10407                 }
10408         }
10409         if pos == -1 {
10410                 pos = 0
10411                 cmp := numbers[0]
10412                 for cmp < x.Number {
10413                         pos++
10414                         cmp = numbers[int(pos)]
10415                 }
10416                 pos--
10417                 pos += (x.Number - numbers[int(pos)]) / (cmp - numbers[int(pos)])
10418         }
10419         pow := math.Pow(10, significance.Number)
10420         digit := pow * pos / (float64(cnt) - 1)
10421         if name == "PERCENTRANK.EXC" {
10422                 digit = pow * (pos + 1) / (float64(cnt) + 1)
10423         }
10424         return newNumberFormulaArg(math.Floor(digit) / pow)
10425 }
10426
10427 // PERCENTRANKdotEXC function calculates the relative position, between 0 and
10428 // 1 (exclusive), of a specified value within a supplied array. The syntax of
10429 // the function is:
10430 //
10431 //      PERCENTRANK.EXC(array,x,[significance])
10432 func (fn *formulaFuncs) PERCENTRANKdotEXC(argsList *list.List) formulaArg {
10433         return fn.percentrank("PERCENTRANK.EXC", argsList)
10434 }
10435
10436 // PERCENTRANKdotINC function calculates the relative position, between 0 and
10437 // 1 (inclusive), of a specified value within a supplied array.The syntax of
10438 // the function is:
10439 //
10440 //      PERCENTRANK.INC(array,x,[significance])
10441 func (fn *formulaFuncs) PERCENTRANKdotINC(argsList *list.List) formulaArg {
10442         return fn.percentrank("PERCENTRANK.INC", argsList)
10443 }
10444
10445 // PERCENTRANK function calculates the relative position of a specified value,
10446 // within a set of values, as a percentage. The syntax of the function is:
10447 //
10448 //      PERCENTRANK(array,x,[significance])
10449 func (fn *formulaFuncs) PERCENTRANK(argsList *list.List) formulaArg {
10450         return fn.percentrank("PERCENTRANK", argsList)
10451 }
10452
10453 // PERMUT function calculates the number of permutations of a specified number
10454 // of objects from a set of objects. The syntax of the function is:
10455 //
10456 //      PERMUT(number,number_chosen)
10457 func (fn *formulaFuncs) PERMUT(argsList *list.List) formulaArg {
10458         if argsList.Len() != 2 {
10459                 return newErrorFormulaArg(formulaErrorVALUE, "PERMUT requires 2 numeric arguments")
10460         }
10461         number := argsList.Front().Value.(formulaArg).ToNumber()
10462         chosen := argsList.Back().Value.(formulaArg).ToNumber()
10463         if number.Type != ArgNumber {
10464                 return number
10465         }
10466         if chosen.Type != ArgNumber {
10467                 return chosen
10468         }
10469         if number.Number < chosen.Number {
10470                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10471         }
10472         return newNumberFormulaArg(math.Round(fact(number.Number) / fact(number.Number-chosen.Number)))
10473 }
10474
10475 // PERMUTATIONA function calculates the number of permutations, with
10476 // repetitions, of a specified number of objects from a set. The syntax of
10477 // the function is:
10478 //
10479 //      PERMUTATIONA(number,number_chosen)
10480 func (fn *formulaFuncs) PERMUTATIONA(argsList *list.List) formulaArg {
10481         if argsList.Len() < 1 {
10482                 return newErrorFormulaArg(formulaErrorVALUE, "PERMUTATIONA requires 2 numeric arguments")
10483         }
10484         number := argsList.Front().Value.(formulaArg).ToNumber()
10485         chosen := argsList.Back().Value.(formulaArg).ToNumber()
10486         if number.Type != ArgNumber {
10487                 return number
10488         }
10489         if chosen.Type != ArgNumber {
10490                 return chosen
10491         }
10492         num, numChosen := math.Floor(number.Number), math.Floor(chosen.Number)
10493         if num < 0 || numChosen < 0 {
10494                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10495         }
10496         return newNumberFormulaArg(math.Pow(num, numChosen))
10497 }
10498
10499 // PHI function returns the value of the density function for a standard normal
10500 // distribution for a supplied number. The syntax of the function is:
10501 //
10502 //      PHI(x)
10503 func (fn *formulaFuncs) PHI(argsList *list.List) formulaArg {
10504         if argsList.Len() != 1 {
10505                 return newErrorFormulaArg(formulaErrorVALUE, "PHI requires 1 argument")
10506         }
10507         x := argsList.Front().Value.(formulaArg).ToNumber()
10508         if x.Type != ArgNumber {
10509                 return x
10510         }
10511         return newNumberFormulaArg(0.39894228040143268 * math.Exp(-(x.Number*x.Number)/2))
10512 }
10513
10514 // QUARTILE function returns a requested quartile of a supplied range of
10515 // values. The syntax of the function is:
10516 //
10517 //      QUARTILE(array,quart)
10518 func (fn *formulaFuncs) QUARTILE(argsList *list.List) formulaArg {
10519         if argsList.Len() != 2 {
10520                 return newErrorFormulaArg(formulaErrorVALUE, "QUARTILE requires 2 arguments")
10521         }
10522         quart := argsList.Back().Value.(formulaArg).ToNumber()
10523         if quart.Type != ArgNumber {
10524                 return quart
10525         }
10526         if quart.Number < 0 || quart.Number > 4 {
10527                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10528         }
10529         args := list.New().Init()
10530         args.PushBack(argsList.Front().Value.(formulaArg))
10531         args.PushBack(newNumberFormulaArg(quart.Number / 4))
10532         return fn.PERCENTILE(args)
10533 }
10534
10535 // QUARTILEdotEXC function returns a requested quartile of a supplied range of
10536 // values, based on a percentile range of 0 to 1 exclusive. The syntax of the
10537 // function is:
10538 //
10539 //      QUARTILE.EXC(array,quart)
10540 func (fn *formulaFuncs) QUARTILEdotEXC(argsList *list.List) formulaArg {
10541         if argsList.Len() != 2 {
10542                 return newErrorFormulaArg(formulaErrorVALUE, "QUARTILE.EXC requires 2 arguments")
10543         }
10544         quart := argsList.Back().Value.(formulaArg).ToNumber()
10545         if quart.Type != ArgNumber {
10546                 return quart
10547         }
10548         if quart.Number <= 0 || quart.Number >= 4 {
10549                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10550         }
10551         args := list.New().Init()
10552         args.PushBack(argsList.Front().Value.(formulaArg))
10553         args.PushBack(newNumberFormulaArg(quart.Number / 4))
10554         return fn.PERCENTILEdotEXC(args)
10555 }
10556
10557 // QUARTILEdotINC function returns a requested quartile of a supplied range of
10558 // values. The syntax of the function is:
10559 //
10560 //      QUARTILE.INC(array,quart)
10561 func (fn *formulaFuncs) QUARTILEdotINC(argsList *list.List) formulaArg {
10562         if argsList.Len() != 2 {
10563                 return newErrorFormulaArg(formulaErrorVALUE, "QUARTILE.INC requires 2 arguments")
10564         }
10565         return fn.QUARTILE(argsList)
10566 }
10567
10568 // rank is an implementation of the formula functions RANK and RANK.EQ.
10569 func (fn *formulaFuncs) rank(name string, argsList *list.List) formulaArg {
10570         if argsList.Len() < 2 {
10571                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 2 arguments", name))
10572         }
10573         if argsList.Len() > 3 {
10574                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at most 3 arguments", name))
10575         }
10576         num := argsList.Front().Value.(formulaArg).ToNumber()
10577         if num.Type != ArgNumber {
10578                 return num
10579         }
10580         var arr []float64
10581         for _, arg := range argsList.Front().Next().Value.(formulaArg).ToList() {
10582                 if arg.Type == ArgNumber {
10583                         arr = append(arr, arg.Number)
10584                 }
10585         }
10586         sort.Float64s(arr)
10587         order := newNumberFormulaArg(0)
10588         if argsList.Len() == 3 {
10589                 if order = argsList.Back().Value.(formulaArg).ToNumber(); order.Type != ArgNumber {
10590                         return order
10591                 }
10592         }
10593         if order.Number == 0 {
10594                 sort.Sort(sort.Reverse(sort.Float64Slice(arr)))
10595         }
10596         if idx := inFloat64Slice(arr, num.Number); idx != -1 {
10597                 return newNumberFormulaArg(float64(idx + 1))
10598         }
10599         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10600 }
10601
10602 // RANKdotEQ function returns the statistical rank of a given value, within a
10603 // supplied array of values. If there are duplicate values in the list, these
10604 // are given the same rank. The syntax of the function is:
10605 //
10606 //      RANK.EQ(number,ref,[order])
10607 func (fn *formulaFuncs) RANKdotEQ(argsList *list.List) formulaArg {
10608         return fn.rank("RANK.EQ", argsList)
10609 }
10610
10611 // RANK function returns the statistical rank of a given value, within a
10612 // supplied array of values. If there are duplicate values in the list, these
10613 // are given the same rank. The syntax of the function is:
10614 //
10615 //      RANK(number,ref,[order])
10616 func (fn *formulaFuncs) RANK(argsList *list.List) formulaArg {
10617         return fn.rank("RANK", argsList)
10618 }
10619
10620 // RSQ function calculates the square of the Pearson Product-Moment Correlation
10621 // Coefficient for two supplied sets of values. The syntax of the function
10622 // is:
10623 //
10624 //      RSQ(known_y's,known_x's)
10625 func (fn *formulaFuncs) RSQ(argsList *list.List) formulaArg {
10626         return fn.pearsonProduct("RSQ", 2, argsList)
10627 }
10628
10629 // skew is an implementation of the formula functions SKEW and SKEW.P.
10630 func (fn *formulaFuncs) skew(name string, argsList *list.List) formulaArg {
10631         if argsList.Len() < 1 {
10632                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
10633         }
10634         mean := fn.AVERAGE(argsList)
10635         var stdDev formulaArg
10636         var count, summer float64
10637         if name == "SKEW" {
10638                 stdDev = fn.STDEV(argsList)
10639         } else {
10640                 stdDev = fn.STDEVP(argsList)
10641         }
10642         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
10643                 token := arg.Value.(formulaArg)
10644                 switch token.Type {
10645                 case ArgNumber, ArgString:
10646                         num := token.ToNumber()
10647                         if num.Type == ArgError {
10648                                 return num
10649                         }
10650                         summer += math.Pow((num.Number-mean.Number)/stdDev.Number, 3)
10651                         count++
10652                 case ArgList, ArgMatrix:
10653                         for _, cell := range token.ToList() {
10654                                 if cell.Type != ArgNumber {
10655                                         continue
10656                                 }
10657                                 summer += math.Pow((cell.Number-mean.Number)/stdDev.Number, 3)
10658                                 count++
10659                         }
10660                 }
10661         }
10662         if count > 2 {
10663                 if name == "SKEW" {
10664                         return newNumberFormulaArg(summer * (count / ((count - 1) * (count - 2))))
10665                 }
10666                 return newNumberFormulaArg(summer / count)
10667         }
10668         return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
10669 }
10670
10671 // SKEW function calculates the skewness of the distribution of a supplied set
10672 // of values. The syntax of the function is:
10673 //
10674 //      SKEW(number1,[number2],...)
10675 func (fn *formulaFuncs) SKEW(argsList *list.List) formulaArg {
10676         return fn.skew("SKEW", argsList)
10677 }
10678
10679 // SKEWdotP function calculates the skewness of the distribution of a supplied
10680 // set of values. The syntax of the function is:
10681 //
10682 //      SKEW.P(number1,[number2],...)
10683 func (fn *formulaFuncs) SKEWdotP(argsList *list.List) formulaArg {
10684         return fn.skew("SKEW.P", argsList)
10685 }
10686
10687 // SLOPE returns the slope of the linear regression line through data points in
10688 // known_y's and known_x's. The slope is the vertical distance divided by the
10689 // horizontal distance between any two points on the line, which is the rate
10690 // of change along the regression line. The syntax of the function is:
10691 //
10692 //      SLOPE(known_y's,known_x's)
10693 func (fn *formulaFuncs) SLOPE(argsList *list.List) formulaArg {
10694         return fn.pearsonProduct("SLOPE", 2, argsList)
10695 }
10696
10697 // SMALL function returns the k'th smallest value from an array of numeric
10698 // values. The syntax of the function is:
10699 //
10700 //      SMALL(array,k)
10701 func (fn *formulaFuncs) SMALL(argsList *list.List) formulaArg {
10702         return fn.kth("SMALL", argsList)
10703 }
10704
10705 // STANDARDIZE function returns a normalized value of a distribution that is
10706 // characterized by a supplied mean and standard deviation. The syntax of the
10707 // function is:
10708 //
10709 //      STANDARDIZE(x,mean,standard_dev)
10710 func (fn *formulaFuncs) STANDARDIZE(argsList *list.List) formulaArg {
10711         if argsList.Len() != 3 {
10712                 return newErrorFormulaArg(formulaErrorVALUE, "STANDARDIZE requires 3 arguments")
10713         }
10714         x := argsList.Front().Value.(formulaArg).ToNumber()
10715         if x.Type != ArgNumber {
10716                 return x
10717         }
10718         mean := argsList.Front().Next().Value.(formulaArg).ToNumber()
10719         if mean.Type != ArgNumber {
10720                 return mean
10721         }
10722         stdDev := argsList.Back().Value.(formulaArg).ToNumber()
10723         if stdDev.Type != ArgNumber {
10724                 return stdDev
10725         }
10726         if stdDev.Number <= 0 {
10727                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10728         }
10729         return newNumberFormulaArg((x.Number - mean.Number) / stdDev.Number)
10730 }
10731
10732 // stdevp is an implementation of the formula functions STDEVP, STDEV.P and
10733 // STDEVPA.
10734 func (fn *formulaFuncs) stdevp(name string, argsList *list.List) formulaArg {
10735         if argsList.Len() < 1 {
10736                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
10737         }
10738         fnName := "VARP"
10739         if name == "STDEVPA" {
10740                 fnName = "VARPA"
10741         }
10742         varp := fn.vars(fnName, argsList)
10743         if varp.Type != ArgNumber {
10744                 return varp
10745         }
10746         return newNumberFormulaArg(math.Sqrt(varp.Number))
10747 }
10748
10749 // STDEVP function calculates the standard deviation of a supplied set of
10750 // values. The syntax of the function is:
10751 //
10752 //      STDEVP(number1,[number2],...)
10753 func (fn *formulaFuncs) STDEVP(argsList *list.List) formulaArg {
10754         return fn.stdevp("STDEVP", argsList)
10755 }
10756
10757 // STDEVdotP function calculates the standard deviation of a supplied set of
10758 // values.
10759 //
10760 //      STDEV.P( number1, [number2], ... )
10761 func (fn *formulaFuncs) STDEVdotP(argsList *list.List) formulaArg {
10762         return fn.stdevp("STDEV.P", argsList)
10763 }
10764
10765 // STDEVPA function calculates the standard deviation of a supplied set of
10766 // values. The syntax of the function is:
10767 //
10768 //      STDEVPA(number1,[number2],...)
10769 func (fn *formulaFuncs) STDEVPA(argsList *list.List) formulaArg {
10770         return fn.stdevp("STDEVPA", argsList)
10771 }
10772
10773 // STEYX function calculates the standard error for the line of best fit,
10774 // through a supplied set of x- and y- values. The syntax of the function is:
10775 //
10776 //      STEYX(known_y's,known_x's)
10777 func (fn *formulaFuncs) STEYX(argsList *list.List) formulaArg {
10778         if argsList.Len() != 2 {
10779                 return newErrorFormulaArg(formulaErrorVALUE, "STEYX requires 2 arguments")
10780         }
10781         array1 := argsList.Back().Value.(formulaArg).ToList()
10782         array2 := argsList.Front().Value.(formulaArg).ToList()
10783         if len(array1) != len(array2) {
10784                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
10785         }
10786         var count, sumX, sumY, squareX, squareY, sigmaXY float64
10787         for i := 0; i < len(array1); i++ {
10788                 num1, num2 := array1[i], array2[i]
10789                 if !(num1.Type == ArgNumber && num2.Type == ArgNumber) {
10790                         continue
10791                 }
10792                 sumX += num1.Number
10793                 sumY += num2.Number
10794                 squareX += num1.Number * num1.Number
10795                 squareY += num2.Number * num2.Number
10796                 sigmaXY += num1.Number * num2.Number
10797                 count++
10798         }
10799         if count < 3 {
10800                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
10801         }
10802         dx, dy := sumX/count, sumY/count
10803         sigma1 := squareY - 2*dy*sumY + count*dy*dy
10804         sigma2 := sigmaXY - dy*sumX - sumY*dx + count*dy*dx
10805         sigma3 := squareX - 2*dx*sumX + count*dx*dx
10806         return newNumberFormulaArg(math.Sqrt((sigma1 - (sigma2*sigma2)/sigma3) / (count - 2)))
10807 }
10808
10809 // getTDist is an implementation for the beta distribution probability density
10810 // function.
10811 func getTDist(T, fDF, nType float64) float64 {
10812         var res float64
10813         switch nType {
10814         case 1:
10815                 res = 0.5 * getBetaDist(fDF/(fDF+T*T), fDF/2, 0.5)
10816         case 2:
10817                 res = getBetaDist(fDF/(fDF+T*T), fDF/2, 0.5)
10818         case 3:
10819                 res = math.Pow(1+(T*T/fDF), -(fDF+1)/2) / (math.Sqrt(fDF) * getBeta(0.5, fDF/2.0))
10820         case 4:
10821                 X := fDF / (T*T + fDF)
10822                 R := 0.5 * getBetaDist(X, 0.5*fDF, 0.5)
10823                 res = 1 - R
10824                 if T < 0 {
10825                         res = R
10826                 }
10827         }
10828         return res
10829 }
10830
10831 // TdotDIST function calculates the one-tailed Student's T Distribution, which
10832 // is a continuous probability distribution that is frequently used for
10833 // testing hypotheses on small sample data sets. The syntax of the function
10834 // is:
10835 //
10836 //      T.DIST(x,degrees_freedom,cumulative)
10837 func (fn *formulaFuncs) TdotDIST(argsList *list.List) formulaArg {
10838         if argsList.Len() != 3 {
10839                 return newErrorFormulaArg(formulaErrorVALUE, "T.DIST requires 3 arguments")
10840         }
10841         var x, degrees, cumulative formulaArg
10842         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
10843                 return x
10844         }
10845         if degrees = argsList.Front().Next().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
10846                 return degrees
10847         }
10848         if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type != ArgNumber {
10849                 return cumulative
10850         }
10851         if cumulative.Number == 1 && degrees.Number < 1 {
10852                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10853         }
10854         if cumulative.Number == 0 {
10855                 if degrees.Number < 0 {
10856                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10857                 }
10858                 if degrees.Number == 0 {
10859                         return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
10860                 }
10861                 return newNumberFormulaArg(getTDist(x.Number, degrees.Number, 3))
10862         }
10863         return newNumberFormulaArg(getTDist(x.Number, degrees.Number, 4))
10864 }
10865
10866 // TdotDISTdot2T function calculates the two-tailed Student's T Distribution,
10867 // which is a continuous probability distribution that is frequently used for
10868 // testing hypotheses on small sample data sets. The syntax of the function
10869 // is:
10870 //
10871 //      T.DIST.2T(x,degrees_freedom)
10872 func (fn *formulaFuncs) TdotDISTdot2T(argsList *list.List) formulaArg {
10873         if argsList.Len() != 2 {
10874                 return newErrorFormulaArg(formulaErrorVALUE, "T.DIST.2T requires 2 arguments")
10875         }
10876         var x, degrees formulaArg
10877         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
10878                 return x
10879         }
10880         if degrees = argsList.Back().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
10881                 return degrees
10882         }
10883         if x.Number < 0 || degrees.Number < 1 {
10884                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10885         }
10886         return newNumberFormulaArg(getTDist(x.Number, degrees.Number, 2))
10887 }
10888
10889 // TdotDISTdotRT function calculates the right-tailed Student's T Distribution,
10890 // which is a continuous probability distribution that is frequently used for
10891 // testing hypotheses on small sample data sets. The syntax of the function
10892 // is:
10893 //
10894 //      T.DIST.RT(x,degrees_freedom)
10895 func (fn *formulaFuncs) TdotDISTdotRT(argsList *list.List) formulaArg {
10896         if argsList.Len() != 2 {
10897                 return newErrorFormulaArg(formulaErrorVALUE, "T.DIST.RT requires 2 arguments")
10898         }
10899         var x, degrees formulaArg
10900         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
10901                 return x
10902         }
10903         if degrees = argsList.Back().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
10904                 return degrees
10905         }
10906         if degrees.Number < 1 {
10907                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10908         }
10909         v := getTDist(x.Number, degrees.Number, 1)
10910         if x.Number < 0 {
10911                 v = 1 - v
10912         }
10913         return newNumberFormulaArg(v)
10914 }
10915
10916 // TDIST function calculates the Student's T Distribution, which is a
10917 // continuous probability distribution that is frequently used for testing
10918 // hypotheses on small sample data sets. The syntax of the function is:
10919 //
10920 //      TDIST(x,degrees_freedom,tails)
10921 func (fn *formulaFuncs) TDIST(argsList *list.List) formulaArg {
10922         if argsList.Len() != 3 {
10923                 return newErrorFormulaArg(formulaErrorVALUE, "TDIST requires 3 arguments")
10924         }
10925         var x, degrees, tails formulaArg
10926         if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
10927                 return x
10928         }
10929         if degrees = argsList.Front().Next().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
10930                 return degrees
10931         }
10932         if tails = argsList.Back().Value.(formulaArg).ToNumber(); tails.Type != ArgNumber {
10933                 return tails
10934         }
10935         if x.Number < 0 || degrees.Number < 1 || (tails.Number != 1 && tails.Number != 2) {
10936                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10937         }
10938         return newNumberFormulaArg(getTDist(x.Number, degrees.Number, tails.Number))
10939 }
10940
10941 // TdotINV function calculates the left-tailed inverse of the Student's T
10942 // Distribution, which is a continuous probability distribution that is
10943 // frequently used for testing hypotheses on small sample data sets. The
10944 // syntax of the function is:
10945 //
10946 //      T.INV(probability,degrees_freedom)
10947 func (fn *formulaFuncs) TdotINV(argsList *list.List) formulaArg {
10948         if argsList.Len() != 2 {
10949                 return newErrorFormulaArg(formulaErrorVALUE, "T.INV requires 2 arguments")
10950         }
10951         var probability, degrees formulaArg
10952         if probability = argsList.Front().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
10953                 return probability
10954         }
10955         if degrees = argsList.Back().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
10956                 return degrees
10957         }
10958         if probability.Number <= 0 || probability.Number >= 1 || degrees.Number < 1 {
10959                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10960         }
10961         if probability.Number < 0.5 {
10962                 return newNumberFormulaArg(-calcIterateInverse(calcInverseIterator{
10963                         name: "T.INV",
10964                         fp:   1 - probability.Number,
10965                         fDF:  degrees.Number,
10966                         nT:   4,
10967                 }, degrees.Number/2, degrees.Number))
10968         }
10969         return newNumberFormulaArg(calcIterateInverse(calcInverseIterator{
10970                 name: "T.INV",
10971                 fp:   probability.Number,
10972                 fDF:  degrees.Number,
10973                 nT:   4,
10974         }, degrees.Number/2, degrees.Number))
10975 }
10976
10977 // TdotINVdot2T function calculates the inverse of the two-tailed Student's T
10978 // Distribution, which is a continuous probability distribution that is
10979 // frequently used for testing hypotheses on small sample data sets. The
10980 // syntax of the function is:
10981 //
10982 //      T.INV.2T(probability,degrees_freedom)
10983 func (fn *formulaFuncs) TdotINVdot2T(argsList *list.List) formulaArg {
10984         if argsList.Len() != 2 {
10985                 return newErrorFormulaArg(formulaErrorVALUE, "T.INV.2T requires 2 arguments")
10986         }
10987         var probability, degrees formulaArg
10988         if probability = argsList.Front().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
10989                 return probability
10990         }
10991         if degrees = argsList.Back().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
10992                 return degrees
10993         }
10994         if probability.Number <= 0 || probability.Number > 1 || degrees.Number < 1 {
10995                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
10996         }
10997         return newNumberFormulaArg(calcIterateInverse(calcInverseIterator{
10998                 name: "T.INV.2T",
10999                 fp:   probability.Number,
11000                 fDF:  degrees.Number,
11001                 nT:   2,
11002         }, degrees.Number/2, degrees.Number))
11003 }
11004
11005 // TINV function calculates the inverse of the two-tailed Student's T
11006 // Distribution, which is a continuous probability distribution that is
11007 // frequently used for testing hypotheses on small sample data sets. The
11008 // syntax of the function is:
11009 //
11010 //      TINV(probability,degrees_freedom)
11011 func (fn *formulaFuncs) TINV(argsList *list.List) formulaArg {
11012         if argsList.Len() != 2 {
11013                 return newErrorFormulaArg(formulaErrorVALUE, "TINV requires 2 arguments")
11014         }
11015         return fn.TdotINVdot2T(argsList)
11016 }
11017
11018 // TREND function calculates the linear trend line through a given set of
11019 // y-values and (optionally), a given set of x-values. The function then
11020 // extends the linear trendline to calculate additional y-values for a further
11021 // supplied set of new x-values. The syntax of the function is:
11022 //
11023 //      TREND(known_y's,[known_x's],[new_x's],[const])
11024 func (fn *formulaFuncs) TREND(argsList *list.List) formulaArg {
11025         return fn.trendGrowth("TREND", argsList)
11026 }
11027
11028 // tTest calculates the probability associated with the Student's T Test.
11029 func tTest(bTemplin bool, mtx1, mtx2 [][]formulaArg, c1, c2, r1, r2 int) (float64, float64, bool) {
11030         var cnt1, cnt2, sum1, sumSqr1, sum2, sumSqr2 float64
11031         var fVal formulaArg
11032         for i := 0; i < c1; i++ {
11033                 for j := 0; j < r1; j++ {
11034                         if fVal = mtx1[i][j]; fVal.Type == ArgNumber {
11035                                 sum1 += fVal.Number
11036                                 sumSqr1 += fVal.Number * fVal.Number
11037                                 cnt1++
11038                         }
11039                 }
11040         }
11041         for i := 0; i < c2; i++ {
11042                 for j := 0; j < r2; j++ {
11043                         if fVal = mtx2[i][j]; fVal.Type == ArgNumber {
11044                                 sum2 += fVal.Number
11045                                 sumSqr2 += fVal.Number * fVal.Number
11046                                 cnt2++
11047                         }
11048                 }
11049         }
11050         if cnt1 < 2.0 || cnt2 < 2.0 {
11051                 return 0, 0, false
11052         }
11053         if bTemplin {
11054                 fS1 := (sumSqr1 - sum1*sum1/cnt1) / (cnt1 - 1) / cnt1
11055                 fS2 := (sumSqr2 - sum2*sum2/cnt2) / (cnt2 - 1) / cnt2
11056                 if fS1+fS2 == 0 {
11057                         return 0, 0, false
11058                 }
11059                 c := fS1 / (fS1 + fS2)
11060                 return math.Abs(sum1/cnt1-sum2/cnt2) / math.Sqrt(fS1+fS2), 1 / (c*c/(cnt1-1) + (1-c)*(1-c)/(cnt2-1)), true
11061         }
11062         fS1 := (sumSqr1 - sum1*sum1/cnt1) / (cnt1 - 1)
11063         fS2 := (sumSqr2 - sum2*sum2/cnt2) / (cnt2 - 1)
11064         return math.Abs(sum1/cnt1-sum2/cnt2) / math.Sqrt((cnt1-1)*fS1+(cnt2-1)*fS2) * math.Sqrt(cnt1*cnt2*(cnt1+cnt2-2)/(cnt1+cnt2)), cnt1 + cnt2 - 2, true
11065 }
11066
11067 // tTest is an implementation of the formula function TTEST.
11068 func (fn *formulaFuncs) tTest(mtx1, mtx2 [][]formulaArg, fTails, fTyp float64) formulaArg {
11069         var fT, fF float64
11070         c1, c2, r1, r2, ok := len(mtx1), len(mtx2), len(mtx1[0]), len(mtx2[0]), true
11071         if fTyp == 1 {
11072                 if c1 != c2 || r1 != r2 {
11073                         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11074                 }
11075                 var cnt, sum1, sum2, sumSqrD float64
11076                 var fVal1, fVal2 formulaArg
11077                 for i := 0; i < c1; i++ {
11078                         for j := 0; j < r1; j++ {
11079                                 fVal1, fVal2 = mtx1[i][j], mtx2[i][j]
11080                                 if fVal1.Type != ArgNumber || fVal2.Type != ArgNumber {
11081                                         continue
11082                                 }
11083                                 sum1 += fVal1.Number
11084                                 sum2 += fVal2.Number
11085                                 sumSqrD += (fVal1.Number - fVal2.Number) * (fVal1.Number - fVal2.Number)
11086                                 cnt++
11087                         }
11088                 }
11089                 if cnt < 1 {
11090                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
11091                 }
11092                 sumD := sum1 - sum2
11093                 divider := cnt*sumSqrD - sumD*sumD
11094                 if divider == 0 {
11095                         return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
11096                 }
11097                 fT = math.Abs(sumD) * math.Sqrt((cnt-1)/divider)
11098                 fF = cnt - 1
11099         } else if fTyp == 2 {
11100                 fT, fF, ok = tTest(false, mtx1, mtx2, c1, c2, r1, r2)
11101         } else {
11102                 fT, fF, ok = tTest(true, mtx1, mtx2, c1, c2, r1, r2)
11103         }
11104         if !ok {
11105                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
11106         }
11107         return newNumberFormulaArg(getTDist(fT, fF, fTails))
11108 }
11109
11110 // TTEST function calculates the probability associated with the Student's T
11111 // Test, which is commonly used for identifying whether two data sets are
11112 // likely to have come from the same two underlying populations with the same
11113 // mean. The syntax of the function is:
11114 //
11115 //      TTEST(array1,array2,tails,type)
11116 func (fn *formulaFuncs) TTEST(argsList *list.List) formulaArg {
11117         if argsList.Len() != 4 {
11118                 return newErrorFormulaArg(formulaErrorVALUE, "TTEST requires 4 arguments")
11119         }
11120         var array1, array2, tails, typeArg formulaArg
11121         array1 = argsList.Front().Value.(formulaArg)
11122         array2 = argsList.Front().Next().Value.(formulaArg)
11123         if tails = argsList.Front().Next().Next().Value.(formulaArg); tails.Type != ArgNumber {
11124                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11125         }
11126         if typeArg = argsList.Back().Value.(formulaArg); typeArg.Type != ArgNumber {
11127                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11128         }
11129         if len(array1.Matrix) == 0 || len(array2.Matrix) == 0 {
11130                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
11131         }
11132         if tails.Number != 1 && tails.Number != 2 {
11133                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
11134         }
11135         if typeArg.Number != 1 && typeArg.Number != 2 && typeArg.Number != 3 {
11136                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
11137         }
11138         return fn.tTest(array1.Matrix, array2.Matrix, tails.Number, typeArg.Number)
11139 }
11140
11141 // TdotTEST function calculates the probability associated with the Student's T
11142 // Test, which is commonly used for identifying whether two data sets are
11143 // likely to have come from the same two underlying populations with the same
11144 // mean. The syntax of the function is:
11145 //
11146 //      T.TEST(array1,array2,tails,type)
11147 func (fn *formulaFuncs) TdotTEST(argsList *list.List) formulaArg {
11148         if argsList.Len() != 4 {
11149                 return newErrorFormulaArg(formulaErrorVALUE, "T.TEST requires 4 arguments")
11150         }
11151         return fn.TTEST(argsList)
11152 }
11153
11154 // TRIMMEAN function calculates the trimmed mean (or truncated mean) of a
11155 // supplied set of values. The syntax of the function is:
11156 //
11157 //      TRIMMEAN(array,percent)
11158 func (fn *formulaFuncs) TRIMMEAN(argsList *list.List) formulaArg {
11159         if argsList.Len() != 2 {
11160                 return newErrorFormulaArg(formulaErrorVALUE, "TRIMMEAN requires 2 arguments")
11161         }
11162         percent := argsList.Back().Value.(formulaArg).ToNumber()
11163         if percent.Type != ArgNumber {
11164                 return percent
11165         }
11166         if percent.Number < 0 || percent.Number >= 1 {
11167                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
11168         }
11169         var arr []float64
11170         arrArg := argsList.Front().Value.(formulaArg).ToList()
11171         for _, cell := range arrArg {
11172                 if cell.Type != ArgNumber {
11173                         continue
11174                 }
11175                 arr = append(arr, cell.Number)
11176         }
11177         discard := math.Floor(float64(len(arr)) * percent.Number / 2)
11178         sort.Float64s(arr)
11179         for i := 0; i < int(discard); i++ {
11180                 if len(arr) > 0 {
11181                         arr = arr[1:]
11182                 }
11183                 if len(arr) > 0 {
11184                         arr = arr[:len(arr)-1]
11185                 }
11186         }
11187
11188         args := list.New().Init()
11189         for _, ele := range arr {
11190                 args.PushBack(newNumberFormulaArg(ele))
11191         }
11192         return fn.AVERAGE(args)
11193 }
11194
11195 // vars is an implementation of the formula functions VAR, VARA, VARP, VAR.P
11196 // VAR.S and VARPA.
11197 func (fn *formulaFuncs) vars(name string, argsList *list.List) formulaArg {
11198         if argsList.Len() < 1 {
11199                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
11200         }
11201         summerA, summerB, count := 0.0, 0.0, 0.0
11202         minimum := 0.0
11203         if name == "VAR" || name == "VAR.S" || name == "VARA" {
11204                 minimum = 1.0
11205         }
11206         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
11207                 for _, token := range arg.Value.(formulaArg).ToList() {
11208                         if token.Value() == "" {
11209                                 continue
11210                         }
11211                         num := token.ToNumber()
11212                         if token.Value() != "TRUE" && num.Type == ArgNumber {
11213                                 summerA += num.Number * num.Number
11214                                 summerB += num.Number
11215                                 count++
11216                                 continue
11217                         }
11218                         num = token.ToBool()
11219                         if num.Type == ArgNumber {
11220                                 summerA += num.Number * num.Number
11221                                 summerB += num.Number
11222                                 count++
11223                                 continue
11224                         }
11225                         if name == "VARA" || name == "VARPA" {
11226                                 count++
11227                         }
11228                 }
11229         }
11230         if count > minimum {
11231                 summerA *= count
11232                 summerB *= summerB
11233                 return newNumberFormulaArg((summerA - summerB) / (count * (count - minimum)))
11234         }
11235         return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
11236 }
11237
11238 // VAR function returns the sample variance of a supplied set of values. The
11239 // syntax of the function is:
11240 //
11241 //      VAR(number1,[number2],...)
11242 func (fn *formulaFuncs) VAR(argsList *list.List) formulaArg {
11243         return fn.vars("VAR", argsList)
11244 }
11245
11246 // VARA function calculates the sample variance of a supplied set of values.
11247 // The syntax of the function is:
11248 //
11249 //      VARA(number1,[number2],...)
11250 func (fn *formulaFuncs) VARA(argsList *list.List) formulaArg {
11251         return fn.vars("VARA", argsList)
11252 }
11253
11254 // VARP function returns the Variance of a given set of values. The syntax of
11255 // the function is:
11256 //
11257 //      VARP(number1,[number2],...)
11258 func (fn *formulaFuncs) VARP(argsList *list.List) formulaArg {
11259         return fn.vars("VARP", argsList)
11260 }
11261
11262 // VARdotP function returns the Variance of a given set of values. The syntax
11263 // of the function is:
11264 //
11265 //      VAR.P(number1,[number2],...)
11266 func (fn *formulaFuncs) VARdotP(argsList *list.List) formulaArg {
11267         return fn.vars("VAR.P", argsList)
11268 }
11269
11270 // VARdotS function calculates the sample variance of a supplied set of
11271 // values. The syntax of the function is:
11272 //
11273 //      VAR.S(number1,[number2],...)
11274 func (fn *formulaFuncs) VARdotS(argsList *list.List) formulaArg {
11275         return fn.vars("VAR.S", argsList)
11276 }
11277
11278 // VARPA function returns the Variance of a given set of values. The syntax of
11279 // the function is:
11280 //
11281 //      VARPA(number1,[number2],...)
11282 func (fn *formulaFuncs) VARPA(argsList *list.List) formulaArg {
11283         return fn.vars("VARPA", argsList)
11284 }
11285
11286 // WEIBULL function calculates the Weibull Probability Density Function or the
11287 // Weibull Cumulative Distribution Function for a supplied set of parameters.
11288 // The syntax of the function is:
11289 //
11290 //      WEIBULL(x,alpha,beta,cumulative)
11291 func (fn *formulaFuncs) WEIBULL(argsList *list.List) formulaArg {
11292         if argsList.Len() != 4 {
11293                 return newErrorFormulaArg(formulaErrorVALUE, "WEIBULL requires 4 arguments")
11294         }
11295         x := argsList.Front().Value.(formulaArg).ToNumber()
11296         alpha := argsList.Front().Next().Value.(formulaArg).ToNumber()
11297         beta := argsList.Back().Prev().Value.(formulaArg).ToNumber()
11298         if alpha.Type == ArgNumber && beta.Type == ArgNumber && x.Type == ArgNumber {
11299                 if alpha.Number < 0 || alpha.Number <= 0 || beta.Number <= 0 {
11300                         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11301                 }
11302                 cumulative := argsList.Back().Value.(formulaArg).ToBool()
11303                 if cumulative.Boolean && cumulative.Number == 1 {
11304                         return newNumberFormulaArg(1 - math.Exp(0-math.Pow(x.Number/beta.Number, alpha.Number)))
11305                 }
11306                 return newNumberFormulaArg((alpha.Number / math.Pow(beta.Number, alpha.Number)) *
11307                         math.Pow(x.Number, alpha.Number-1) * math.Exp(0-math.Pow(x.Number/beta.Number, alpha.Number)))
11308         }
11309         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11310 }
11311
11312 // WEIBULLdotDIST function calculates the Weibull Probability Density Function
11313 // or the Weibull Cumulative Distribution Function for a supplied set of
11314 // parameters. The syntax of the function is:
11315 //
11316 //      WEIBULL.DIST(x,alpha,beta,cumulative)
11317 func (fn *formulaFuncs) WEIBULLdotDIST(argsList *list.List) formulaArg {
11318         if argsList.Len() != 4 {
11319                 return newErrorFormulaArg(formulaErrorVALUE, "WEIBULL.DIST requires 4 arguments")
11320         }
11321         return fn.WEIBULL(argsList)
11322 }
11323
11324 // ZdotTEST function calculates the one-tailed probability value of the
11325 // Z-Test. The syntax of the function is:
11326 //
11327 //      Z.TEST(array,x,[sigma])
11328 func (fn *formulaFuncs) ZdotTEST(argsList *list.List) formulaArg {
11329         argsLen := argsList.Len()
11330         if argsLen < 2 {
11331                 return newErrorFormulaArg(formulaErrorVALUE, "Z.TEST requires at least 2 arguments")
11332         }
11333         if argsLen > 3 {
11334                 return newErrorFormulaArg(formulaErrorVALUE, "Z.TEST accepts at most 3 arguments")
11335         }
11336         return fn.ZTEST(argsList)
11337 }
11338
11339 // ZTEST function calculates the one-tailed probability value of the Z-Test.
11340 // The syntax of the function is:
11341 //
11342 //      ZTEST(array,x,[sigma])
11343 func (fn *formulaFuncs) ZTEST(argsList *list.List) formulaArg {
11344         argsLen := argsList.Len()
11345         if argsLen < 2 {
11346                 return newErrorFormulaArg(formulaErrorVALUE, "ZTEST requires at least 2 arguments")
11347         }
11348         if argsLen > 3 {
11349                 return newErrorFormulaArg(formulaErrorVALUE, "ZTEST accepts at most 3 arguments")
11350         }
11351         arrArg, arrArgs := argsList.Front().Value.(formulaArg), list.New()
11352         arrArgs.PushBack(arrArg)
11353         arr := fn.AVERAGE(arrArgs)
11354         if arr.Type == ArgError {
11355                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11356         }
11357         x := argsList.Front().Next().Value.(formulaArg).ToNumber()
11358         if x.Type == ArgError {
11359                 return x
11360         }
11361         sigma := argsList.Back().Value.(formulaArg).ToNumber()
11362         if sigma.Type == ArgError {
11363                 return sigma
11364         }
11365         if argsLen != 3 {
11366                 sigma = fn.STDEV(arrArgs).ToNumber()
11367         }
11368         normsdistArg := list.New()
11369         div := sigma.Number / math.Sqrt(float64(len(arrArg.ToList())))
11370         if div == 0 {
11371                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
11372         }
11373         normsdistArg.PushBack(newNumberFormulaArg((arr.Number - x.Number) / div))
11374         return newNumberFormulaArg(1 - fn.NORMSDIST(normsdistArg).Number)
11375 }
11376
11377 // Information Functions
11378
11379 // ERRORdotTYPE function receives an error value and returns an integer, that
11380 // tells you the type of the supplied error. The syntax of the function is:
11381 //
11382 //      ERROR.TYPE(error_val)
11383 func (fn *formulaFuncs) ERRORdotTYPE(argsList *list.List) formulaArg {
11384         if argsList.Len() != 1 {
11385                 return newErrorFormulaArg(formulaErrorVALUE, "ERROR.TYPE requires 1 argument")
11386         }
11387         token := argsList.Front().Value.(formulaArg)
11388         if token.Type == ArgError {
11389                 for i, errType := range []string{
11390                         formulaErrorNULL, formulaErrorDIV, formulaErrorVALUE, formulaErrorREF,
11391                         formulaErrorNAME, formulaErrorNUM, formulaErrorNA,
11392                 } {
11393                         if errType == token.String {
11394                                 return newNumberFormulaArg(float64(i) + 1)
11395                         }
11396                 }
11397         }
11398         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11399 }
11400
11401 // ISBLANK function tests if a specified cell is blank (empty) and if so,
11402 // returns TRUE; Otherwise the function returns FALSE. The syntax of the
11403 // function is:
11404 //
11405 //      ISBLANK(value)
11406 func (fn *formulaFuncs) ISBLANK(argsList *list.List) formulaArg {
11407         if argsList.Len() != 1 {
11408                 return newErrorFormulaArg(formulaErrorVALUE, "ISBLANK requires 1 argument")
11409         }
11410         token := argsList.Front().Value.(formulaArg)
11411         switch token.Type {
11412         case ArgUnknown, ArgEmpty:
11413                 return newBoolFormulaArg(true)
11414         default:
11415                 return newBoolFormulaArg(false)
11416         }
11417 }
11418
11419 // ISERR function tests if an initial supplied expression (or value) returns
11420 // any Excel Error, except the #N/A error. If so, the function returns the
11421 // logical value TRUE; If the supplied value is not an error or is the #N/A
11422 // error, the ISERR function returns FALSE. The syntax of the function is:
11423 //
11424 //      ISERR(value)
11425 func (fn *formulaFuncs) ISERR(argsList *list.List) formulaArg {
11426         if argsList.Len() != 1 {
11427                 return newErrorFormulaArg(formulaErrorVALUE, "ISERR requires 1 argument")
11428         }
11429         token := argsList.Front().Value.(formulaArg)
11430         result := false
11431         if token.Type == ArgError {
11432                 for _, errType := range []string{
11433                         formulaErrorDIV, formulaErrorNAME, formulaErrorNUM,
11434                         formulaErrorVALUE, formulaErrorREF, formulaErrorNULL,
11435                         formulaErrorSPILL, formulaErrorCALC, formulaErrorGETTINGDATA,
11436                 } {
11437                         if errType == token.String {
11438                                 result = true
11439                         }
11440                 }
11441         }
11442         return newBoolFormulaArg(result)
11443 }
11444
11445 // ISERROR function tests if an initial supplied expression (or value) returns
11446 // an Excel Error, and if so, returns the logical value TRUE; Otherwise the
11447 // function returns FALSE. The syntax of the function is:
11448 //
11449 //      ISERROR(value)
11450 func (fn *formulaFuncs) ISERROR(argsList *list.List) formulaArg {
11451         if argsList.Len() != 1 {
11452                 return newErrorFormulaArg(formulaErrorVALUE, "ISERROR requires 1 argument")
11453         }
11454         token := argsList.Front().Value.(formulaArg)
11455         result := false
11456         if token.Type == ArgError {
11457                 for _, errType := range []string{
11458                         formulaErrorDIV, formulaErrorNAME, formulaErrorNA, formulaErrorNUM,
11459                         formulaErrorVALUE, formulaErrorREF, formulaErrorNULL, formulaErrorSPILL,
11460                         formulaErrorCALC, formulaErrorGETTINGDATA,
11461                 } {
11462                         if errType == token.String {
11463                                 result = true
11464                         }
11465                 }
11466         }
11467         return newBoolFormulaArg(result)
11468 }
11469
11470 // ISEVEN function tests if a supplied number (or numeric expression)
11471 // evaluates to an even number, and if so, returns TRUE; Otherwise, the
11472 // function returns FALSE. The syntax of the function is:
11473 //
11474 //      ISEVEN(value)
11475 func (fn *formulaFuncs) ISEVEN(argsList *list.List) formulaArg {
11476         if argsList.Len() != 1 {
11477                 return newErrorFormulaArg(formulaErrorVALUE, "ISEVEN requires 1 argument")
11478         }
11479         token := argsList.Front().Value.(formulaArg)
11480         switch token.Type {
11481         case ArgEmpty:
11482                 return newBoolFormulaArg(true)
11483         case ArgNumber, ArgString:
11484                 num := token.ToNumber()
11485                 if num.Type != ArgNumber {
11486                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11487                 }
11488                 if num.Number == 1 {
11489                         return newBoolFormulaArg(false)
11490                 }
11491                 return newBoolFormulaArg(num.Number == num.Number/2*2)
11492         default:
11493                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11494         }
11495 }
11496
11497 // ISFORMULA function tests if a specified cell contains a formula, and if so,
11498 // returns TRUE; Otherwise, the function returns FALSE. The syntax of the
11499 // function is:
11500 //
11501 //      ISFORMULA(reference)
11502 func (fn *formulaFuncs) ISFORMULA(argsList *list.List) formulaArg {
11503         if argsList.Len() != 1 {
11504                 return newErrorFormulaArg(formulaErrorVALUE, "ISFORMULA requires 1 argument")
11505         }
11506         arg := argsList.Front().Value.(formulaArg)
11507         if arg.cellRefs != nil && arg.cellRefs.Len() == 1 {
11508                 ref := arg.cellRefs.Front().Value.(cellRef)
11509                 cell, _ := CoordinatesToCellName(ref.Col, ref.Row)
11510                 if formula, _ := fn.f.GetCellFormula(ref.Sheet, cell); len(formula) > 0 {
11511                         return newBoolFormulaArg(true)
11512                 }
11513         }
11514         return newBoolFormulaArg(false)
11515 }
11516
11517 // ISLOGICAL function tests if a supplied value (or expression) returns a
11518 // logical value (i.e. evaluates to True or False). If so, the function
11519 // returns TRUE; Otherwise, it returns FALSE. The syntax of the function is:
11520 //
11521 //      ISLOGICAL(value)
11522 func (fn *formulaFuncs) ISLOGICAL(argsList *list.List) formulaArg {
11523         if argsList.Len() != 1 {
11524                 return newErrorFormulaArg(formulaErrorVALUE, "ISLOGICAL requires 1 argument")
11525         }
11526         val := argsList.Front().Value.(formulaArg).Value()
11527         if strings.EqualFold("TRUE", val) || strings.EqualFold("FALSE", val) {
11528                 return newBoolFormulaArg(true)
11529         }
11530         return newBoolFormulaArg(false)
11531 }
11532
11533 // ISNA function tests if an initial supplied expression (or value) returns
11534 // the Excel #N/A Error, and if so, returns TRUE; Otherwise the function
11535 // returns FALSE. The syntax of the function is:
11536 //
11537 //      ISNA(value)
11538 func (fn *formulaFuncs) ISNA(argsList *list.List) formulaArg {
11539         if argsList.Len() != 1 {
11540                 return newErrorFormulaArg(formulaErrorVALUE, "ISNA requires 1 argument")
11541         }
11542         token := argsList.Front().Value.(formulaArg)
11543         result := "FALSE"
11544         if token.Type == ArgError && token.String == formulaErrorNA {
11545                 result = "TRUE"
11546         }
11547         return newStringFormulaArg(result)
11548 }
11549
11550 // ISNONTEXT function tests if a supplied value is text. If not, the
11551 // function returns TRUE; If the supplied value is text, the function returns
11552 // FALSE. The syntax of the function is:
11553 //
11554 //      ISNONTEXT(value)
11555 func (fn *formulaFuncs) ISNONTEXT(argsList *list.List) formulaArg {
11556         if argsList.Len() != 1 {
11557                 return newErrorFormulaArg(formulaErrorVALUE, "ISNONTEXT requires 1 argument")
11558         }
11559         if argsList.Front().Value.(formulaArg).Type == ArgString {
11560                 return newBoolFormulaArg(false)
11561         }
11562         return newBoolFormulaArg(true)
11563 }
11564
11565 // ISNUMBER function tests if a supplied value is a number. If so,
11566 // the function returns TRUE; Otherwise it returns FALSE. The syntax of the
11567 // function is:
11568 //
11569 //      ISNUMBER(value)
11570 func (fn *formulaFuncs) ISNUMBER(argsList *list.List) formulaArg {
11571         if argsList.Len() != 1 {
11572                 return newErrorFormulaArg(formulaErrorVALUE, "ISNUMBER requires 1 argument")
11573         }
11574         if argsList.Front().Value.(formulaArg).Type == ArgNumber {
11575                 return newBoolFormulaArg(true)
11576         }
11577         return newBoolFormulaArg(false)
11578 }
11579
11580 // ISODD function tests if a supplied number (or numeric expression) evaluates
11581 // to an odd number, and if so, returns TRUE; Otherwise, the function returns
11582 // FALSE. The syntax of the function is:
11583 //
11584 //      ISODD(value)
11585 func (fn *formulaFuncs) ISODD(argsList *list.List) formulaArg {
11586         if argsList.Len() != 1 {
11587                 return newErrorFormulaArg(formulaErrorVALUE, "ISODD requires 1 argument")
11588         }
11589         arg := argsList.Front().Value.(formulaArg).ToNumber()
11590         if arg.Type != ArgNumber {
11591                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11592         }
11593         if int(arg.Number) != int(arg.Number)/2*2 {
11594                 return newBoolFormulaArg(true)
11595         }
11596         return newBoolFormulaArg(false)
11597 }
11598
11599 // ISREF function tests if a supplied value is a reference. If so, the
11600 // function returns TRUE; Otherwise it returns FALSE. The syntax of the
11601 // function is:
11602 //
11603 //      ISREF(value)
11604 func (fn *formulaFuncs) ISREF(argsList *list.List) formulaArg {
11605         if argsList.Len() != 1 {
11606                 return newErrorFormulaArg(formulaErrorVALUE, "ISREF requires 1 argument")
11607         }
11608         arg := argsList.Front().Value.(formulaArg)
11609         if arg.cellRanges != nil && arg.cellRanges.Len() > 0 || arg.cellRefs != nil && arg.cellRefs.Len() > 0 {
11610                 return newBoolFormulaArg(true)
11611         }
11612         return newBoolFormulaArg(false)
11613 }
11614
11615 // ISTEXT function tests if a supplied value is text, and if so, returns TRUE;
11616 // Otherwise, the function returns FALSE. The syntax of the function is:
11617 //
11618 //      ISTEXT(value)
11619 func (fn *formulaFuncs) ISTEXT(argsList *list.List) formulaArg {
11620         if argsList.Len() != 1 {
11621                 return newErrorFormulaArg(formulaErrorVALUE, "ISTEXT requires 1 argument")
11622         }
11623         token := argsList.Front().Value.(formulaArg)
11624         if token.ToNumber().Type != ArgError {
11625                 return newBoolFormulaArg(false)
11626         }
11627         return newBoolFormulaArg(token.Type == ArgString)
11628 }
11629
11630 // N function converts data into a numeric value. The syntax of the function
11631 // is:
11632 //
11633 //      N(value)
11634 func (fn *formulaFuncs) N(argsList *list.List) formulaArg {
11635         if argsList.Len() != 1 {
11636                 return newErrorFormulaArg(formulaErrorVALUE, "N requires 1 argument")
11637         }
11638         token, num := argsList.Front().Value.(formulaArg), 0.0
11639         if token.Type == ArgError {
11640                 return token
11641         }
11642         if arg := token.ToNumber(); arg.Type == ArgNumber {
11643                 num = arg.Number
11644         }
11645         if token.Value() == "TRUE" {
11646                 num = 1
11647         }
11648         return newNumberFormulaArg(num)
11649 }
11650
11651 // NA function returns the Excel #N/A error. This error message has the
11652 // meaning 'value not available' and is produced when an Excel Formula is
11653 // unable to find a value that it needs. The syntax of the function is:
11654 //
11655 //      NA()
11656 func (fn *formulaFuncs) NA(argsList *list.List) formulaArg {
11657         if argsList.Len() != 0 {
11658                 return newErrorFormulaArg(formulaErrorVALUE, "NA accepts no arguments")
11659         }
11660         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11661 }
11662
11663 // SHEET function returns the Sheet number for a specified reference. The
11664 // syntax of the function is:
11665 //
11666 //      SHEET([value])
11667 func (fn *formulaFuncs) SHEET(argsList *list.List) formulaArg {
11668         if argsList.Len() > 1 {
11669                 return newErrorFormulaArg(formulaErrorVALUE, "SHEET accepts at most 1 argument")
11670         }
11671         if argsList.Len() == 0 {
11672                 idx, _ := fn.f.GetSheetIndex(fn.sheet)
11673                 return newNumberFormulaArg(float64(idx + 1))
11674         }
11675         arg := argsList.Front().Value.(formulaArg)
11676         if sheetIdx, _ := fn.f.GetSheetIndex(arg.Value()); sheetIdx != -1 {
11677                 return newNumberFormulaArg(float64(sheetIdx + 1))
11678         }
11679         if arg.cellRanges != nil && arg.cellRanges.Len() > 0 {
11680                 if sheetIdx, _ := fn.f.GetSheetIndex(arg.cellRanges.Front().Value.(cellRange).From.Sheet); sheetIdx != -1 {
11681                         return newNumberFormulaArg(float64(sheetIdx + 1))
11682                 }
11683         }
11684         if arg.cellRefs != nil && arg.cellRefs.Len() > 0 {
11685                 if sheetIdx, _ := fn.f.GetSheetIndex(arg.cellRefs.Front().Value.(cellRef).Sheet); sheetIdx != -1 {
11686                         return newNumberFormulaArg(float64(sheetIdx + 1))
11687                 }
11688         }
11689         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11690 }
11691
11692 // SHEETS function returns the number of sheets in a supplied reference. The
11693 // result includes sheets that are Visible, Hidden or Very Hidden. The syntax
11694 // of the function is:
11695 //
11696 //      SHEETS([reference])
11697 func (fn *formulaFuncs) SHEETS(argsList *list.List) formulaArg {
11698         if argsList.Len() > 1 {
11699                 return newErrorFormulaArg(formulaErrorVALUE, "SHEETS accepts at most 1 argument")
11700         }
11701         if argsList.Len() == 0 {
11702                 return newNumberFormulaArg(float64(len(fn.f.GetSheetList())))
11703         }
11704         arg := argsList.Front().Value.(formulaArg)
11705         sheetMap := map[string]struct{}{}
11706         if arg.cellRanges != nil && arg.cellRanges.Len() > 0 {
11707                 for rng := arg.cellRanges.Front(); rng != nil; rng = rng.Next() {
11708                         sheetMap[rng.Value.(cellRange).From.Sheet] = struct{}{}
11709                 }
11710         }
11711         if arg.cellRefs != nil && arg.cellRefs.Len() > 0 {
11712                 for ref := arg.cellRefs.Front(); ref != nil; ref = ref.Next() {
11713                         sheetMap[ref.Value.(cellRef).Sheet] = struct{}{}
11714                 }
11715         }
11716         if len(sheetMap) > 0 {
11717                 return newNumberFormulaArg(float64(len(sheetMap)))
11718         }
11719         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11720 }
11721
11722 // TYPE function returns an integer that represents the value's data type. The
11723 // syntax of the function is:
11724 //
11725 //      TYPE(value)
11726 func (fn *formulaFuncs) TYPE(argsList *list.List) formulaArg {
11727         if argsList.Len() != 1 {
11728                 return newErrorFormulaArg(formulaErrorVALUE, "TYPE requires 1 argument")
11729         }
11730         token := argsList.Front().Value.(formulaArg)
11731         switch token.Type {
11732         case ArgError:
11733                 return newNumberFormulaArg(16)
11734         case ArgMatrix:
11735                 return newNumberFormulaArg(64)
11736         case ArgNumber, ArgEmpty:
11737                 if token.Boolean {
11738                         return newNumberFormulaArg(4)
11739                 }
11740                 return newNumberFormulaArg(1)
11741         default:
11742                 return newNumberFormulaArg(2)
11743         }
11744 }
11745
11746 // T function tests if a supplied value is text and if so, returns the
11747 // supplied text; Otherwise, the function returns an empty text string. The
11748 // syntax of the function is:
11749 //
11750 //      T(value)
11751 func (fn *formulaFuncs) T(argsList *list.List) formulaArg {
11752         if argsList.Len() != 1 {
11753                 return newErrorFormulaArg(formulaErrorVALUE, "T requires 1 argument")
11754         }
11755         token := argsList.Front().Value.(formulaArg)
11756         if token.Type == ArgError {
11757                 return token
11758         }
11759         if token.Type == ArgNumber {
11760                 return newStringFormulaArg("")
11761         }
11762         return newStringFormulaArg(token.Value())
11763 }
11764
11765 // Logical Functions
11766
11767 // AND function tests a number of supplied conditions and returns TRUE or
11768 // FALSE. The syntax of the function is:
11769 //
11770 //      AND(logical_test1,[logical_test2],...)
11771 func (fn *formulaFuncs) AND(argsList *list.List) formulaArg {
11772         if argsList.Len() == 0 {
11773                 return newErrorFormulaArg(formulaErrorVALUE, "AND requires at least 1 argument")
11774         }
11775         if argsList.Len() > 30 {
11776                 return newErrorFormulaArg(formulaErrorVALUE, "AND accepts at most 30 arguments")
11777         }
11778         and := true
11779         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
11780                 token := arg.Value.(formulaArg)
11781                 switch token.Type {
11782                 case ArgUnknown:
11783                         continue
11784                 case ArgString:
11785                         if token.String == "TRUE" {
11786                                 continue
11787                         }
11788                         if token.String == "FALSE" {
11789                                 return newStringFormulaArg(token.String)
11790                         }
11791                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11792                 case ArgNumber:
11793                         and = and && token.Number != 0
11794                 case ArgMatrix:
11795                         // TODO
11796                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11797                 }
11798         }
11799         return newBoolFormulaArg(and)
11800 }
11801
11802 // FALSE function returns the logical value FALSE. The syntax of the
11803 // function is:
11804 //
11805 //      FALSE()
11806 func (fn *formulaFuncs) FALSE(argsList *list.List) formulaArg {
11807         if argsList.Len() != 0 {
11808                 return newErrorFormulaArg(formulaErrorVALUE, "FALSE takes no arguments")
11809         }
11810         return newBoolFormulaArg(false)
11811 }
11812
11813 // IFERROR function receives two values (or expressions) and tests if the
11814 // first of these evaluates to an error. The syntax of the function is:
11815 //
11816 //      IFERROR(value,value_if_error)
11817 func (fn *formulaFuncs) IFERROR(argsList *list.List) formulaArg {
11818         if argsList.Len() != 2 {
11819                 return newErrorFormulaArg(formulaErrorVALUE, "IFERROR requires 2 arguments")
11820         }
11821         value := argsList.Front().Value.(formulaArg)
11822         if value.Type != ArgError {
11823                 if value.Type == ArgEmpty {
11824                         return newNumberFormulaArg(0)
11825                 }
11826                 return value
11827         }
11828         return argsList.Back().Value.(formulaArg)
11829 }
11830
11831 // IFNA function tests if an initial supplied value (or expression) evaluates
11832 // to the Excel #N/A error. If so, the function returns a second supplied
11833 // value; Otherwise the function returns the first supplied value. The syntax
11834 // of the function is:
11835 //
11836 //      IFNA(value,value_if_na)
11837 func (fn *formulaFuncs) IFNA(argsList *list.List) formulaArg {
11838         if argsList.Len() != 2 {
11839                 return newErrorFormulaArg(formulaErrorVALUE, "IFNA requires 2 arguments")
11840         }
11841         arg := argsList.Front().Value.(formulaArg)
11842         if arg.Type == ArgError && arg.String == formulaErrorNA {
11843                 return argsList.Back().Value.(formulaArg)
11844         }
11845         return arg
11846 }
11847
11848 // IFS function tests a number of supplied conditions and returns the result
11849 // corresponding to the first condition that evaluates to TRUE. If none of
11850 // the supplied conditions evaluate to TRUE, the function returns the #N/A
11851 // error.
11852 //
11853 //      IFS(logical_test1,value_if_true1,[logical_test2,value_if_true2],...)
11854 func (fn *formulaFuncs) IFS(argsList *list.List) formulaArg {
11855         if argsList.Len() < 2 {
11856                 return newErrorFormulaArg(formulaErrorVALUE, "IFS requires at least 2 arguments")
11857         }
11858         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
11859                 if arg.Value.(formulaArg).ToBool().Number == 1 {
11860                         return arg.Next().Value.(formulaArg)
11861                 }
11862                 arg = arg.Next()
11863         }
11864         return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11865 }
11866
11867 // NOT function returns the opposite to a supplied logical value. The syntax
11868 // of the function is:
11869 //
11870 //      NOT(logical)
11871 func (fn *formulaFuncs) NOT(argsList *list.List) formulaArg {
11872         if argsList.Len() != 1 {
11873                 return newErrorFormulaArg(formulaErrorVALUE, "NOT requires 1 argument")
11874         }
11875         token := argsList.Front().Value.(formulaArg)
11876         switch token.Type {
11877         case ArgString, ArgList:
11878                 if strings.ToUpper(token.String) == "TRUE" {
11879                         return newBoolFormulaArg(false)
11880                 }
11881                 if strings.ToUpper(token.String) == "FALSE" {
11882                         return newBoolFormulaArg(true)
11883                 }
11884         case ArgNumber:
11885                 return newBoolFormulaArg(!(token.Number != 0))
11886         case ArgError:
11887                 return token
11888         }
11889         return newErrorFormulaArg(formulaErrorVALUE, "NOT expects 1 boolean or numeric argument")
11890 }
11891
11892 // OR function tests a number of supplied conditions and returns either TRUE
11893 // or FALSE. The syntax of the function is:
11894 //
11895 //      OR(logical_test1,[logical_test2],...)
11896 func (fn *formulaFuncs) OR(argsList *list.List) formulaArg {
11897         if argsList.Len() == 0 {
11898                 return newErrorFormulaArg(formulaErrorVALUE, "OR requires at least 1 argument")
11899         }
11900         if argsList.Len() > 30 {
11901                 return newErrorFormulaArg(formulaErrorVALUE, "OR accepts at most 30 arguments")
11902         }
11903         var or bool
11904         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
11905                 token := arg.Value.(formulaArg)
11906                 switch token.Type {
11907                 case ArgUnknown:
11908                         continue
11909                 case ArgString:
11910                         if token.String == "FALSE" {
11911                                 continue
11912                         }
11913                         if token.String == "TRUE" {
11914                                 or = true
11915                                 continue
11916                         }
11917                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11918                 case ArgNumber:
11919                         if or = token.Number != 0; or {
11920                                 return newStringFormulaArg(strings.ToUpper(strconv.FormatBool(or)))
11921                         }
11922                 case ArgMatrix:
11923                         // TODO
11924                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
11925                 }
11926         }
11927         return newStringFormulaArg(strings.ToUpper(strconv.FormatBool(or)))
11928 }
11929
11930 // SWITCH function compares a number of supplied values to a supplied test
11931 // expression and returns a result corresponding to the first value that
11932 // matches the test expression. A default value can be supplied, to be
11933 // returned if none of the supplied values match the test expression. The
11934 // syntax of the function is:
11935 //
11936 //      SWITCH(expression,value1,result1,[value2,result2],[value3,result3],...,[default])
11937 func (fn *formulaFuncs) SWITCH(argsList *list.List) formulaArg {
11938         if argsList.Len() < 3 {
11939                 return newErrorFormulaArg(formulaErrorVALUE, "SWITCH requires at least 3 arguments")
11940         }
11941         target := argsList.Front().Value.(formulaArg)
11942         argCount := argsList.Len() - 1
11943         switchCount := int(math.Floor(float64(argCount) / 2))
11944         hasDefaultClause := argCount%2 != 0
11945         result := newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
11946         if hasDefaultClause {
11947                 result = argsList.Back().Value.(formulaArg)
11948         }
11949         if switchCount > 0 {
11950                 arg := argsList.Front()
11951                 for i := 0; i < switchCount; i++ {
11952                         arg = arg.Next()
11953                         if target.Value() == arg.Value.(formulaArg).Value() {
11954                                 result = arg.Next().Value.(formulaArg)
11955                                 break
11956                         }
11957                         arg = arg.Next()
11958                 }
11959         }
11960         return result
11961 }
11962
11963 // TRUE function returns the logical value TRUE. The syntax of the function
11964 // is:
11965 //
11966 //      TRUE()
11967 func (fn *formulaFuncs) TRUE(argsList *list.List) formulaArg {
11968         if argsList.Len() != 0 {
11969                 return newErrorFormulaArg(formulaErrorVALUE, "TRUE takes no arguments")
11970         }
11971         return newBoolFormulaArg(true)
11972 }
11973
11974 // calcXor checking if numeric cell exists and count it by given arguments
11975 // sequence for the formula function XOR.
11976 func calcXor(argsList *list.List) formulaArg {
11977         count, ok := 0, false
11978         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
11979                 token := arg.Value.(formulaArg)
11980                 switch token.Type {
11981                 case ArgError:
11982                         return token
11983                 case ArgNumber:
11984                         ok = true
11985                         if token.Number != 0 {
11986                                 count++
11987                         }
11988                 case ArgMatrix:
11989                         for _, value := range token.ToList() {
11990                                 if num := value.ToNumber(); num.Type == ArgNumber {
11991                                         ok = true
11992                                         if num.Number != 0 {
11993                                                 count++
11994                                         }
11995                                 }
11996                         }
11997                 }
11998         }
11999         if !ok {
12000                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12001         }
12002         return newBoolFormulaArg(count%2 != 0)
12003 }
12004
12005 // XOR function returns the Exclusive Or logical operation for one or more
12006 // supplied conditions. I.e. the Xor function returns TRUE if an odd number
12007 // of the supplied conditions evaluate to TRUE, and FALSE otherwise. The
12008 // syntax of the function is:
12009 //
12010 //      XOR(logical_test1,[logical_test2],...)
12011 func (fn *formulaFuncs) XOR(argsList *list.List) formulaArg {
12012         if argsList.Len() < 1 {
12013                 return newErrorFormulaArg(formulaErrorVALUE, "XOR requires at least 1 argument")
12014         }
12015         return calcXor(argsList)
12016 }
12017
12018 // Date and Time Functions
12019
12020 // DATE returns a date, from a user-supplied year, month and day. The syntax
12021 // of the function is:
12022 //
12023 //      DATE(year,month,day)
12024 func (fn *formulaFuncs) DATE(argsList *list.List) formulaArg {
12025         if argsList.Len() != 3 {
12026                 return newErrorFormulaArg(formulaErrorVALUE, "DATE requires 3 number arguments")
12027         }
12028         year := argsList.Front().Value.(formulaArg).ToNumber()
12029         month := argsList.Front().Next().Value.(formulaArg).ToNumber()
12030         day := argsList.Back().Value.(formulaArg).ToNumber()
12031         if year.Type != ArgNumber || month.Type != ArgNumber || day.Type != ArgNumber {
12032                 return newErrorFormulaArg(formulaErrorVALUE, "DATE requires 3 number arguments")
12033         }
12034         d := makeDate(int(year.Number), time.Month(month.Number), int(day.Number))
12035         return newStringFormulaArg(timeFromExcelTime(daysBetween(excelMinTime1900.Unix(), d)+1, false).String())
12036 }
12037
12038 // calcDateDif is an implementation of the formula function DATEDIF,
12039 // calculation difference between two dates.
12040 func calcDateDif(unit string, diff float64, seq []int, startArg, endArg formulaArg) float64 {
12041         ey, sy, em, sm, ed, sd := seq[0], seq[1], seq[2], seq[3], seq[4], seq[5]
12042         switch unit {
12043         case "d":
12044                 diff = endArg.Number - startArg.Number
12045         case "md":
12046                 smMD := em
12047                 if ed < sd {
12048                         smMD--
12049                 }
12050                 diff = endArg.Number - daysBetween(excelMinTime1900.Unix(), makeDate(ey, time.Month(smMD), sd)) - 1
12051         case "ym":
12052                 diff = float64(em - sm)
12053                 if ed < sd {
12054                         diff--
12055                 }
12056                 if diff < 0 {
12057                         diff += 12
12058                 }
12059         case "yd":
12060                 syYD := sy
12061                 if em < sm || (em == sm && ed < sd) {
12062                         syYD++
12063                 }
12064                 s := daysBetween(excelMinTime1900.Unix(), makeDate(syYD, time.Month(em), ed))
12065                 e := daysBetween(excelMinTime1900.Unix(), makeDate(sy, time.Month(sm), sd))
12066                 diff = s - e
12067         }
12068         return diff
12069 }
12070
12071 // DATEDIF function calculates the number of days, months, or years between
12072 // two dates. The syntax of the function is:
12073 //
12074 //      DATEDIF(start_date,end_date,unit)
12075 func (fn *formulaFuncs) DATEDIF(argsList *list.List) formulaArg {
12076         if argsList.Len() != 3 {
12077                 return newErrorFormulaArg(formulaErrorVALUE, "DATEDIF requires 3 number arguments")
12078         }
12079         startArg, endArg := argsList.Front().Value.(formulaArg).ToNumber(), argsList.Front().Next().Value.(formulaArg).ToNumber()
12080         if startArg.Type != ArgNumber || endArg.Type != ArgNumber {
12081                 return startArg
12082         }
12083         if startArg.Number > endArg.Number {
12084                 return newErrorFormulaArg(formulaErrorNUM, "start_date > end_date")
12085         }
12086         if startArg.Number == endArg.Number {
12087                 return newNumberFormulaArg(0)
12088         }
12089         unit := strings.ToLower(argsList.Back().Value.(formulaArg).Value())
12090         startDate, endDate := timeFromExcelTime(startArg.Number, false), timeFromExcelTime(endArg.Number, false)
12091         sy, smm, sd := startDate.Date()
12092         ey, emm, ed := endDate.Date()
12093         sm, em, diff := int(smm), int(emm), 0.0
12094         switch unit {
12095         case "y":
12096                 diff = float64(ey - sy)
12097                 if em < sm || (em == sm && ed < sd) {
12098                         diff--
12099                 }
12100         case "m":
12101                 yDiff := ey - sy
12102                 mDiff := em - sm
12103                 if ed < sd {
12104                         mDiff--
12105                 }
12106                 if mDiff < 0 {
12107                         yDiff--
12108                         mDiff += 12
12109                 }
12110                 diff = float64(yDiff*12 + mDiff)
12111         case "d", "md", "ym", "yd":
12112                 diff = calcDateDif(unit, diff, []int{ey, sy, em, sm, ed, sd}, startArg, endArg)
12113         default:
12114                 return newErrorFormulaArg(formulaErrorVALUE, "DATEDIF has invalid unit")
12115         }
12116         return newNumberFormulaArg(diff)
12117 }
12118
12119 // isDateOnlyFmt check if the given string matches date-only format regular expressions.
12120 func isDateOnlyFmt(dateString string) bool {
12121         for _, df := range dateOnlyFormats {
12122                 subMatch := df.FindStringSubmatch(dateString)
12123                 if len(subMatch) > 1 {
12124                         return true
12125                 }
12126         }
12127         return false
12128 }
12129
12130 // isTimeOnlyFmt check if the given string matches time-only format regular expressions.
12131 func isTimeOnlyFmt(timeString string) bool {
12132         for _, tf := range timeFormats {
12133                 subMatch := tf.FindStringSubmatch(timeString)
12134                 if len(subMatch) > 1 {
12135                         return true
12136                 }
12137         }
12138         return false
12139 }
12140
12141 // strToTimePatternHandler1 parse and convert the given string in pattern
12142 // hh to the time.
12143 func strToTimePatternHandler1(subMatch []string) (h, m int, s float64, err error) {
12144         h, err = strconv.Atoi(subMatch[0])
12145         return
12146 }
12147
12148 // strToTimePatternHandler2 parse and convert the given string in pattern
12149 // hh:mm to the time.
12150 func strToTimePatternHandler2(subMatch []string) (h, m int, s float64, err error) {
12151         if h, err = strconv.Atoi(subMatch[0]); err != nil {
12152                 return
12153         }
12154         m, err = strconv.Atoi(subMatch[2])
12155         return
12156 }
12157
12158 // strToTimePatternHandler3 parse and convert the given string in pattern
12159 // mm:ss to the time.
12160 func strToTimePatternHandler3(subMatch []string) (h, m int, s float64, err error) {
12161         if m, err = strconv.Atoi(subMatch[0]); err != nil {
12162                 return
12163         }
12164         s, err = strconv.ParseFloat(subMatch[2], 64)
12165         return
12166 }
12167
12168 // strToTimePatternHandler4 parse and convert the given string in pattern
12169 // hh:mm:ss to the time.
12170 func strToTimePatternHandler4(subMatch []string) (h, m int, s float64, err error) {
12171         if h, err = strconv.Atoi(subMatch[0]); err != nil {
12172                 return
12173         }
12174         if m, err = strconv.Atoi(subMatch[2]); err != nil {
12175                 return
12176         }
12177         s, err = strconv.ParseFloat(subMatch[4], 64)
12178         return
12179 }
12180
12181 // strToTime parse and convert the given string to the time.
12182 func strToTime(str string) (int, int, float64, bool, bool, formulaArg) {
12183         var subMatch []string
12184         pattern := ""
12185         for key, tf := range timeFormats {
12186                 subMatch = tf.FindStringSubmatch(str)
12187                 if len(subMatch) > 1 {
12188                         pattern = key
12189                         break
12190                 }
12191         }
12192         if pattern == "" {
12193                 return 0, 0, 0, false, false, newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12194         }
12195         dateIsEmpty := subMatch[1] == ""
12196         subMatch = subMatch[49:]
12197         var (
12198                 l              = len(subMatch)
12199                 last           = subMatch[l-1]
12200                 am             = last == "am"
12201                 pm             = last == "pm"
12202                 hours, minutes int
12203                 seconds        float64
12204                 err            error
12205         )
12206         if handler, ok := map[string]func(match []string) (int, int, float64, error){
12207                 "hh":       strToTimePatternHandler1,
12208                 "hh:mm":    strToTimePatternHandler2,
12209                 "mm:ss":    strToTimePatternHandler3,
12210                 "hh:mm:ss": strToTimePatternHandler4,
12211         }[pattern]; ok {
12212                 if hours, minutes, seconds, err = handler(subMatch); err != nil {
12213                         return 0, 0, 0, false, false, newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12214                 }
12215         }
12216         if minutes >= 60 {
12217                 return 0, 0, 0, false, false, newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12218         }
12219         if am || pm {
12220                 if hours > 12 || seconds >= 60 {
12221                         return 0, 0, 0, false, false, newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12222                 } else if hours == 12 {
12223                         hours = 0
12224                 }
12225         } else if hours >= 24 || seconds >= 10000 {
12226                 return 0, 0, 0, false, false, newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12227         }
12228         return hours, minutes, seconds, pm, dateIsEmpty, newEmptyFormulaArg()
12229 }
12230
12231 // strToDatePatternHandler1 parse and convert the given string in pattern
12232 // mm/dd/yy to the date.
12233 func strToDatePatternHandler1(subMatch []string) (int, int, int, bool, error) {
12234         var year, month, day int
12235         var err error
12236         if month, err = strconv.Atoi(subMatch[1]); err != nil {
12237                 return 0, 0, 0, false, err
12238         }
12239         if day, err = strconv.Atoi(subMatch[3]); err != nil {
12240                 return 0, 0, 0, false, err
12241         }
12242         if year, err = strconv.Atoi(subMatch[5]); err != nil {
12243                 return 0, 0, 0, false, err
12244         }
12245         if year < 0 || year > 9999 || (year > 99 && year < 1900) {
12246                 return 0, 0, 0, false, ErrParameterInvalid
12247         }
12248         return formatYear(year), month, day, subMatch[8] == "", err
12249 }
12250
12251 // strToDatePatternHandler2 parse and convert the given string in pattern mm
12252 // dd, yy to the date.
12253 func strToDatePatternHandler2(subMatch []string) (int, int, int, bool, error) {
12254         var year, month, day int
12255         var err error
12256         month = month2num[subMatch[1]]
12257         if day, err = strconv.Atoi(subMatch[14]); err != nil {
12258                 return 0, 0, 0, false, err
12259         }
12260         if year, err = strconv.Atoi(subMatch[16]); err != nil {
12261                 return 0, 0, 0, false, err
12262         }
12263         if year < 0 || year > 9999 || (year > 99 && year < 1900) {
12264                 return 0, 0, 0, false, ErrParameterInvalid
12265         }
12266         return formatYear(year), month, day, subMatch[19] == "", err
12267 }
12268
12269 // strToDatePatternHandler3 parse and convert the given string in pattern
12270 // yy-mm-dd to the date.
12271 func strToDatePatternHandler3(subMatch []string) (int, int, int, bool, error) {
12272         var year, month, day int
12273         v1, err := strconv.Atoi(subMatch[1])
12274         if err != nil {
12275                 return 0, 0, 0, false, err
12276         }
12277         v2, err := strconv.Atoi(subMatch[3])
12278         if err != nil {
12279                 return 0, 0, 0, false, err
12280         }
12281         v3, err := strconv.Atoi(subMatch[5])
12282         if err != nil {
12283                 return 0, 0, 0, false, err
12284         }
12285         if v1 >= 1900 && v1 < 10000 {
12286                 year = v1
12287                 month = v2
12288                 day = v3
12289         } else if v1 > 0 && v1 < 13 {
12290                 month = v1
12291                 day = v2
12292                 year = v3
12293         } else {
12294                 return 0, 0, 0, false, ErrParameterInvalid
12295         }
12296         return year, month, day, subMatch[8] == "", err
12297 }
12298
12299 // strToDatePatternHandler4 parse and convert the given string in pattern
12300 // yy-mmStr-dd, yy to the date.
12301 func strToDatePatternHandler4(subMatch []string) (int, int, int, bool, error) {
12302         var year, month, day int
12303         var err error
12304         if year, err = strconv.Atoi(subMatch[16]); err != nil {
12305                 return 0, 0, 0, false, err
12306         }
12307         month = month2num[subMatch[3]]
12308         if day, err = strconv.Atoi(subMatch[1]); err != nil {
12309                 return 0, 0, 0, false, err
12310         }
12311         return formatYear(year), month, day, subMatch[19] == "", err
12312 }
12313
12314 // strToDate parse and convert the given string to the date.
12315 func strToDate(str string) (int, int, int, bool, formulaArg) {
12316         var subMatch []string
12317         pattern := ""
12318         for key, df := range dateFormats {
12319                 subMatch = df.FindStringSubmatch(str)
12320                 if len(subMatch) > 1 {
12321                         pattern = key
12322                         break
12323                 }
12324         }
12325         if pattern == "" {
12326                 return 0, 0, 0, false, newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12327         }
12328         var (
12329                 timeIsEmpty      bool
12330                 year, month, day int
12331                 err              error
12332         )
12333         if handler, ok := map[string]func(match []string) (int, int, int, bool, error){
12334                 "mm/dd/yy":    strToDatePatternHandler1,
12335                 "mm dd, yy":   strToDatePatternHandler2,
12336                 "yy-mm-dd":    strToDatePatternHandler3,
12337                 "yy-mmStr-dd": strToDatePatternHandler4,
12338         }[pattern]; ok {
12339                 if year, month, day, timeIsEmpty, err = handler(subMatch); err != nil {
12340                         return 0, 0, 0, false, newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12341                 }
12342         }
12343         if !validateDate(year, month, day) {
12344                 return 0, 0, 0, false, newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12345         }
12346         return year, month, day, timeIsEmpty, newEmptyFormulaArg()
12347 }
12348
12349 // DATEVALUE function converts a text representation of a date into an Excel
12350 // date. For example, the function converts a text string representing a
12351 // date, into the serial number that represents the date in Excels' date-time
12352 // code. The syntax of the function is:
12353 //
12354 //      DATEVALUE(date_text)
12355 func (fn *formulaFuncs) DATEVALUE(argsList *list.List) formulaArg {
12356         if argsList.Len() != 1 {
12357                 return newErrorFormulaArg(formulaErrorVALUE, "DATEVALUE requires 1 argument")
12358         }
12359         dateText := argsList.Front().Value.(formulaArg).Value()
12360         if !isDateOnlyFmt(dateText) {
12361                 if _, _, _, _, _, err := strToTime(dateText); err.Type == ArgError {
12362                         return err
12363                 }
12364         }
12365         y, m, d, _, err := strToDate(dateText)
12366         if err.Type == ArgError {
12367                 return err
12368         }
12369         return newNumberFormulaArg(daysBetween(excelMinTime1900.Unix(), makeDate(y, time.Month(m), d)) + 1)
12370 }
12371
12372 // DAY function returns the day of a date, represented by a serial number. The
12373 // day is given as an integer ranging from 1 to 31. The syntax of the
12374 // function is:
12375 //
12376 //      DAY(serial_number)
12377 func (fn *formulaFuncs) DAY(argsList *list.List) formulaArg {
12378         if argsList.Len() != 1 {
12379                 return newErrorFormulaArg(formulaErrorVALUE, "DAY requires exactly 1 argument")
12380         }
12381         arg := argsList.Front().Value.(formulaArg)
12382         num := arg.ToNumber()
12383         if num.Type != ArgNumber {
12384                 dateString := strings.ToLower(arg.Value())
12385                 if !isDateOnlyFmt(dateString) {
12386                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
12387                                 return err
12388                         }
12389                 }
12390                 _, _, day, _, err := strToDate(dateString)
12391                 if err.Type == ArgError {
12392                         return err
12393                 }
12394                 return newNumberFormulaArg(float64(day))
12395         }
12396         if num.Number < 0 {
12397                 return newErrorFormulaArg(formulaErrorNUM, "DAY only accepts positive argument")
12398         }
12399         if num.Number <= 60 {
12400                 return newNumberFormulaArg(math.Mod(num.Number, 31.0))
12401         }
12402         return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Day()))
12403 }
12404
12405 // DAYS function returns the number of days between two supplied dates. The
12406 // syntax of the function is:
12407 //
12408 //      DAYS(end_date,start_date)
12409 func (fn *formulaFuncs) DAYS(argsList *list.List) formulaArg {
12410         if argsList.Len() != 2 {
12411                 return newErrorFormulaArg(formulaErrorVALUE, "DAYS requires 2 arguments")
12412         }
12413         args := fn.prepareDataValueArgs(2, argsList)
12414         if args.Type != ArgList {
12415                 return args
12416         }
12417         end, start := args.List[0], args.List[1]
12418         return newNumberFormulaArg(end.Number - start.Number)
12419 }
12420
12421 // DAYS360 function returns the number of days between 2 dates, based on a
12422 // 360-day year (12 x 30 months). The syntax of the function is:
12423 //
12424 //      DAYS360(start_date,end_date,[method])
12425 func (fn *formulaFuncs) DAYS360(argsList *list.List) formulaArg {
12426         if argsList.Len() < 2 {
12427                 return newErrorFormulaArg(formulaErrorVALUE, "DAYS360 requires at least 2 arguments")
12428         }
12429         if argsList.Len() > 3 {
12430                 return newErrorFormulaArg(formulaErrorVALUE, "DAYS360 requires at most 3 arguments")
12431         }
12432         startDate := toExcelDateArg(argsList.Front().Value.(formulaArg))
12433         if startDate.Type != ArgNumber {
12434                 return startDate
12435         }
12436         endDate := toExcelDateArg(argsList.Front().Next().Value.(formulaArg))
12437         if endDate.Type != ArgNumber {
12438                 return endDate
12439         }
12440         start, end := timeFromExcelTime(startDate.Number, false), timeFromExcelTime(endDate.Number, false)
12441         sy, sm, sd, ey, em, ed := start.Year(), int(start.Month()), start.Day(), end.Year(), int(end.Month()), end.Day()
12442         method := newBoolFormulaArg(false)
12443         if argsList.Len() > 2 {
12444                 if method = argsList.Back().Value.(formulaArg).ToBool(); method.Type != ArgNumber {
12445                         return method
12446                 }
12447         }
12448         if method.Number == 1 {
12449                 if sd == 31 {
12450                         sd--
12451                 }
12452                 if ed == 31 {
12453                         ed--
12454                 }
12455         } else {
12456                 if getDaysInMonth(sy, sm) == sd {
12457                         sd = 30
12458                 }
12459                 if ed > 30 {
12460                         if sd < 30 {
12461                                 em++
12462                                 ed = 1
12463                         } else {
12464                                 ed = 30
12465                         }
12466                 }
12467         }
12468         return newNumberFormulaArg(float64(360*(ey-sy) + 30*(em-sm) + (ed - sd)))
12469 }
12470
12471 // ISOWEEKNUM function returns the ISO week number of a supplied date. The
12472 // syntax of the function is:
12473 //
12474 //      ISOWEEKNUM(date)
12475 func (fn *formulaFuncs) ISOWEEKNUM(argsList *list.List) formulaArg {
12476         if argsList.Len() != 1 {
12477                 return newErrorFormulaArg(formulaErrorVALUE, "ISOWEEKNUM requires 1 argument")
12478         }
12479         date := argsList.Front().Value.(formulaArg)
12480         num := date.ToNumber()
12481         weekNum := 0
12482         if num.Type != ArgNumber {
12483                 dateString := strings.ToLower(date.Value())
12484                 if !isDateOnlyFmt(dateString) {
12485                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
12486                                 return err
12487                         }
12488                 }
12489                 y, m, d, _, err := strToDate(dateString)
12490                 if err.Type == ArgError {
12491                         return err
12492                 }
12493                 _, weekNum = time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.UTC).ISOWeek()
12494         } else {
12495                 if num.Number < 0 {
12496                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
12497                 }
12498                 _, weekNum = timeFromExcelTime(num.Number, false).ISOWeek()
12499         }
12500         return newNumberFormulaArg(float64(weekNum))
12501 }
12502
12503 // EDATE function returns a date that is a specified number of months before or
12504 // after a supplied start date. The syntax of function is:
12505 //
12506 //      EDATE(start_date,months)
12507 func (fn *formulaFuncs) EDATE(argsList *list.List) formulaArg {
12508         if argsList.Len() != 2 {
12509                 return newErrorFormulaArg(formulaErrorVALUE, "EDATE requires 2 arguments")
12510         }
12511         date := argsList.Front().Value.(formulaArg)
12512         num := date.ToNumber()
12513         var dateTime time.Time
12514         if num.Type != ArgNumber {
12515                 dateString := strings.ToLower(date.Value())
12516                 if !isDateOnlyFmt(dateString) {
12517                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
12518                                 return err
12519                         }
12520                 }
12521                 y, m, d, _, err := strToDate(dateString)
12522                 if err.Type == ArgError {
12523                         return err
12524                 }
12525                 dateTime = time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.Now().Location())
12526         } else {
12527                 if num.Number < 0 {
12528                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
12529                 }
12530                 dateTime = timeFromExcelTime(num.Number, false)
12531         }
12532         month := argsList.Back().Value.(formulaArg).ToNumber()
12533         if month.Type != ArgNumber {
12534                 return month
12535         }
12536         y, d := dateTime.Year(), dateTime.Day()
12537         m := int(dateTime.Month()) + int(month.Number)
12538         if month.Number < 0 {
12539                 y -= int(math.Ceil(-1 * float64(m) / 12))
12540         }
12541         if month.Number > 11 {
12542                 y += int(math.Floor(float64(m) / 12))
12543         }
12544         if m = m % 12; m < 0 {
12545                 m += 12
12546         }
12547         if d > 28 {
12548                 if days := getDaysInMonth(y, m); d > days {
12549                         d = days
12550                 }
12551         }
12552         result, _ := timeToExcelTime(time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.UTC), false)
12553         return newNumberFormulaArg(result)
12554 }
12555
12556 // EOMONTH function returns the last day of the month, that is a specified
12557 // number of months before or after an initial supplied start date. The syntax
12558 // of the function is:
12559 //
12560 //      EOMONTH(start_date,months)
12561 func (fn *formulaFuncs) EOMONTH(argsList *list.List) formulaArg {
12562         if argsList.Len() != 2 {
12563                 return newErrorFormulaArg(formulaErrorVALUE, "EOMONTH requires 2 arguments")
12564         }
12565         date := argsList.Front().Value.(formulaArg)
12566         num := date.ToNumber()
12567         var dateTime time.Time
12568         if num.Type != ArgNumber {
12569                 dateString := strings.ToLower(date.Value())
12570                 if !isDateOnlyFmt(dateString) {
12571                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
12572                                 return err
12573                         }
12574                 }
12575                 y, m, d, _, err := strToDate(dateString)
12576                 if err.Type == ArgError {
12577                         return err
12578                 }
12579                 dateTime = time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.Now().Location())
12580         } else {
12581                 if num.Number < 0 {
12582                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
12583                 }
12584                 dateTime = timeFromExcelTime(num.Number, false)
12585         }
12586         months := argsList.Back().Value.(formulaArg).ToNumber()
12587         if months.Type != ArgNumber {
12588                 return months
12589         }
12590         y, m := dateTime.Year(), int(dateTime.Month())+int(months.Number)-1
12591         if m < 0 {
12592                 y -= int(math.Ceil(-1 * float64(m) / 12))
12593         }
12594         if m > 11 {
12595                 y += int(math.Floor(float64(m) / 12))
12596         }
12597         if m = m % 12; m < 0 {
12598                 m += 12
12599         }
12600         result, _ := timeToExcelTime(time.Date(y, time.Month(m+1), getDaysInMonth(y, m+1), 0, 0, 0, 0, time.UTC), false)
12601         return newNumberFormulaArg(result)
12602 }
12603
12604 // HOUR function returns an integer representing the hour component of a
12605 // supplied Excel time. The syntax of the function is:
12606 //
12607 //      HOUR(serial_number)
12608 func (fn *formulaFuncs) HOUR(argsList *list.List) formulaArg {
12609         if argsList.Len() != 1 {
12610                 return newErrorFormulaArg(formulaErrorVALUE, "HOUR requires exactly 1 argument")
12611         }
12612         date := argsList.Front().Value.(formulaArg)
12613         num := date.ToNumber()
12614         if num.Type != ArgNumber {
12615                 timeString := strings.ToLower(date.Value())
12616                 if !isTimeOnlyFmt(timeString) {
12617                         _, _, _, _, err := strToDate(timeString)
12618                         if err.Type == ArgError {
12619                                 return err
12620                         }
12621                 }
12622                 h, _, _, pm, _, err := strToTime(timeString)
12623                 if err.Type == ArgError {
12624                         return err
12625                 }
12626                 if pm {
12627                         h += 12
12628                 }
12629                 return newNumberFormulaArg(float64(h))
12630         }
12631         if num.Number < 0 {
12632                 return newErrorFormulaArg(formulaErrorNUM, "HOUR only accepts positive argument")
12633         }
12634         return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Hour()))
12635 }
12636
12637 // MINUTE function returns an integer representing the minute component of a
12638 // supplied Excel time. The syntax of the function is:
12639 //
12640 //      MINUTE(serial_number)
12641 func (fn *formulaFuncs) MINUTE(argsList *list.List) formulaArg {
12642         if argsList.Len() != 1 {
12643                 return newErrorFormulaArg(formulaErrorVALUE, "MINUTE requires exactly 1 argument")
12644         }
12645         date := argsList.Front().Value.(formulaArg)
12646         num := date.ToNumber()
12647         if num.Type != ArgNumber {
12648                 timeString := strings.ToLower(date.Value())
12649                 if !isTimeOnlyFmt(timeString) {
12650                         _, _, _, _, err := strToDate(timeString)
12651                         if err.Type == ArgError {
12652                                 return err
12653                         }
12654                 }
12655                 _, m, _, _, _, err := strToTime(timeString)
12656                 if err.Type == ArgError {
12657                         return err
12658                 }
12659                 return newNumberFormulaArg(float64(m))
12660         }
12661         if num.Number < 0 {
12662                 return newErrorFormulaArg(formulaErrorNUM, "MINUTE only accepts positive argument")
12663         }
12664         return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Minute()))
12665 }
12666
12667 // MONTH function returns the month of a date represented by a serial number.
12668 // The month is given as an integer, ranging from 1 (January) to 12
12669 // (December). The syntax of the function is:
12670 //
12671 //      MONTH(serial_number)
12672 func (fn *formulaFuncs) MONTH(argsList *list.List) formulaArg {
12673         if argsList.Len() != 1 {
12674                 return newErrorFormulaArg(formulaErrorVALUE, "MONTH requires exactly 1 argument")
12675         }
12676         arg := argsList.Front().Value.(formulaArg)
12677         num := arg.ToNumber()
12678         if num.Type != ArgNumber {
12679                 dateString := strings.ToLower(arg.Value())
12680                 if !isDateOnlyFmt(dateString) {
12681                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
12682                                 return err
12683                         }
12684                 }
12685                 _, month, _, _, err := strToDate(dateString)
12686                 if err.Type == ArgError {
12687                         return err
12688                 }
12689                 return newNumberFormulaArg(float64(month))
12690         }
12691         if num.Number < 0 {
12692                 return newErrorFormulaArg(formulaErrorNUM, "MONTH only accepts positive argument")
12693         }
12694         return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Month()))
12695 }
12696
12697 // genWeekendMask generate weekend mask of a series of seven 0's and 1's which
12698 // represent the seven weekdays, starting from Monday.
12699 func genWeekendMask(weekend int) []byte {
12700         if masks, ok := map[int][]int{
12701                 1: {5, 6}, 2: {6, 0}, 3: {0, 1}, 4: {1, 2}, 5: {2, 3}, 6: {3, 4}, 7: {4, 5},
12702                 11: {6}, 12: {0}, 13: {1}, 14: {2}, 15: {3}, 16: {4}, 17: {5},
12703         }[weekend]; ok {
12704                 mask := make([]byte, 7)
12705                 for _, idx := range masks {
12706                         mask[idx] = 1
12707                 }
12708                 return mask
12709         }
12710         return nil
12711 }
12712
12713 // isWorkday check if the date is workday.
12714 func isWorkday(weekendMask []byte, date float64) bool {
12715         dateTime := timeFromExcelTime(date, false)
12716         weekday := dateTime.Weekday()
12717         if weekday == time.Sunday {
12718                 weekday = 7
12719         }
12720         return weekendMask[weekday-1] == 0
12721 }
12722
12723 // prepareWorkday returns weekend mask and workdays pre week by given days
12724 // counted as weekend.
12725 func prepareWorkday(weekend formulaArg) ([]byte, int) {
12726         weekendArg := weekend.ToNumber()
12727         if weekendArg.Type != ArgNumber {
12728                 return nil, 0
12729         }
12730         var weekendMask []byte
12731         var workdaysPerWeek int
12732         if len(weekend.Value()) == 7 {
12733                 // possible string values for the weekend argument
12734                 for _, mask := range weekend.Value() {
12735                         if mask != '0' && mask != '1' {
12736                                 return nil, 0
12737                         }
12738                         weekendMask = append(weekendMask, byte(mask)-48)
12739                 }
12740         } else {
12741                 weekendMask = genWeekendMask(int(weekendArg.Number))
12742         }
12743         for _, mask := range weekendMask {
12744                 if mask == 0 {
12745                         workdaysPerWeek++
12746                 }
12747         }
12748         return weekendMask, workdaysPerWeek
12749 }
12750
12751 // toExcelDateArg function converts a text representation of a time, into an
12752 // Excel date time number formula argument.
12753 func toExcelDateArg(arg formulaArg) formulaArg {
12754         num := arg.ToNumber()
12755         if num.Type != ArgNumber {
12756                 dateString := strings.ToLower(arg.Value())
12757                 if !isDateOnlyFmt(dateString) {
12758                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
12759                                 return err
12760                         }
12761                 }
12762                 y, m, d, _, err := strToDate(dateString)
12763                 if err.Type == ArgError {
12764                         return err
12765                 }
12766                 num.Number, _ = timeToExcelTime(time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.UTC), false)
12767                 return newNumberFormulaArg(num.Number)
12768         }
12769         if arg.Number < 0 {
12770                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
12771         }
12772         return num
12773 }
12774
12775 // prepareHolidays function converts array type formula arguments to into an
12776 // Excel date time number formula arguments list.
12777 func prepareHolidays(args formulaArg) []int {
12778         var holidays []int
12779         for _, arg := range args.ToList() {
12780                 num := toExcelDateArg(arg)
12781                 if num.Type != ArgNumber {
12782                         continue
12783                 }
12784                 holidays = append(holidays, int(math.Ceil(num.Number)))
12785         }
12786         return holidays
12787 }
12788
12789 // workdayIntl is an implementation of the formula function WORKDAY.INTL.
12790 func workdayIntl(endDate, sign int, holidays []int, weekendMask []byte, startDate float64) int {
12791         for i := 0; i < len(holidays); i++ {
12792                 holiday := holidays[i]
12793                 if sign > 0 {
12794                         if holiday > endDate {
12795                                 break
12796                         }
12797                 } else {
12798                         if holiday < endDate {
12799                                 break
12800                         }
12801                 }
12802                 if sign > 0 {
12803                         if holiday > int(math.Ceil(startDate)) {
12804                                 if isWorkday(weekendMask, float64(holiday)) {
12805                                         endDate += sign
12806                                         for !isWorkday(weekendMask, float64(endDate)) {
12807                                                 endDate += sign
12808                                         }
12809                                 }
12810                         }
12811                 } else {
12812                         if holiday < int(math.Ceil(startDate)) {
12813                                 if isWorkday(weekendMask, float64(holiday)) {
12814                                         endDate += sign
12815                                         for !isWorkday(weekendMask, float64(endDate)) {
12816                                                 endDate += sign
12817                                         }
12818                                 }
12819                         }
12820                 }
12821         }
12822         return endDate
12823 }
12824
12825 // NETWORKDAYS function calculates the number of work days between two supplied
12826 // dates (including the start and end date). The calculation includes all
12827 // weekdays (Mon - Fri), excluding a supplied list of holidays. The syntax of
12828 // the function is:
12829 //
12830 //      NETWORKDAYS(start_date,end_date,[holidays])
12831 func (fn *formulaFuncs) NETWORKDAYS(argsList *list.List) formulaArg {
12832         if argsList.Len() < 2 {
12833                 return newErrorFormulaArg(formulaErrorVALUE, "NETWORKDAYS requires at least 2 arguments")
12834         }
12835         if argsList.Len() > 3 {
12836                 return newErrorFormulaArg(formulaErrorVALUE, "NETWORKDAYS requires at most 3 arguments")
12837         }
12838         args := list.New()
12839         args.PushBack(argsList.Front().Value.(formulaArg))
12840         args.PushBack(argsList.Front().Next().Value.(formulaArg))
12841         args.PushBack(newNumberFormulaArg(1))
12842         if argsList.Len() == 3 {
12843                 args.PushBack(argsList.Back().Value.(formulaArg))
12844         }
12845         return fn.NETWORKDAYSdotINTL(args)
12846 }
12847
12848 // NETWORKDAYSdotINTL function calculates the number of whole work days between
12849 // two supplied dates, excluding weekends and holidays. The function allows
12850 // the user to specify which days are counted as weekends and holidays. The
12851 // syntax of the function is:
12852 //
12853 //      NETWORKDAYS.INTL(start_date,end_date,[weekend],[holidays])
12854 func (fn *formulaFuncs) NETWORKDAYSdotINTL(argsList *list.List) formulaArg {
12855         if argsList.Len() < 2 {
12856                 return newErrorFormulaArg(formulaErrorVALUE, "NETWORKDAYS.INTL requires at least 2 arguments")
12857         }
12858         if argsList.Len() > 4 {
12859                 return newErrorFormulaArg(formulaErrorVALUE, "NETWORKDAYS.INTL requires at most 4 arguments")
12860         }
12861         startDate := toExcelDateArg(argsList.Front().Value.(formulaArg))
12862         if startDate.Type != ArgNumber {
12863                 return startDate
12864         }
12865         endDate := toExcelDateArg(argsList.Front().Next().Value.(formulaArg))
12866         if endDate.Type != ArgNumber {
12867                 return endDate
12868         }
12869         weekend := newNumberFormulaArg(1)
12870         if argsList.Len() > 2 {
12871                 weekend = argsList.Front().Next().Next().Value.(formulaArg)
12872         }
12873         var holidays []int
12874         if argsList.Len() == 4 {
12875                 holidays = prepareHolidays(argsList.Back().Value.(formulaArg))
12876                 sort.Ints(holidays)
12877         }
12878         weekendMask, workdaysPerWeek := prepareWorkday(weekend)
12879         if workdaysPerWeek == 0 {
12880                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12881         }
12882         sign := 1
12883         if startDate.Number > endDate.Number {
12884                 sign = -1
12885                 temp := startDate.Number
12886                 startDate.Number = endDate.Number
12887                 endDate.Number = temp
12888         }
12889         offset := endDate.Number - startDate.Number
12890         count := int(math.Floor(offset/7) * float64(workdaysPerWeek))
12891         daysMod := int(offset) % 7
12892         for daysMod >= 0 {
12893                 if isWorkday(weekendMask, endDate.Number-float64(daysMod)) {
12894                         count++
12895                 }
12896                 daysMod--
12897         }
12898         for i := 0; i < len(holidays); i++ {
12899                 holiday := float64(holidays[i])
12900                 if isWorkday(weekendMask, holiday) && holiday >= startDate.Number && holiday <= endDate.Number {
12901                         count--
12902                 }
12903         }
12904         return newNumberFormulaArg(float64(sign * count))
12905 }
12906
12907 // WORKDAY function returns a date that is a supplied number of working days
12908 // (excluding weekends and holidays) ahead of a given start date. The syntax
12909 // of the function is:
12910 //
12911 //      WORKDAY(start_date,days,[holidays])
12912 func (fn *formulaFuncs) WORKDAY(argsList *list.List) formulaArg {
12913         if argsList.Len() < 2 {
12914                 return newErrorFormulaArg(formulaErrorVALUE, "WORKDAY requires at least 2 arguments")
12915         }
12916         if argsList.Len() > 3 {
12917                 return newErrorFormulaArg(formulaErrorVALUE, "WORKDAY requires at most 3 arguments")
12918         }
12919         args := list.New()
12920         args.PushBack(argsList.Front().Value.(formulaArg))
12921         args.PushBack(argsList.Front().Next().Value.(formulaArg))
12922         args.PushBack(newNumberFormulaArg(1))
12923         if argsList.Len() == 3 {
12924                 args.PushBack(argsList.Back().Value.(formulaArg))
12925         }
12926         return fn.WORKDAYdotINTL(args)
12927 }
12928
12929 // WORKDAYdotINTL function returns a date that is a supplied number of working
12930 // days (excluding weekends and holidays) ahead of a given start date. The
12931 // function allows the user to specify which days of the week are counted as
12932 // weekends. The syntax of the function is:
12933 //
12934 //      WORKDAY.INTL(start_date,days,[weekend],[holidays])
12935 func (fn *formulaFuncs) WORKDAYdotINTL(argsList *list.List) formulaArg {
12936         if argsList.Len() < 2 {
12937                 return newErrorFormulaArg(formulaErrorVALUE, "WORKDAY.INTL requires at least 2 arguments")
12938         }
12939         if argsList.Len() > 4 {
12940                 return newErrorFormulaArg(formulaErrorVALUE, "WORKDAY.INTL requires at most 4 arguments")
12941         }
12942         startDate := toExcelDateArg(argsList.Front().Value.(formulaArg))
12943         if startDate.Type != ArgNumber {
12944                 return startDate
12945         }
12946         days := argsList.Front().Next().Value.(formulaArg).ToNumber()
12947         if days.Type != ArgNumber {
12948                 return days
12949         }
12950         weekend := newNumberFormulaArg(1)
12951         if argsList.Len() > 2 {
12952                 weekend = argsList.Front().Next().Next().Value.(formulaArg)
12953         }
12954         var holidays []int
12955         if argsList.Len() == 4 {
12956                 holidays = prepareHolidays(argsList.Back().Value.(formulaArg))
12957                 sort.Ints(holidays)
12958         }
12959         if days.Number == 0 {
12960                 return newNumberFormulaArg(math.Ceil(startDate.Number))
12961         }
12962         weekendMask, workdaysPerWeek := prepareWorkday(weekend)
12963         if workdaysPerWeek == 0 {
12964                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
12965         }
12966         sign := 1
12967         if days.Number < 0 {
12968                 sign = -1
12969         }
12970         offset := int(days.Number) / workdaysPerWeek
12971         daysMod := int(days.Number) % workdaysPerWeek
12972         endDate := int(math.Ceil(startDate.Number)) + offset*7
12973         if daysMod == 0 {
12974                 for !isWorkday(weekendMask, float64(endDate)) {
12975                         endDate -= sign
12976                 }
12977         } else {
12978                 for daysMod != 0 {
12979                         endDate += sign
12980                         if isWorkday(weekendMask, float64(endDate)) {
12981                                 if daysMod < 0 {
12982                                         daysMod++
12983                                         continue
12984                                 }
12985                                 daysMod--
12986                         }
12987                 }
12988         }
12989         return newNumberFormulaArg(float64(workdayIntl(endDate, sign, holidays, weekendMask, startDate.Number)))
12990 }
12991
12992 // YEAR function returns an integer representing the year of a supplied date.
12993 // The syntax of the function is:
12994 //
12995 //      YEAR(serial_number)
12996 func (fn *formulaFuncs) YEAR(argsList *list.List) formulaArg {
12997         if argsList.Len() != 1 {
12998                 return newErrorFormulaArg(formulaErrorVALUE, "YEAR requires exactly 1 argument")
12999         }
13000         arg := argsList.Front().Value.(formulaArg)
13001         num := arg.ToNumber()
13002         if num.Type != ArgNumber {
13003                 dateString := strings.ToLower(arg.Value())
13004                 if !isDateOnlyFmt(dateString) {
13005                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
13006                                 return err
13007                         }
13008                 }
13009                 year, _, _, _, err := strToDate(dateString)
13010                 if err.Type == ArgError {
13011                         return err
13012                 }
13013                 return newNumberFormulaArg(float64(year))
13014         }
13015         if num.Number < 0 {
13016                 return newErrorFormulaArg(formulaErrorNUM, "YEAR only accepts positive argument")
13017         }
13018         return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Year()))
13019 }
13020
13021 // yearFracBasisCond is an implementation of the yearFracBasis1.
13022 func yearFracBasisCond(sy, sm, sd, ey, em, ed int) bool {
13023         return (isLeapYear(sy) && (sm < 2 || (sm == 2 && sd <= 29))) || (isLeapYear(ey) && (em > 2 || (em == 2 && ed == 29)))
13024 }
13025
13026 // yearFracBasis0 function returns the fraction of a year that between two
13027 // supplied dates in US (NASD) 30/360 type of day.
13028 func yearFracBasis0(startDate, endDate float64) (dayDiff, daysInYear float64) {
13029         startTime, endTime := timeFromExcelTime(startDate, false), timeFromExcelTime(endDate, false)
13030         sy, smM, sd := startTime.Date()
13031         ey, emM, ed := endTime.Date()
13032         sm, em := int(smM), int(emM)
13033         if sd == 31 {
13034                 sd--
13035         }
13036         if sd == 30 && ed == 31 {
13037                 ed--
13038         } else if leap := isLeapYear(sy); sm == 2 && ((leap && sd == 29) || (!leap && sd == 28)) {
13039                 sd = 30
13040                 if leap := isLeapYear(ey); em == 2 && ((leap && ed == 29) || (!leap && ed == 28)) {
13041                         ed = 30
13042                 }
13043         }
13044         dayDiff = float64((ey-sy)*360 + (em-sm)*30 + (ed - sd))
13045         daysInYear = 360
13046         return
13047 }
13048
13049 // yearFracBasis1 function returns the fraction of a year that between two
13050 // supplied dates in actual type of day.
13051 func yearFracBasis1(startDate, endDate float64) (dayDiff, daysInYear float64) {
13052         startTime, endTime := timeFromExcelTime(startDate, false), timeFromExcelTime(endDate, false)
13053         sy, smM, sd := startTime.Date()
13054         ey, emM, ed := endTime.Date()
13055         sm, em := int(smM), int(emM)
13056         dayDiff = endDate - startDate
13057         isYearDifferent := sy != ey
13058         if isYearDifferent && (ey != sy+1 || sm < em || (sm == em && sd < ed)) {
13059                 dayCount := 0
13060                 for y := sy; y <= ey; y++ {
13061                         dayCount += getYearDays(y, 1)
13062                 }
13063                 daysInYear = float64(dayCount) / float64(ey-sy+1)
13064         } else {
13065                 if !isYearDifferent && isLeapYear(sy) {
13066                         daysInYear = 366
13067                 } else {
13068                         if isYearDifferent && yearFracBasisCond(sy, sm, sd, ey, em, ed) {
13069                                 daysInYear = 366
13070                         } else {
13071                                 daysInYear = 365
13072                         }
13073                 }
13074         }
13075         return
13076 }
13077
13078 // yearFracBasis4 function returns the fraction of a year that between two
13079 // supplied dates in European 30/360 type of day.
13080 func yearFracBasis4(startDate, endDate float64) (dayDiff, daysInYear float64) {
13081         startTime, endTime := timeFromExcelTime(startDate, false), timeFromExcelTime(endDate, false)
13082         sy, smM, sd := startTime.Date()
13083         ey, emM, ed := endTime.Date()
13084         sm, em := int(smM), int(emM)
13085         if sd == 31 {
13086                 sd--
13087         }
13088         if ed == 31 {
13089                 ed--
13090         }
13091         dayDiff = float64((ey-sy)*360 + (em-sm)*30 + (ed - sd))
13092         daysInYear = 360
13093         return
13094 }
13095
13096 // yearFrac is an implementation of the formula function YEARFRAC.
13097 func yearFrac(startDate, endDate float64, basis int) formulaArg {
13098         startTime, endTime := timeFromExcelTime(startDate, false), timeFromExcelTime(endDate, false)
13099         if startTime == endTime {
13100                 return newNumberFormulaArg(0)
13101         }
13102         var dayDiff, daysInYear float64
13103         switch basis {
13104         case 0:
13105                 dayDiff, daysInYear = yearFracBasis0(startDate, endDate)
13106         case 1:
13107                 dayDiff, daysInYear = yearFracBasis1(startDate, endDate)
13108         case 2:
13109                 dayDiff = endDate - startDate
13110                 daysInYear = 360
13111         case 3:
13112                 dayDiff = endDate - startDate
13113                 daysInYear = 365
13114         case 4:
13115                 dayDiff, daysInYear = yearFracBasis4(startDate, endDate)
13116         default:
13117                 return newErrorFormulaArg(formulaErrorNUM, "invalid basis")
13118         }
13119         return newNumberFormulaArg(dayDiff / daysInYear)
13120 }
13121
13122 // getYearDays return days of the year with specifying the type of day count
13123 // basis to be used.
13124 func getYearDays(year, basis int) int {
13125         switch basis {
13126         case 1:
13127                 if isLeapYear(year) {
13128                         return 366
13129                 }
13130                 return 365
13131         case 3:
13132                 return 365
13133         default:
13134                 return 360
13135         }
13136 }
13137
13138 // YEARFRAC function returns the fraction of a year that is represented by the
13139 // number of whole days between two supplied dates. The syntax of the
13140 // function is:
13141 //
13142 //      YEARFRAC(start_date,end_date,[basis])
13143 func (fn *formulaFuncs) YEARFRAC(argsList *list.List) formulaArg {
13144         if argsList.Len() != 2 && argsList.Len() != 3 {
13145                 return newErrorFormulaArg(formulaErrorVALUE, "YEARFRAC requires 3 or 4 arguments")
13146         }
13147         args := fn.prepareDataValueArgs(2, argsList)
13148         if args.Type != ArgList {
13149                 return args
13150         }
13151         start, end := args.List[0], args.List[1]
13152         basis := newNumberFormulaArg(0)
13153         if argsList.Len() == 3 {
13154                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
13155                         return basis
13156                 }
13157         }
13158         return yearFrac(start.Number, end.Number, int(basis.Number))
13159 }
13160
13161 // NOW function returns the current date and time. The function receives no
13162 // arguments and therefore. The syntax of the function is:
13163 //
13164 //      NOW()
13165 func (fn *formulaFuncs) NOW(argsList *list.List) formulaArg {
13166         if argsList.Len() != 0 {
13167                 return newErrorFormulaArg(formulaErrorVALUE, "NOW accepts no arguments")
13168         }
13169         now := time.Now()
13170         _, offset := now.Zone()
13171         return newNumberFormulaArg(25569.0 + float64(now.Unix()+int64(offset))/86400)
13172 }
13173
13174 // SECOND function returns an integer representing the second component of a
13175 // supplied Excel time. The syntax of the function is:
13176 //
13177 //      SECOND(serial_number)
13178 func (fn *formulaFuncs) SECOND(argsList *list.List) formulaArg {
13179         if argsList.Len() != 1 {
13180                 return newErrorFormulaArg(formulaErrorVALUE, "SECOND requires exactly 1 argument")
13181         }
13182         date := argsList.Front().Value.(formulaArg)
13183         num := date.ToNumber()
13184         if num.Type != ArgNumber {
13185                 timeString := strings.ToLower(date.Value())
13186                 if !isTimeOnlyFmt(timeString) {
13187                         _, _, _, _, err := strToDate(timeString)
13188                         if err.Type == ArgError {
13189                                 return err
13190                         }
13191                 }
13192                 _, _, s, _, _, err := strToTime(timeString)
13193                 if err.Type == ArgError {
13194                         return err
13195                 }
13196                 return newNumberFormulaArg(float64(int(s) % 60))
13197         }
13198         if num.Number < 0 {
13199                 return newErrorFormulaArg(formulaErrorNUM, "SECOND only accepts positive argument")
13200         }
13201         return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Second()))
13202 }
13203
13204 // TIME function accepts three integer arguments representing hours, minutes
13205 // and seconds, and returns an Excel time. I.e. the function returns the
13206 // decimal value that represents the time in Excel. The syntax of the
13207 // function is:
13208 //
13209 //      TIME(hour,minute,second)
13210 func (fn *formulaFuncs) TIME(argsList *list.List) formulaArg {
13211         if argsList.Len() != 3 {
13212                 return newErrorFormulaArg(formulaErrorVALUE, "TIME requires 3 number arguments")
13213         }
13214         h := argsList.Front().Value.(formulaArg).ToNumber()
13215         m := argsList.Front().Next().Value.(formulaArg).ToNumber()
13216         s := argsList.Back().Value.(formulaArg).ToNumber()
13217         if h.Type != ArgNumber || m.Type != ArgNumber || s.Type != ArgNumber {
13218                 return newErrorFormulaArg(formulaErrorVALUE, "TIME requires 3 number arguments")
13219         }
13220         t := (h.Number*3600 + m.Number*60 + s.Number) / 86400
13221         if t < 0 {
13222                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
13223         }
13224         return newNumberFormulaArg(t)
13225 }
13226
13227 // TIMEVALUE function converts a text representation of a time, into an Excel
13228 // time. The syntax of the function is:
13229 //
13230 //      TIMEVALUE(time_text)
13231 func (fn *formulaFuncs) TIMEVALUE(argsList *list.List) formulaArg {
13232         if argsList.Len() != 1 {
13233                 return newErrorFormulaArg(formulaErrorVALUE, "TIMEVALUE requires exactly 1 argument")
13234         }
13235         date := argsList.Front().Value.(formulaArg)
13236         timeString := strings.ToLower(date.Value())
13237         if !isTimeOnlyFmt(timeString) {
13238                 _, _, _, _, err := strToDate(timeString)
13239                 if err.Type == ArgError {
13240                         return err
13241                 }
13242         }
13243         h, m, s, pm, _, err := strToTime(timeString)
13244         if err.Type == ArgError {
13245                 return err
13246         }
13247         if pm {
13248                 h += 12
13249         }
13250         args := list.New()
13251         args.PushBack(newNumberFormulaArg(float64(h)))
13252         args.PushBack(newNumberFormulaArg(float64(m)))
13253         args.PushBack(newNumberFormulaArg(s))
13254         return fn.TIME(args)
13255 }
13256
13257 // TODAY function returns the current date. The function has no arguments and
13258 // therefore. The syntax of the function is:
13259 //
13260 //      TODAY()
13261 func (fn *formulaFuncs) TODAY(argsList *list.List) formulaArg {
13262         if argsList.Len() != 0 {
13263                 return newErrorFormulaArg(formulaErrorVALUE, "TODAY accepts no arguments")
13264         }
13265         now := time.Now()
13266         _, offset := now.Zone()
13267         return newNumberFormulaArg(daysBetween(excelMinTime1900.Unix(), now.Unix()+int64(offset)) + 1)
13268 }
13269
13270 // makeDate return date as a Unix time, the number of seconds elapsed since
13271 // January 1, 1970 UTC.
13272 func makeDate(y int, m time.Month, d int) int64 {
13273         if y == 1900 && int(m) <= 2 {
13274                 d--
13275         }
13276         date := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
13277         return date.Unix()
13278 }
13279
13280 // daysBetween return time interval of the given start timestamp and end
13281 // timestamp.
13282 func daysBetween(startDate, endDate int64) float64 {
13283         return float64(int(0.5 + float64((endDate-startDate)/86400)))
13284 }
13285
13286 // WEEKDAY function returns an integer representing the day of the week for a
13287 // supplied date. The syntax of the function is:
13288 //
13289 //      WEEKDAY(serial_number,[return_type])
13290 func (fn *formulaFuncs) WEEKDAY(argsList *list.List) formulaArg {
13291         if argsList.Len() < 1 {
13292                 return newErrorFormulaArg(formulaErrorVALUE, "WEEKDAY requires at least 1 argument")
13293         }
13294         if argsList.Len() > 2 {
13295                 return newErrorFormulaArg(formulaErrorVALUE, "WEEKDAY allows at most 2 arguments")
13296         }
13297         sn := argsList.Front().Value.(formulaArg)
13298         num := sn.ToNumber()
13299         weekday, returnType := 0, 1
13300         if num.Type != ArgNumber {
13301                 dateString := strings.ToLower(sn.Value())
13302                 if !isDateOnlyFmt(dateString) {
13303                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
13304                                 return err
13305                         }
13306                 }
13307                 y, m, d, _, err := strToDate(dateString)
13308                 if err.Type == ArgError {
13309                         return err
13310                 }
13311                 weekday = int(time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.Now().Location()).Weekday())
13312         } else {
13313                 if num.Number < 0 {
13314                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
13315                 }
13316                 weekday = int(timeFromExcelTime(num.Number, false).Weekday())
13317         }
13318         if argsList.Len() == 2 {
13319                 returnTypeArg := argsList.Back().Value.(formulaArg).ToNumber()
13320                 if returnTypeArg.Type != ArgNumber {
13321                         return returnTypeArg
13322                 }
13323                 returnType = int(returnTypeArg.Number)
13324         }
13325         if returnType == 2 {
13326                 returnType = 11
13327         }
13328         weekday++
13329         if returnType == 1 {
13330                 return newNumberFormulaArg(float64(weekday))
13331         }
13332         if returnType == 3 {
13333                 return newNumberFormulaArg(float64((weekday + 6 - 1) % 7))
13334         }
13335         if returnType >= 11 && returnType <= 17 {
13336                 return newNumberFormulaArg(float64((weekday+6-(returnType-10))%7 + 1))
13337         }
13338         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13339 }
13340
13341 // weeknum is an implementation of the formula function WEEKNUM.
13342 func (fn *formulaFuncs) weeknum(snTime time.Time, returnType int) formulaArg {
13343         days := snTime.YearDay()
13344         weekMod, weekNum := days%7, math.Ceil(float64(days)/7)
13345         if weekMod == 0 {
13346                 weekMod = 7
13347         }
13348         year := snTime.Year()
13349         firstWeekday := int(time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC).Weekday())
13350         var offset int
13351         switch returnType {
13352         case 1, 17:
13353                 offset = 0
13354         case 2, 11, 21:
13355                 offset = 1
13356         case 12, 13, 14, 15, 16:
13357                 offset = returnType - 10
13358         default:
13359                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
13360         }
13361         padding := offset + 7 - firstWeekday
13362         if padding > 7 {
13363                 padding -= 7
13364         }
13365         if weekMod > padding {
13366                 weekNum++
13367         }
13368         if returnType == 21 && (firstWeekday == 0 || firstWeekday > 4) {
13369                 if weekNum--; weekNum < 1 {
13370                         if weekNum = 52; int(time.Date(year-1, time.January, 1, 0, 0, 0, 0, time.UTC).Weekday()) < 4 {
13371                                 weekNum++
13372                         }
13373                 }
13374         }
13375         return newNumberFormulaArg(weekNum)
13376 }
13377
13378 // WEEKNUM function returns an integer representing the week number (from 1 to
13379 // 53) of the year. The syntax of the function is:
13380 //
13381 //      WEEKNUM(serial_number,[return_type])
13382 func (fn *formulaFuncs) WEEKNUM(argsList *list.List) formulaArg {
13383         if argsList.Len() < 1 {
13384                 return newErrorFormulaArg(formulaErrorVALUE, "WEEKNUM requires at least 1 argument")
13385         }
13386         if argsList.Len() > 2 {
13387                 return newErrorFormulaArg(formulaErrorVALUE, "WEEKNUM allows at most 2 arguments")
13388         }
13389         sn := argsList.Front().Value.(formulaArg)
13390         num, returnType := sn.ToNumber(), 1
13391         var snTime time.Time
13392         if num.Type != ArgNumber {
13393                 dateString := strings.ToLower(sn.Value())
13394                 if !isDateOnlyFmt(dateString) {
13395                         if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError {
13396                                 return err
13397                         }
13398                 }
13399                 y, m, d, _, err := strToDate(dateString)
13400                 if err.Type == ArgError {
13401                         return err
13402                 }
13403                 snTime = time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.Now().Location())
13404         } else {
13405                 if num.Number < 0 {
13406                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
13407                 }
13408                 snTime = timeFromExcelTime(num.Number, false)
13409         }
13410         if argsList.Len() == 2 {
13411                 returnTypeArg := argsList.Back().Value.(formulaArg).ToNumber()
13412                 if returnTypeArg.Type != ArgNumber {
13413                         return returnTypeArg
13414                 }
13415                 returnType = int(returnTypeArg.Number)
13416         }
13417         return fn.weeknum(snTime, returnType)
13418 }
13419
13420 // Text Functions
13421
13422 // prepareToText checking and prepare arguments for the formula functions
13423 // ARRAYTOTEXT and VALUETOTEXT.
13424 func prepareToText(name string, argsList *list.List) formulaArg {
13425         if argsList.Len() < 1 {
13426                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
13427         }
13428         if argsList.Len() > 2 {
13429                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s allows at most 2 arguments", name))
13430         }
13431         format := newNumberFormulaArg(0)
13432         if argsList.Len() == 2 {
13433                 if format = argsList.Back().Value.(formulaArg).ToNumber(); format.Type != ArgNumber {
13434                         return format
13435                 }
13436         }
13437         if format.Number != 0 && format.Number != 1 {
13438                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13439         }
13440         return format
13441 }
13442
13443 // ARRAYTOTEXT function returns an array of text values from any specified
13444 // range. It passes text values unchanged, and converts non-text values to
13445 // text. The syntax of the function is:
13446 //
13447 //      ARRAYTOTEXT(array,[format])
13448 func (fn *formulaFuncs) ARRAYTOTEXT(argsList *list.List) formulaArg {
13449         var mtx [][]string
13450         format := prepareToText("ARRAYTOTEXT", argsList)
13451         if format.Type != ArgNumber {
13452                 return format
13453         }
13454         for _, rows := range argsList.Front().Value.(formulaArg).Matrix {
13455                 var row []string
13456                 for _, cell := range rows {
13457                         if num := cell.ToNumber(); num.Type != ArgNumber && format.Number == 1 {
13458                                 row = append(row, fmt.Sprintf("\"%s\"", cell.Value()))
13459                                 continue
13460                         }
13461                         row = append(row, cell.Value())
13462                 }
13463                 mtx = append(mtx, row)
13464         }
13465         var text []string
13466         for _, row := range mtx {
13467                 if format.Number == 1 {
13468                         text = append(text, strings.Join(row, ","))
13469                         continue
13470                 }
13471                 text = append(text, strings.Join(row, ", "))
13472         }
13473         if format.Number == 1 {
13474                 return newStringFormulaArg(fmt.Sprintf("{%s}", strings.Join(text, ";")))
13475         }
13476         return newStringFormulaArg(strings.Join(text, ", "))
13477 }
13478
13479 // CHAR function returns the character relating to a supplied character set
13480 // number (from 1 to 255). The syntax of the function is:
13481 //
13482 //      CHAR(number)
13483 func (fn *formulaFuncs) CHAR(argsList *list.List) formulaArg {
13484         if argsList.Len() != 1 {
13485                 return newErrorFormulaArg(formulaErrorVALUE, "CHAR requires 1 argument")
13486         }
13487         arg := argsList.Front().Value.(formulaArg).ToNumber()
13488         if arg.Type != ArgNumber {
13489                 return arg
13490         }
13491         num := int(arg.Number)
13492         if num < 0 || num > MaxFieldLength {
13493                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13494         }
13495         return newStringFormulaArg(fmt.Sprintf("%c", num))
13496 }
13497
13498 // CLEAN removes all non-printable characters from a supplied text string. The
13499 // syntax of the function is:
13500 //
13501 //      CLEAN(text)
13502 func (fn *formulaFuncs) CLEAN(argsList *list.List) formulaArg {
13503         if argsList.Len() != 1 {
13504                 return newErrorFormulaArg(formulaErrorVALUE, "CLEAN requires 1 argument")
13505         }
13506         b := bytes.Buffer{}
13507         for _, c := range argsList.Front().Value.(formulaArg).Value() {
13508                 if c > 31 {
13509                         b.WriteRune(c)
13510                 }
13511         }
13512         return newStringFormulaArg(b.String())
13513 }
13514
13515 // CODE function converts the first character of a supplied text string into
13516 // the associated numeric character set code used by your computer. The
13517 // syntax of the function is:
13518 //
13519 //      CODE(text)
13520 func (fn *formulaFuncs) CODE(argsList *list.List) formulaArg {
13521         return fn.code("CODE", argsList)
13522 }
13523
13524 // code is an implementation of the formula functions CODE and UNICODE.
13525 func (fn *formulaFuncs) code(name string, argsList *list.List) formulaArg {
13526         if argsList.Len() != 1 {
13527                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 1 argument", name))
13528         }
13529         text := argsList.Front().Value.(formulaArg).Value()
13530         if len(text) == 0 {
13531                 if name == "CODE" {
13532                         return newNumberFormulaArg(0)
13533                 }
13534                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13535         }
13536         return newNumberFormulaArg(float64(text[0]))
13537 }
13538
13539 // CONCAT function joins together a series of supplied text strings into one
13540 // combined text string.
13541 //
13542 //      CONCAT(text1,[text2],...)
13543 func (fn *formulaFuncs) CONCAT(argsList *list.List) formulaArg {
13544         return fn.concat("CONCAT", argsList)
13545 }
13546
13547 // CONCATENATE function joins together a series of supplied text strings into
13548 // one combined text string.
13549 //
13550 //      CONCATENATE(text1,[text2],...)
13551 func (fn *formulaFuncs) CONCATENATE(argsList *list.List) formulaArg {
13552         return fn.concat("CONCATENATE", argsList)
13553 }
13554
13555 // concat is an implementation of the formula functions CONCAT and
13556 // CONCATENATE.
13557 func (fn *formulaFuncs) concat(name string, argsList *list.List) formulaArg {
13558         var buf bytes.Buffer
13559         for arg := argsList.Front(); arg != nil; arg = arg.Next() {
13560                 for _, cell := range arg.Value.(formulaArg).ToList() {
13561                         if cell.Type == ArgError {
13562                                 return cell
13563                         }
13564                         buf.WriteString(cell.Value())
13565                 }
13566         }
13567         return newStringFormulaArg(buf.String())
13568 }
13569
13570 // DBCS converts half-width (single-byte) letters within a character string to
13571 // full-width (double-byte) characters. The syntax of the function is:
13572 //
13573 //      DBCS(text)
13574 func (fn *formulaFuncs) DBCS(argsList *list.List) formulaArg {
13575         if argsList.Len() != 1 {
13576                 return newErrorFormulaArg(formulaErrorVALUE, "DBCS requires 1 argument")
13577         }
13578         arg := argsList.Front().Value.(formulaArg)
13579         if arg.Type == ArgError {
13580                 return arg
13581         }
13582         if fn.f.options.CultureInfo == CultureNameZhCN {
13583                 var chars []string
13584                 for _, r := range arg.Value() {
13585                         code := r
13586                         if code == 32 {
13587                                 code = 12288
13588                         } else {
13589                                 code += 65248
13590                         }
13591                         if (code < 32 || code > 126) && r != 165 && code < 65381 {
13592                                 chars = append(chars, string(code))
13593                         } else {
13594                                 chars = append(chars, string(r))
13595                         }
13596                 }
13597                 return newStringFormulaArg(strings.Join(chars, ""))
13598         }
13599         return arg
13600 }
13601
13602 // EXACT function tests if two supplied text strings or values are exactly
13603 // equal and if so, returns TRUE; Otherwise, the function returns FALSE. The
13604 // function is case-sensitive. The syntax of the function is:
13605 //
13606 //      EXACT(text1,text2)
13607 func (fn *formulaFuncs) EXACT(argsList *list.List) formulaArg {
13608         if argsList.Len() != 2 {
13609                 return newErrorFormulaArg(formulaErrorVALUE, "EXACT requires 2 arguments")
13610         }
13611         text1 := argsList.Front().Value.(formulaArg).Value()
13612         text2 := argsList.Back().Value.(formulaArg).Value()
13613         return newBoolFormulaArg(text1 == text2)
13614 }
13615
13616 // FIXED function rounds a supplied number to a specified number of decimal
13617 // places and then converts this into text. The syntax of the function is:
13618 //
13619 //      FIXED(number,[decimals],[no_commas])
13620 func (fn *formulaFuncs) FIXED(argsList *list.List) formulaArg {
13621         if argsList.Len() < 1 {
13622                 return newErrorFormulaArg(formulaErrorVALUE, "FIXED requires at least 1 argument")
13623         }
13624         if argsList.Len() > 3 {
13625                 return newErrorFormulaArg(formulaErrorVALUE, "FIXED allows at most 3 arguments")
13626         }
13627         numArg := argsList.Front().Value.(formulaArg).ToNumber()
13628         if numArg.Type != ArgNumber {
13629                 return numArg
13630         }
13631         precision, decimals, noCommas := 0, 0, false
13632         s := strings.Split(argsList.Front().Value.(formulaArg).Value(), ".")
13633         if argsList.Len() == 1 && len(s) == 2 {
13634                 precision = len(s[1])
13635                 decimals = len(s[1])
13636         }
13637         if argsList.Len() >= 2 {
13638                 decimalsArg := argsList.Front().Next().Value.(formulaArg).ToNumber()
13639                 if decimalsArg.Type != ArgNumber {
13640                         return decimalsArg
13641                 }
13642                 decimals = int(decimalsArg.Number)
13643         }
13644         if argsList.Len() == 3 {
13645                 noCommasArg := argsList.Back().Value.(formulaArg).ToBool()
13646                 if noCommasArg.Type == ArgError {
13647                         return noCommasArg
13648                 }
13649                 noCommas = noCommasArg.Boolean
13650         }
13651         n := math.Pow(10, float64(decimals))
13652         r := numArg.Number * n
13653         fixed := float64(int(r+math.Copysign(0.5, r))) / n
13654         if decimals > 0 {
13655                 precision = decimals
13656         }
13657         if noCommas {
13658                 return newStringFormulaArg(fmt.Sprintf(fmt.Sprintf("%%.%df", precision), fixed))
13659         }
13660         p := message.NewPrinter(language.English)
13661         return newStringFormulaArg(p.Sprintf(fmt.Sprintf("%%.%df", precision), fixed))
13662 }
13663
13664 // FIND function returns the position of a specified character or sub-string
13665 // within a supplied text string. The function is case-sensitive. The syntax
13666 // of the function is:
13667 //
13668 //      FIND(find_text,within_text,[start_num])
13669 func (fn *formulaFuncs) FIND(argsList *list.List) formulaArg {
13670         return fn.find("FIND", argsList)
13671 }
13672
13673 // FINDB counts each double-byte character as 2 when you have enabled the
13674 // editing of a language that supports DBCS and then set it as the default
13675 // language. Otherwise, FINDB counts each character as 1. The syntax of the
13676 // function is:
13677 //
13678 //      FINDB(find_text,within_text,[start_num])
13679 func (fn *formulaFuncs) FINDB(argsList *list.List) formulaArg {
13680         return fn.find("FINDB", argsList)
13681 }
13682
13683 // prepareFindArgs checking and prepare arguments for the formula functions
13684 // FIND, FINDB, SEARCH and SEARCHB.
13685 func (fn *formulaFuncs) prepareFindArgs(name string, argsList *list.List) formulaArg {
13686         if argsList.Len() < 2 {
13687                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 2 arguments", name))
13688         }
13689         if argsList.Len() > 3 {
13690                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s allows at most 3 arguments", name))
13691         }
13692         startNum := 1
13693         if argsList.Len() == 3 {
13694                 numArg := argsList.Back().Value.(formulaArg).ToNumber()
13695                 if numArg.Type != ArgNumber {
13696                         return numArg
13697                 }
13698                 if numArg.Number < 0 {
13699                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13700                 }
13701                 startNum = int(numArg.Number)
13702         }
13703         return newListFormulaArg([]formulaArg{newNumberFormulaArg(float64(startNum))})
13704 }
13705
13706 // find is an implementation of the formula functions FIND, FINDB, SEARCH and
13707 // SEARCHB.
13708 func (fn *formulaFuncs) find(name string, argsList *list.List) formulaArg {
13709         args := fn.prepareFindArgs(name, argsList)
13710         if args.Type != ArgList {
13711                 return args
13712         }
13713         findText := argsList.Front().Value.(formulaArg).Value()
13714         withinText := argsList.Front().Next().Value.(formulaArg).Value()
13715         startNum := int(args.List[0].Number)
13716         if findText == "" {
13717                 return newNumberFormulaArg(float64(startNum))
13718         }
13719         dbcs, search := name == "FINDB" || name == "SEARCHB", name == "SEARCH" || name == "SEARCHB"
13720         if search {
13721                 findText, withinText = strings.ToUpper(findText), strings.ToUpper(withinText)
13722         }
13723         offset, ok := matchPattern(findText, withinText, dbcs, startNum)
13724         if !ok {
13725                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13726         }
13727         result := offset
13728         if dbcs {
13729                 var pre int
13730                 for idx := range withinText {
13731                         if pre > offset {
13732                                 break
13733                         }
13734                         if idx-pre > 1 {
13735                                 result++
13736                         }
13737                         pre = idx
13738                 }
13739         }
13740         return newNumberFormulaArg(float64(result))
13741 }
13742
13743 // LEFT function returns a specified number of characters from the start of a
13744 // supplied text string. The syntax of the function is:
13745 //
13746 //      LEFT(text,[num_chars])
13747 func (fn *formulaFuncs) LEFT(argsList *list.List) formulaArg {
13748         return fn.leftRight("LEFT", argsList)
13749 }
13750
13751 // LEFTB returns the first character or characters in a text string, based on
13752 // the number of bytes you specify. The syntax of the function is:
13753 //
13754 //      LEFTB(text,[num_bytes])
13755 func (fn *formulaFuncs) LEFTB(argsList *list.List) formulaArg {
13756         return fn.leftRight("LEFTB", argsList)
13757 }
13758
13759 // leftRight is an implementation of the formula functions LEFT, LEFTB, RIGHT,
13760 // RIGHTB.
13761 func (fn *formulaFuncs) leftRight(name string, argsList *list.List) formulaArg {
13762         if argsList.Len() < 1 {
13763                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
13764         }
13765         if argsList.Len() > 2 {
13766                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s allows at most 2 arguments", name))
13767         }
13768         text, numChars := argsList.Front().Value.(formulaArg).Value(), 1
13769         if argsList.Len() == 2 {
13770                 numArg := argsList.Back().Value.(formulaArg).ToNumber()
13771                 if numArg.Type != ArgNumber {
13772                         return numArg
13773                 }
13774                 if numArg.Number < 0 {
13775                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13776                 }
13777                 numChars = int(numArg.Number)
13778         }
13779         if name == "LEFTB" || name == "RIGHTB" {
13780                 if len(text) > numChars {
13781                         if name == "LEFTB" {
13782                                 return newStringFormulaArg(text[:numChars])
13783                         }
13784                         // RIGHTB
13785                         return newStringFormulaArg(text[len(text)-numChars:])
13786                 }
13787                 return newStringFormulaArg(text)
13788         }
13789         // LEFT/RIGHT
13790         if utf8.RuneCountInString(text) > numChars {
13791                 if name == "LEFT" {
13792                         return newStringFormulaArg(string([]rune(text)[:numChars]))
13793                 }
13794                 // RIGHT
13795                 return newStringFormulaArg(string([]rune(text)[utf8.RuneCountInString(text)-numChars:]))
13796         }
13797         return newStringFormulaArg(text)
13798 }
13799
13800 // LEN returns the length of a supplied text string. The syntax of the
13801 // function is:
13802 //
13803 //      LEN(text)
13804 func (fn *formulaFuncs) LEN(argsList *list.List) formulaArg {
13805         if argsList.Len() != 1 {
13806                 return newErrorFormulaArg(formulaErrorVALUE, "LEN requires 1 string argument")
13807         }
13808         return newNumberFormulaArg(float64(utf8.RuneCountInString(argsList.Front().Value.(formulaArg).Value())))
13809 }
13810
13811 // LENB returns the number of bytes used to represent the characters in a text
13812 // string. LENB counts 2 bytes per character only when a DBCS language is set
13813 // as the default language. Otherwise LENB behaves the same as LEN, counting
13814 // 1 byte per character. The syntax of the function is:
13815 //
13816 //      LENB(text)
13817 func (fn *formulaFuncs) LENB(argsList *list.List) formulaArg {
13818         if argsList.Len() != 1 {
13819                 return newErrorFormulaArg(formulaErrorVALUE, "LENB requires 1 string argument")
13820         }
13821         bytes := 0
13822         for _, r := range argsList.Front().Value.(formulaArg).Value() {
13823                 b := utf8.RuneLen(r)
13824                 if b == 1 {
13825                         bytes++
13826                 } else if b > 1 {
13827                         bytes += 2
13828                 }
13829         }
13830         return newNumberFormulaArg(float64(bytes))
13831 }
13832
13833 // LOWER converts all characters in a supplied text string to lower case. The
13834 // syntax of the function is:
13835 //
13836 //      LOWER(text)
13837 func (fn *formulaFuncs) LOWER(argsList *list.List) formulaArg {
13838         if argsList.Len() != 1 {
13839                 return newErrorFormulaArg(formulaErrorVALUE, "LOWER requires 1 argument")
13840         }
13841         return newStringFormulaArg(strings.ToLower(argsList.Front().Value.(formulaArg).Value()))
13842 }
13843
13844 // MID function returns a specified number of characters from the middle of a
13845 // supplied text string. The syntax of the function is:
13846 //
13847 //      MID(text,start_num,num_chars)
13848 func (fn *formulaFuncs) MID(argsList *list.List) formulaArg {
13849         return fn.mid("MID", argsList)
13850 }
13851
13852 // MIDB returns a specific number of characters from a text string, starting
13853 // at the position you specify, based on the number of bytes you specify. The
13854 // syntax of the function is:
13855 //
13856 //      MID(text,start_num,num_chars)
13857 func (fn *formulaFuncs) MIDB(argsList *list.List) formulaArg {
13858         return fn.mid("MIDB", argsList)
13859 }
13860
13861 // mid is an implementation of the formula functions MID and MIDB.
13862 func (fn *formulaFuncs) mid(name string, argsList *list.List) formulaArg {
13863         if argsList.Len() != 3 {
13864                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 arguments", name))
13865         }
13866         text := argsList.Front().Value.(formulaArg).Value()
13867         startNumArg, numCharsArg := argsList.Front().Next().Value.(formulaArg).ToNumber(), argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
13868         if startNumArg.Type != ArgNumber {
13869                 return startNumArg
13870         }
13871         if numCharsArg.Type != ArgNumber {
13872                 return numCharsArg
13873         }
13874         startNum := int(startNumArg.Number)
13875         if startNum < 1 || numCharsArg.Number < 0 {
13876                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13877         }
13878         if name == "MIDB" {
13879                 var result string
13880                 var cnt, offset int
13881                 for _, char := range text {
13882                         offset++
13883                         var dbcs bool
13884                         if utf8.RuneLen(char) > 1 {
13885                                 dbcs = true
13886                                 offset++
13887                         }
13888                         if cnt == int(numCharsArg.Number) {
13889                                 break
13890                         }
13891                         if offset+1 > startNum {
13892                                 if dbcs {
13893                                         if cnt+2 > int(numCharsArg.Number) {
13894                                                 result += string(char)[:1]
13895                                                 break
13896                                         }
13897                                         result += string(char)
13898                                         cnt += 2
13899                                 } else {
13900                                         result += string(char)
13901                                         cnt++
13902                                 }
13903                         }
13904                 }
13905                 return newStringFormulaArg(result)
13906         }
13907         // MID
13908         textLen := utf8.RuneCountInString(text)
13909         if startNum > textLen {
13910                 return newStringFormulaArg("")
13911         }
13912         startNum--
13913         endNum := startNum + int(numCharsArg.Number)
13914         if endNum > textLen+1 {
13915                 return newStringFormulaArg(string([]rune(text)[startNum:]))
13916         }
13917         return newStringFormulaArg(string([]rune(text)[startNum:endNum]))
13918 }
13919
13920 // PROPER converts all characters in a supplied text string to proper case
13921 // (i.e. all letters that do not immediately follow another letter are set to
13922 // upper case and all other characters are lower case). The syntax of the
13923 // function is:
13924 //
13925 //      PROPER(text)
13926 func (fn *formulaFuncs) PROPER(argsList *list.List) formulaArg {
13927         if argsList.Len() != 1 {
13928                 return newErrorFormulaArg(formulaErrorVALUE, "PROPER requires 1 argument")
13929         }
13930         buf := bytes.Buffer{}
13931         isLetter := false
13932         for _, char := range argsList.Front().Value.(formulaArg).Value() {
13933                 if !isLetter && unicode.IsLetter(char) {
13934                         buf.WriteRune(unicode.ToUpper(char))
13935                 } else {
13936                         buf.WriteRune(unicode.ToLower(char))
13937                 }
13938                 isLetter = unicode.IsLetter(char)
13939         }
13940         return newStringFormulaArg(buf.String())
13941 }
13942
13943 // REPLACE function replaces all or part of a text string with another string.
13944 // The syntax of the function is:
13945 //
13946 //      REPLACE(old_text,start_num,num_chars,new_text)
13947 func (fn *formulaFuncs) REPLACE(argsList *list.List) formulaArg {
13948         return fn.replace("REPLACE", argsList)
13949 }
13950
13951 // REPLACEB replaces part of a text string, based on the number of bytes you
13952 // specify, with a different text string.
13953 //
13954 //      REPLACEB(old_text,start_num,num_chars,new_text)
13955 func (fn *formulaFuncs) REPLACEB(argsList *list.List) formulaArg {
13956         return fn.replace("REPLACEB", argsList)
13957 }
13958
13959 // replace is an implementation of the formula functions REPLACE and REPLACEB.
13960 // TODO: support DBCS include Japanese, Chinese (Simplified), Chinese
13961 // (Traditional), and Korean.
13962 func (fn *formulaFuncs) replace(name string, argsList *list.List) formulaArg {
13963         if argsList.Len() != 4 {
13964                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 4 arguments", name))
13965         }
13966         sourceText, targetText := argsList.Front().Value.(formulaArg).Value(), argsList.Back().Value.(formulaArg).Value()
13967         startNumArg, numCharsArg := argsList.Front().Next().Value.(formulaArg).ToNumber(), argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
13968         if startNumArg.Type != ArgNumber {
13969                 return startNumArg
13970         }
13971         if numCharsArg.Type != ArgNumber {
13972                 return numCharsArg
13973         }
13974         sourceTextLen, startIdx := len(sourceText), int(startNumArg.Number)
13975         if startIdx > sourceTextLen {
13976                 startIdx = sourceTextLen + 1
13977         }
13978         endIdx := startIdx + int(numCharsArg.Number)
13979         if endIdx > sourceTextLen {
13980                 endIdx = sourceTextLen + 1
13981         }
13982         if startIdx < 1 || endIdx < 1 {
13983                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
13984         }
13985         result := sourceText[:startIdx-1] + targetText + sourceText[endIdx-1:]
13986         return newStringFormulaArg(result)
13987 }
13988
13989 // REPT function returns a supplied text string, repeated a specified number
13990 // of times. The syntax of the function is:
13991 //
13992 //      REPT(text,number_times)
13993 func (fn *formulaFuncs) REPT(argsList *list.List) formulaArg {
13994         if argsList.Len() != 2 {
13995                 return newErrorFormulaArg(formulaErrorVALUE, "REPT requires 2 arguments")
13996         }
13997         text := argsList.Front().Value.(formulaArg)
13998         if text.Type != ArgString {
13999                 return newErrorFormulaArg(formulaErrorVALUE, "REPT requires first argument to be a string")
14000         }
14001         times := argsList.Back().Value.(formulaArg).ToNumber()
14002         if times.Type != ArgNumber {
14003                 return newErrorFormulaArg(formulaErrorVALUE, "REPT requires second argument to be a number")
14004         }
14005         if times.Number < 0 {
14006                 return newErrorFormulaArg(formulaErrorVALUE, "REPT requires second argument to be >= 0")
14007         }
14008         if times.Number == 0 {
14009                 return newStringFormulaArg("")
14010         }
14011         buf := bytes.Buffer{}
14012         for i := 0; i < int(times.Number); i++ {
14013                 buf.WriteString(text.Value())
14014         }
14015         return newStringFormulaArg(buf.String())
14016 }
14017
14018 // RIGHT function returns a specified number of characters from the end of a
14019 // supplied text string. The syntax of the function is:
14020 //
14021 //      RIGHT(text,[num_chars])
14022 func (fn *formulaFuncs) RIGHT(argsList *list.List) formulaArg {
14023         return fn.leftRight("RIGHT", argsList)
14024 }
14025
14026 // RIGHTB returns the last character or characters in a text string, based on
14027 // the number of bytes you specify. The syntax of the function is:
14028 //
14029 //      RIGHTB(text,[num_bytes])
14030 func (fn *formulaFuncs) RIGHTB(argsList *list.List) formulaArg {
14031         return fn.leftRight("RIGHTB", argsList)
14032 }
14033
14034 // SEARCH function returns the position of a specified character or sub-string
14035 // within a supplied text string. The syntax of the function is:
14036 //
14037 //      SEARCH(search_text,within_text,[start_num])
14038 func (fn *formulaFuncs) SEARCH(argsList *list.List) formulaArg {
14039         return fn.find("SEARCH", argsList)
14040 }
14041
14042 // SEARCHB functions locate one text string within a second text string, and
14043 // return the number of the starting position of the first text string from the
14044 // first character of the second text string. The syntax of the function is:
14045 //
14046 //      SEARCHB(search_text,within_text,[start_num])
14047 func (fn *formulaFuncs) SEARCHB(argsList *list.List) formulaArg {
14048         return fn.find("SEARCHB", argsList)
14049 }
14050
14051 // SUBSTITUTE function replaces one or more instances of a given text string,
14052 // within an original text string. The syntax of the function is:
14053 //
14054 //      SUBSTITUTE(text,old_text,new_text,[instance_num])
14055 func (fn *formulaFuncs) SUBSTITUTE(argsList *list.List) formulaArg {
14056         if argsList.Len() != 3 && argsList.Len() != 4 {
14057                 return newErrorFormulaArg(formulaErrorVALUE, "SUBSTITUTE requires 3 or 4 arguments")
14058         }
14059         text, sourceText := argsList.Front().Value.(formulaArg), argsList.Front().Next().Value.(formulaArg)
14060         targetText, instanceNum := argsList.Front().Next().Next().Value.(formulaArg), 0
14061         if argsList.Len() == 3 {
14062                 return newStringFormulaArg(strings.ReplaceAll(text.Value(), sourceText.Value(), targetText.Value()))
14063         }
14064         instanceNumArg := argsList.Back().Value.(formulaArg).ToNumber()
14065         if instanceNumArg.Type != ArgNumber {
14066                 return instanceNumArg
14067         }
14068         instanceNum = int(instanceNumArg.Number)
14069         if instanceNum < 1 {
14070                 return newErrorFormulaArg(formulaErrorVALUE, "instance_num should be > 0")
14071         }
14072         str, sourceTextLen, count, chars, pos := text.Value(), len(sourceText.Value()), instanceNum, 0, -1
14073         for {
14074                 count--
14075                 index := strings.Index(str, sourceText.Value())
14076                 if index == -1 {
14077                         pos = -1
14078                         break
14079                 } else {
14080                         pos = index + chars
14081                         if count == 0 {
14082                                 break
14083                         }
14084                         idx := sourceTextLen + index
14085                         chars += idx
14086                         str = str[idx:]
14087                 }
14088         }
14089         if pos == -1 {
14090                 return newStringFormulaArg(text.Value())
14091         }
14092         pre, post := text.Value()[:pos], text.Value()[pos+sourceTextLen:]
14093         return newStringFormulaArg(pre + targetText.Value() + post)
14094 }
14095
14096 // TEXT function converts a supplied numeric value into text, in a
14097 // user-specified format. The syntax of the function is:
14098 //
14099 //      TEXT(value,format_text)
14100 func (fn *formulaFuncs) TEXT(argsList *list.List) formulaArg {
14101         if argsList.Len() != 2 {
14102                 return newErrorFormulaArg(formulaErrorVALUE, "TEXT requires 2 arguments")
14103         }
14104         value, fmtText := argsList.Front().Value.(formulaArg), argsList.Back().Value.(formulaArg)
14105         if value.Type == ArgError {
14106                 return value
14107         }
14108         if fmtText.Type == ArgError {
14109                 return fmtText
14110         }
14111         cellType := CellTypeNumber
14112         if num := value.ToNumber(); num.Type != ArgNumber {
14113                 cellType = CellTypeSharedString
14114         }
14115         return newStringFormulaArg(format(value.Value(), fmtText.Value(), false, cellType, nil))
14116 }
14117
14118 // prepareTextAfterBefore checking and prepare arguments for the formula
14119 // functions TEXTAFTER and TEXTBEFORE.
14120 func (fn *formulaFuncs) prepareTextAfterBefore(name string, argsList *list.List) formulaArg {
14121         argsLen := argsList.Len()
14122         if argsLen < 2 {
14123                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 2 arguments", name))
14124         }
14125         if argsLen > 6 {
14126                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s accepts at most 6 arguments", name))
14127         }
14128         text, delimiter := argsList.Front().Value.(formulaArg), argsList.Front().Next().Value.(formulaArg)
14129         instanceNum, matchMode, matchEnd, ifNotFound := newNumberFormulaArg(1), newBoolFormulaArg(false), newBoolFormulaArg(false), newEmptyFormulaArg()
14130         if argsLen > 2 {
14131                 instanceNum = argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
14132                 if instanceNum.Type != ArgNumber {
14133                         return instanceNum
14134                 }
14135         }
14136         if argsLen > 3 {
14137                 matchMode = argsList.Front().Next().Next().Next().Value.(formulaArg).ToBool()
14138                 if matchMode.Type != ArgNumber {
14139                         return matchMode
14140                 }
14141                 if matchMode.Number == 1 {
14142                         text, delimiter = newStringFormulaArg(strings.ToLower(text.Value())), newStringFormulaArg(strings.ToLower(delimiter.Value()))
14143                 }
14144         }
14145         if argsLen > 4 {
14146                 matchEnd = argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToBool()
14147                 if matchEnd.Type != ArgNumber {
14148                         return matchEnd
14149                 }
14150         }
14151         if argsLen > 5 {
14152                 ifNotFound = argsList.Back().Value.(formulaArg)
14153         }
14154         if text.Value() == "" {
14155                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
14156         }
14157         lenArgsList := list.New().Init()
14158         lenArgsList.PushBack(text)
14159         textLen := fn.LEN(lenArgsList)
14160         if instanceNum.Number == 0 || instanceNum.Number > textLen.Number {
14161                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14162         }
14163         reverseSearch, startPos := instanceNum.Number < 0, 0.0
14164         if reverseSearch {
14165                 startPos = textLen.Number
14166         }
14167         return newListFormulaArg([]formulaArg{
14168                 text, delimiter, instanceNum, matchMode, matchEnd, ifNotFound,
14169                 textLen, newBoolFormulaArg(reverseSearch), newNumberFormulaArg(startPos),
14170         })
14171 }
14172
14173 // textAfterBeforeSearch is an implementation of the formula functions TEXTAFTER
14174 // and TEXTBEFORE.
14175 func textAfterBeforeSearch(text string, delimiter []string, startPos int, reverseSearch bool) (int, string) {
14176         idx := -1
14177         var modifiedDelimiter string
14178         for i := 0; i < len(delimiter); i++ {
14179                 nextDelimiter := delimiter[i]
14180                 nextIdx := strings.Index(text[startPos:], nextDelimiter)
14181                 if nextIdx != -1 {
14182                         nextIdx += startPos
14183                 }
14184                 if reverseSearch {
14185                         nextIdx = strings.LastIndex(text[:startPos], nextDelimiter)
14186                 }
14187                 if idx == -1 || (((nextIdx < idx && !reverseSearch) || (nextIdx > idx && reverseSearch)) && idx != -1) {
14188                         idx = nextIdx
14189                         modifiedDelimiter = nextDelimiter
14190                 }
14191         }
14192         return idx, modifiedDelimiter
14193 }
14194
14195 // textAfterBeforeResult is an implementation of the formula functions TEXTAFTER
14196 // and TEXTBEFORE.
14197 func textAfterBeforeResult(name, modifiedDelimiter string, text []rune, foundIdx, repeatZero, textLen int, matchEndActive, matchEnd, reverseSearch bool) formulaArg {
14198         if name == "TEXTAFTER" {
14199                 endPos := len(modifiedDelimiter)
14200                 if (repeatZero > 1 || matchEndActive) && matchEnd && reverseSearch {
14201                         endPos = 0
14202                 }
14203                 if foundIdx+endPos >= textLen {
14204                         return newEmptyFormulaArg()
14205                 }
14206                 return newStringFormulaArg(string(text[foundIdx+endPos : textLen]))
14207         }
14208         return newStringFormulaArg(string(text[:foundIdx]))
14209 }
14210
14211 // textAfterBefore is an implementation of the formula functions TEXTAFTER and
14212 // TEXTBEFORE.
14213 func (fn *formulaFuncs) textAfterBefore(name string, argsList *list.List) formulaArg {
14214         args := fn.prepareTextAfterBefore(name, argsList)
14215         if args.Type != ArgList {
14216                 return args
14217         }
14218         var (
14219                 text                 = []rune(argsList.Front().Value.(formulaArg).Value())
14220                 modifiedText         = args.List[0].Value()
14221                 delimiter            = []string{args.List[1].Value()}
14222                 instanceNum          = args.List[2].Number
14223                 matchEnd             = args.List[4].Number == 1
14224                 ifNotFound           = args.List[5]
14225                 textLen              = args.List[6]
14226                 reverseSearch        = args.List[7].Number == 1
14227                 foundIdx             = -1
14228                 repeatZero, startPos int
14229                 matchEndActive       bool
14230                 modifiedDelimiter    string
14231         )
14232         if reverseSearch {
14233                 startPos = int(args.List[8].Number)
14234         }
14235         for i := 0; i < int(math.Abs(instanceNum)); i++ {
14236                 foundIdx, modifiedDelimiter = textAfterBeforeSearch(modifiedText, delimiter, startPos, reverseSearch)
14237                 if foundIdx == 0 {
14238                         repeatZero++
14239                 }
14240                 if foundIdx == -1 {
14241                         if matchEnd && i == int(math.Abs(instanceNum))-1 {
14242                                 if foundIdx = int(textLen.Number); reverseSearch {
14243                                         foundIdx = 0
14244                                 }
14245                                 matchEndActive = true
14246                         }
14247                         break
14248                 }
14249                 if startPos = foundIdx + len(modifiedDelimiter); reverseSearch {
14250                         startPos = foundIdx - len(modifiedDelimiter)
14251                 }
14252         }
14253         if foundIdx == -1 {
14254                 return ifNotFound
14255         }
14256         return textAfterBeforeResult(name, modifiedDelimiter, text, foundIdx, repeatZero, int(textLen.Number), matchEndActive, matchEnd, reverseSearch)
14257 }
14258
14259 // TEXTAFTER function returns the text that occurs after a given substring or
14260 // delimiter. The syntax of the function is:
14261 //
14262 //      TEXTAFTER(text,delimiter,[instance_num],[match_mode],[match_end],[if_not_found])
14263 func (fn *formulaFuncs) TEXTAFTER(argsList *list.List) formulaArg {
14264         return fn.textAfterBefore("TEXTAFTER", argsList)
14265 }
14266
14267 // TEXTBEFORE function returns text that occurs before a given character or
14268 // string. The syntax of the function is:
14269 //
14270 //      TEXTBEFORE(text,delimiter,[instance_num],[match_mode],[match_end],[if_not_found])
14271 func (fn *formulaFuncs) TEXTBEFORE(argsList *list.List) formulaArg {
14272         return fn.textAfterBefore("TEXTBEFORE", argsList)
14273 }
14274
14275 // TEXTJOIN function joins together a series of supplied text strings into one
14276 // combined text string. The user can specify a delimiter to add between the
14277 // individual text items, if required. The syntax of the function is:
14278 //
14279 //      TEXTJOIN([delimiter],[ignore_empty],text1,[text2],...)
14280 func (fn *formulaFuncs) TEXTJOIN(argsList *list.List) formulaArg {
14281         if argsList.Len() < 3 {
14282                 return newErrorFormulaArg(formulaErrorVALUE, "TEXTJOIN requires at least 3 arguments")
14283         }
14284         if argsList.Len() > 252 {
14285                 return newErrorFormulaArg(formulaErrorVALUE, "TEXTJOIN accepts at most 252 arguments")
14286         }
14287         delimiter := argsList.Front().Value.(formulaArg)
14288         ignoreEmpty := argsList.Front().Next().Value.(formulaArg)
14289         if ignoreEmpty.Type != ArgNumber || !ignoreEmpty.Boolean {
14290                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14291         }
14292         args, ok := textJoin(argsList.Front().Next().Next(), []string{}, ignoreEmpty.Number != 0)
14293         if ok.Type != ArgNumber {
14294                 return ok
14295         }
14296         result := strings.Join(args, delimiter.Value())
14297         if len(result) > TotalCellChars {
14298                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("TEXTJOIN function exceeds %d characters", TotalCellChars))
14299         }
14300         return newStringFormulaArg(result)
14301 }
14302
14303 // textJoin is an implementation of the formula function TEXTJOIN.
14304 func textJoin(arg *list.Element, arr []string, ignoreEmpty bool) ([]string, formulaArg) {
14305         for arg.Next(); arg != nil; arg = arg.Next() {
14306                 switch arg.Value.(formulaArg).Type {
14307                 case ArgError:
14308                         return arr, arg.Value.(formulaArg)
14309                 case ArgString, ArgEmpty:
14310                         val := arg.Value.(formulaArg).Value()
14311                         if val != "" || !ignoreEmpty {
14312                                 arr = append(arr, val)
14313                         }
14314                 case ArgNumber:
14315                         arr = append(arr, arg.Value.(formulaArg).Value())
14316                 case ArgMatrix:
14317                         for _, row := range arg.Value.(formulaArg).Matrix {
14318                                 argList := list.New().Init()
14319                                 for _, ele := range row {
14320                                         argList.PushBack(ele)
14321                                 }
14322                                 if argList.Len() > 0 {
14323                                         args, _ := textJoin(argList.Front(), []string{}, ignoreEmpty)
14324                                         arr = append(arr, args...)
14325                                 }
14326                         }
14327                 }
14328         }
14329         return arr, newBoolFormulaArg(true)
14330 }
14331
14332 // TRIM removes extra spaces (i.e. all spaces except for single spaces between
14333 // words or characters) from a supplied text string. The syntax of the
14334 // function is:
14335 //
14336 //      TRIM(text)
14337 func (fn *formulaFuncs) TRIM(argsList *list.List) formulaArg {
14338         if argsList.Len() != 1 {
14339                 return newErrorFormulaArg(formulaErrorVALUE, "TRIM requires 1 argument")
14340         }
14341         return newStringFormulaArg(strings.TrimSpace(argsList.Front().Value.(formulaArg).Value()))
14342 }
14343
14344 // UNICHAR returns the Unicode character that is referenced by the given
14345 // numeric value. The syntax of the function is:
14346 //
14347 //      UNICHAR(number)
14348 func (fn *formulaFuncs) UNICHAR(argsList *list.List) formulaArg {
14349         if argsList.Len() != 1 {
14350                 return newErrorFormulaArg(formulaErrorVALUE, "UNICHAR requires 1 argument")
14351         }
14352         numArg := argsList.Front().Value.(formulaArg).ToNumber()
14353         if numArg.Type != ArgNumber {
14354                 return numArg
14355         }
14356         if numArg.Number <= 0 || numArg.Number > 55295 {
14357                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14358         }
14359         return newStringFormulaArg(string(rune(numArg.Number)))
14360 }
14361
14362 // UNICODE function returns the code point for the first character of a
14363 // supplied text string. The syntax of the function is:
14364 //
14365 //      UNICODE(text)
14366 func (fn *formulaFuncs) UNICODE(argsList *list.List) formulaArg {
14367         return fn.code("UNICODE", argsList)
14368 }
14369
14370 // UPPER converts all characters in a supplied text string to upper case. The
14371 // syntax of the function is:
14372 //
14373 //      UPPER(text)
14374 func (fn *formulaFuncs) UPPER(argsList *list.List) formulaArg {
14375         if argsList.Len() != 1 {
14376                 return newErrorFormulaArg(formulaErrorVALUE, "UPPER requires 1 argument")
14377         }
14378         return newStringFormulaArg(strings.ToUpper(argsList.Front().Value.(formulaArg).Value()))
14379 }
14380
14381 // VALUE function converts a text string into a numeric value. The syntax of
14382 // the function is:
14383 //
14384 //      VALUE(text)
14385 func (fn *formulaFuncs) VALUE(argsList *list.List) formulaArg {
14386         if argsList.Len() != 1 {
14387                 return newErrorFormulaArg(formulaErrorVALUE, "VALUE requires 1 argument")
14388         }
14389         text := strings.ReplaceAll(argsList.Front().Value.(formulaArg).Value(), ",", "")
14390         percent := 1.0
14391         if strings.HasSuffix(text, "%") {
14392                 percent, text = 0.01, strings.TrimSuffix(text, "%")
14393         }
14394         decimal := big.Float{}
14395         if _, ok := decimal.SetString(text); ok {
14396                 value, _ := decimal.Float64()
14397                 return newNumberFormulaArg(value * percent)
14398         }
14399         dateValue, timeValue, errTime, errDate := 0.0, 0.0, false, false
14400         if !isDateOnlyFmt(text) {
14401                 h, m, s, _, _, err := strToTime(text)
14402                 errTime = err.Type == ArgError
14403                 if !errTime {
14404                         timeValue = (float64(h)*3600 + float64(m)*60 + s) / 86400
14405                 }
14406         }
14407         y, m, d, _, err := strToDate(text)
14408         errDate = err.Type == ArgError
14409         if !errDate {
14410                 dateValue = daysBetween(excelMinTime1900.Unix(), makeDate(y, time.Month(m), d)) + 1
14411         }
14412         if errTime && errDate {
14413                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14414         }
14415         return newNumberFormulaArg(dateValue + timeValue)
14416 }
14417
14418 // VALUETOTEXT function returns text from any specified value. It passes text
14419 // values unchanged, and converts non-text values to text.
14420 //
14421 //      VALUETOTEXT(value,[format])
14422 func (fn *formulaFuncs) VALUETOTEXT(argsList *list.List) formulaArg {
14423         format := prepareToText("VALUETOTEXT", argsList)
14424         if format.Type != ArgNumber {
14425                 return format
14426         }
14427         cell := argsList.Front().Value.(formulaArg)
14428         if num := cell.ToNumber(); num.Type != ArgNumber && format.Number == 1 {
14429                 return newStringFormulaArg(fmt.Sprintf("\"%s\"", cell.Value()))
14430         }
14431         return newStringFormulaArg(cell.Value())
14432 }
14433
14434 // Conditional Functions
14435
14436 // IF function tests a supplied condition and returns one result if the
14437 // condition evaluates to TRUE, and another result if the condition evaluates
14438 // to FALSE. The syntax of the function is:
14439 //
14440 //      IF(logical_test,value_if_true,value_if_false)
14441 func (fn *formulaFuncs) IF(argsList *list.List) formulaArg {
14442         if argsList.Len() == 0 {
14443                 return newErrorFormulaArg(formulaErrorVALUE, "IF requires at least 1 argument")
14444         }
14445         if argsList.Len() > 3 {
14446                 return newErrorFormulaArg(formulaErrorVALUE, "IF accepts at most 3 arguments")
14447         }
14448         token := argsList.Front().Value.(formulaArg)
14449         var (
14450                 cond   bool
14451                 err    error
14452                 result formulaArg
14453         )
14454         switch token.Type {
14455         case ArgString:
14456                 if cond, err = strconv.ParseBool(token.Value()); err != nil {
14457                         return newErrorFormulaArg(formulaErrorVALUE, err.Error())
14458                 }
14459         case ArgNumber:
14460                 cond = token.Number == 1
14461         }
14462
14463         if argsList.Len() == 1 {
14464                 return newBoolFormulaArg(cond)
14465         }
14466         if cond {
14467                 value := argsList.Front().Next().Value.(formulaArg)
14468                 switch value.Type {
14469                 case ArgNumber:
14470                         result = value.ToNumber()
14471                 default:
14472                         result = newStringFormulaArg(value.Value())
14473                 }
14474                 return result
14475         }
14476         if argsList.Len() == 3 {
14477                 value := argsList.Back().Value.(formulaArg)
14478                 switch value.Type {
14479                 case ArgNumber:
14480                         result = value.ToNumber()
14481                 default:
14482                         result = newStringFormulaArg(value.Value())
14483                 }
14484         }
14485         return result
14486 }
14487
14488 // Lookup and Reference Functions
14489
14490 // ADDRESS function takes a row and a column number and returns a cell
14491 // reference as a text string. The syntax of the function is:
14492 //
14493 //      ADDRESS(row_num,column_num,[abs_num],[a1],[sheet_text])
14494 func (fn *formulaFuncs) ADDRESS(argsList *list.List) formulaArg {
14495         if argsList.Len() < 2 {
14496                 return newErrorFormulaArg(formulaErrorVALUE, "ADDRESS requires at least 2 arguments")
14497         }
14498         if argsList.Len() > 5 {
14499                 return newErrorFormulaArg(formulaErrorVALUE, "ADDRESS requires at most 5 arguments")
14500         }
14501         rowNum := argsList.Front().Value.(formulaArg).ToNumber()
14502         if rowNum.Type != ArgNumber {
14503                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14504         }
14505         if rowNum.Number > TotalRows {
14506                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14507         }
14508         colNum := argsList.Front().Next().Value.(formulaArg).ToNumber()
14509         if colNum.Type != ArgNumber {
14510                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14511         }
14512         absNum := newNumberFormulaArg(1)
14513         if argsList.Len() >= 3 {
14514                 absNum = argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
14515                 if absNum.Type != ArgNumber {
14516                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14517                 }
14518         }
14519         if absNum.Number < 1 || absNum.Number > 4 {
14520                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
14521         }
14522         a1 := newBoolFormulaArg(true)
14523         if argsList.Len() >= 4 {
14524                 a1 = argsList.Front().Next().Next().Next().Value.(formulaArg).ToBool()
14525                 if a1.Type != ArgNumber {
14526                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14527                 }
14528         }
14529         var sheetText string
14530         if argsList.Len() == 5 {
14531                 sheetText = fmt.Sprintf("%s!", argsList.Back().Value.(formulaArg).Value())
14532         }
14533         formatter := addressFmtMaps[fmt.Sprintf("%d_%s", int(absNum.Number), a1.Value())]
14534         addr, err := formatter(int(colNum.Number), int(rowNum.Number))
14535         if err != nil {
14536                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14537         }
14538         return newStringFormulaArg(fmt.Sprintf("%s%s", sheetText, addr))
14539 }
14540
14541 // ANCHORARRAY function returns the entire spilled range for the dynamic array
14542 // in cell. The syntax of the function is:
14543 //
14544 //      ANCHORARRAY(cell)
14545 func (fn *formulaFuncs) ANCHORARRAY(argsList *list.List) formulaArg {
14546         if argsList.Len() != 1 {
14547                 return newErrorFormulaArg(formulaErrorVALUE, "ANCHORARRAY requires 1 numeric argument")
14548         }
14549         ws, err := fn.f.workSheetReader(fn.sheet)
14550         if err != nil {
14551                 return newErrorFormulaArg(formulaErrorVALUE, err.Error())
14552         }
14553         ref := argsList.Front().Value.(formulaArg).cellRefs.Front().Value.(cellRef)
14554         cell := ws.SheetData.Row[ref.Row-1].C[ref.Col-1]
14555         if cell.F == nil {
14556                 return newEmptyFormulaArg()
14557         }
14558         coordinates, err := rangeRefToCoordinates(cell.F.Ref)
14559         if err != nil {
14560                 return newErrorFormulaArg(formulaErrorVALUE, err.Error())
14561         }
14562         _ = sortCoordinates(coordinates)
14563         var mtx [][]formulaArg
14564         for c := coordinates[0]; c <= coordinates[2]; c++ {
14565                 var row []formulaArg
14566                 for r := coordinates[1]; r <= coordinates[3]; r++ {
14567                         cellName, _ := CoordinatesToCellName(c, r)
14568                         result, err := fn.f.CalcCellValue(ref.Sheet, cellName, Options{RawCellValue: true})
14569                         if err != nil {
14570                                 return newErrorFormulaArg(formulaErrorVALUE, err.Error())
14571                         }
14572                         arg := newStringFormulaArg(result)
14573                         if num := arg.ToNumber(); num.Type == ArgNumber {
14574                                 arg = num
14575                         }
14576                         row = append(row, arg)
14577                 }
14578                 mtx = append(mtx, row)
14579         }
14580         return newMatrixFormulaArg(mtx)
14581 }
14582
14583 // CHOOSE function returns a value from an array, that corresponds to a
14584 // supplied index number (position). The syntax of the function is:
14585 //
14586 //      CHOOSE(index_num,value1,[value2],...)
14587 func (fn *formulaFuncs) CHOOSE(argsList *list.List) formulaArg {
14588         if argsList.Len() < 2 {
14589                 return newErrorFormulaArg(formulaErrorVALUE, "CHOOSE requires 2 arguments")
14590         }
14591         idx, err := strconv.Atoi(argsList.Front().Value.(formulaArg).Value())
14592         if err != nil {
14593                 return newErrorFormulaArg(formulaErrorVALUE, "CHOOSE requires first argument of type number")
14594         }
14595         if argsList.Len() <= idx {
14596                 return newErrorFormulaArg(formulaErrorVALUE, "index_num should be <= to the number of values")
14597         }
14598         arg := argsList.Front()
14599         for i := 0; i < idx; i++ {
14600                 arg = arg.Next()
14601         }
14602         return arg.Value.(formulaArg)
14603 }
14604
14605 // matchPatternToRegExp convert find text pattern to regular expression.
14606 func matchPatternToRegExp(findText string, dbcs bool) (string, bool) {
14607         var (
14608                 exp      string
14609                 wildCard bool
14610                 mark     = "."
14611         )
14612         if dbcs {
14613                 mark = "(?:(?:[\\x00-\\x0081])|(?:[\\xFF61-\\xFFA0])|(?:[\\xF8F1-\\xF8F4])|[0-9A-Za-z])"
14614         }
14615         for _, char := range findText {
14616                 if strings.ContainsAny(string(char), ".+$^[](){}|/") {
14617                         exp += fmt.Sprintf("\\%s", string(char))
14618                         continue
14619                 }
14620                 if char == '?' {
14621                         wildCard = true
14622                         exp += mark
14623                         continue
14624                 }
14625                 if char == '*' {
14626                         wildCard = true
14627                         exp += ".*"
14628                         continue
14629                 }
14630                 exp += string(char)
14631         }
14632         return fmt.Sprintf("^%s", exp), wildCard
14633 }
14634
14635 // matchPattern finds whether the text matches or satisfies the pattern
14636 // string. The pattern supports '*' and '?' wildcards in the pattern string.
14637 func matchPattern(findText, withinText string, dbcs bool, startNum int) (int, bool) {
14638         exp, wildCard := matchPatternToRegExp(findText, dbcs)
14639         offset := 1
14640         for idx := range withinText {
14641                 if offset < startNum {
14642                         offset++
14643                         continue
14644                 }
14645                 if wildCard {
14646                         if ok, _ := regexp.MatchString(exp, withinText[idx:]); ok {
14647                                 break
14648                         }
14649                 }
14650                 if strings.Index(withinText[idx:], findText) == 0 {
14651                         break
14652                 }
14653                 offset++
14654         }
14655         return offset, utf8.RuneCountInString(withinText) != offset-1
14656 }
14657
14658 // compareFormulaArg compares the left-hand sides and the right-hand sides'
14659 // formula arguments by given conditions such as case-sensitive, if exact
14660 // match, and make compare result as formula criteria condition type.
14661 func compareFormulaArg(lhs, rhs, matchMode formulaArg, caseSensitive bool) byte {
14662         if lhs.Type != rhs.Type {
14663                 return criteriaNe
14664         }
14665         switch lhs.Type {
14666         case ArgNumber:
14667                 if lhs.Number == rhs.Number {
14668                         return criteriaEq
14669                 }
14670                 if lhs.Number < rhs.Number {
14671                         return criteriaL
14672                 }
14673                 return criteriaG
14674         case ArgString:
14675                 ls, rs := lhs.Value(), rhs.Value()
14676                 if !caseSensitive {
14677                         ls, rs = strings.ToLower(ls), strings.ToLower(rs)
14678                 }
14679                 if matchMode.Number == matchModeWildcard {
14680                         if _, ok := matchPattern(rs, ls, false, 0); ok {
14681                                 return criteriaEq
14682                         }
14683                 }
14684                 return map[int]byte{1: criteriaG, -1: criteriaL, 0: criteriaEq}[strings.Compare(ls, rs)]
14685         case ArgEmpty:
14686                 return criteriaEq
14687         case ArgList:
14688                 return compareFormulaArgList(lhs, rhs, matchMode, caseSensitive)
14689         case ArgMatrix:
14690                 return compareFormulaArgMatrix(lhs, rhs, matchMode, caseSensitive)
14691         default:
14692                 return criteriaErr
14693         }
14694 }
14695
14696 // compareFormulaArgList compares the left-hand sides and the right-hand sides
14697 // list type formula arguments.
14698 func compareFormulaArgList(lhs, rhs, matchMode formulaArg, caseSensitive bool) byte {
14699         if len(lhs.List) < len(rhs.List) {
14700                 return criteriaL
14701         }
14702         if len(lhs.List) > len(rhs.List) {
14703                 return criteriaG
14704         }
14705         for arg := range lhs.List {
14706                 criteria := compareFormulaArg(lhs.List[arg], rhs.List[arg], matchMode, caseSensitive)
14707                 if criteria != criteriaEq {
14708                         return criteria
14709                 }
14710         }
14711         return criteriaEq
14712 }
14713
14714 // compareFormulaArgMatrix compares the left-hand sides and the right-hand sides'
14715 // matrix type formula arguments.
14716 func compareFormulaArgMatrix(lhs, rhs, matchMode formulaArg, caseSensitive bool) byte {
14717         if len(lhs.Matrix) < len(rhs.Matrix) {
14718                 return criteriaL
14719         }
14720         if len(lhs.Matrix) > len(rhs.Matrix) {
14721                 return criteriaG
14722         }
14723         for i := range lhs.Matrix {
14724                 left, right := lhs.Matrix[i], rhs.Matrix[i]
14725                 if len(left) < len(right) {
14726                         return criteriaL
14727                 }
14728                 if len(left) > len(right) {
14729                         return criteriaG
14730                 }
14731                 for arg := range left {
14732                         criteria := compareFormulaArg(left[arg], right[arg], matchMode, caseSensitive)
14733                         if criteria != criteriaEq {
14734                                 return criteria
14735                         }
14736                 }
14737         }
14738         return criteriaEq
14739 }
14740
14741 // COLUMN function returns the first column number within a supplied reference
14742 // or the number of the current column. The syntax of the function is:
14743 //
14744 //      COLUMN([reference])
14745 func (fn *formulaFuncs) COLUMN(argsList *list.List) formulaArg {
14746         if argsList.Len() > 1 {
14747                 return newErrorFormulaArg(formulaErrorVALUE, "COLUMN requires at most 1 argument")
14748         }
14749         if argsList.Len() == 1 {
14750                 if argsList.Front().Value.(formulaArg).cellRanges != nil && argsList.Front().Value.(formulaArg).cellRanges.Len() > 0 {
14751                         return newNumberFormulaArg(float64(argsList.Front().Value.(formulaArg).cellRanges.Front().Value.(cellRange).From.Col))
14752                 }
14753                 if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 {
14754                         return newNumberFormulaArg(float64(argsList.Front().Value.(formulaArg).cellRefs.Front().Value.(cellRef).Col))
14755                 }
14756                 return newErrorFormulaArg(formulaErrorVALUE, "invalid reference")
14757         }
14758         col, _, _ := CellNameToCoordinates(fn.cell)
14759         return newNumberFormulaArg(float64(col))
14760 }
14761
14762 // calcColsRowsMinMax calculation min and max value for given formula arguments
14763 // sequence of the formula functions COLUMNS and ROWS.
14764 func calcColsRowsMinMax(cols bool, argsList *list.List) (min, max int) {
14765         getVal := func(cols bool, cell cellRef) int {
14766                 if cols {
14767                         return cell.Col
14768                 }
14769                 return cell.Row
14770         }
14771         if argsList.Front().Value.(formulaArg).cellRanges != nil && argsList.Front().Value.(formulaArg).cellRanges.Len() > 0 {
14772                 crs := argsList.Front().Value.(formulaArg).cellRanges
14773                 for cr := crs.Front(); cr != nil; cr = cr.Next() {
14774                         if min == 0 {
14775                                 min = getVal(cols, cr.Value.(cellRange).From)
14776                         }
14777                         if max < getVal(cols, cr.Value.(cellRange).To) {
14778                                 max = getVal(cols, cr.Value.(cellRange).To)
14779                         }
14780                 }
14781         }
14782         if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 {
14783                 cr := argsList.Front().Value.(formulaArg).cellRefs
14784                 for refs := cr.Front(); refs != nil; refs = refs.Next() {
14785                         if min == 0 {
14786                                 min = getVal(cols, refs.Value.(cellRef))
14787                         }
14788                         if max < getVal(cols, refs.Value.(cellRef)) {
14789                                 max = getVal(cols, refs.Value.(cellRef))
14790                         }
14791                 }
14792         }
14793         return
14794 }
14795
14796 // COLUMNS function receives an Excel range and returns the number of columns
14797 // that are contained within the range. The syntax of the function is:
14798 //
14799 //      COLUMNS(array)
14800 func (fn *formulaFuncs) COLUMNS(argsList *list.List) formulaArg {
14801         if argsList.Len() != 1 {
14802                 return newErrorFormulaArg(formulaErrorVALUE, "COLUMNS requires 1 argument")
14803         }
14804         min, max := calcColsRowsMinMax(true, argsList)
14805         if max == MaxColumns {
14806                 return newNumberFormulaArg(float64(MaxColumns))
14807         }
14808         result := max - min + 1
14809         if max == min {
14810                 if min == 0 {
14811                         return newErrorFormulaArg(formulaErrorVALUE, "invalid reference")
14812                 }
14813                 return newNumberFormulaArg(float64(1))
14814         }
14815         return newNumberFormulaArg(float64(result))
14816 }
14817
14818 // FORMULATEXT function returns a formula as a text string. The syntax of the
14819 // function is:
14820 //
14821 //      FORMULATEXT(reference)
14822 func (fn *formulaFuncs) FORMULATEXT(argsList *list.List) formulaArg {
14823         if argsList.Len() != 1 {
14824                 return newErrorFormulaArg(formulaErrorVALUE, "FORMULATEXT requires 1 argument")
14825         }
14826         refs := argsList.Front().Value.(formulaArg).cellRefs
14827         col, row := 0, 0
14828         if refs != nil && refs.Len() > 0 {
14829                 col, row = refs.Front().Value.(cellRef).Col, refs.Front().Value.(cellRef).Row
14830         }
14831         ranges := argsList.Front().Value.(formulaArg).cellRanges
14832         if ranges != nil && ranges.Len() > 0 {
14833                 col, row = ranges.Front().Value.(cellRange).From.Col, ranges.Front().Value.(cellRange).From.Row
14834         }
14835         cell, err := CoordinatesToCellName(col, row)
14836         if err != nil {
14837                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
14838         }
14839         formula, _ := fn.f.GetCellFormula(fn.sheet, cell)
14840         return newStringFormulaArg(formula)
14841 }
14842
14843 // checkHVLookupArgs checking arguments, prepare extract mode, lookup value,
14844 // and data for the formula functions HLOOKUP and VLOOKUP.
14845 func checkHVLookupArgs(name string, argsList *list.List) (idx int, lookupValue, tableArray, matchMode, errArg formulaArg) {
14846         unit := map[string]string{
14847                 "HLOOKUP": "row",
14848                 "VLOOKUP": "col",
14849         }[name]
14850         if argsList.Len() < 3 {
14851                 errArg = newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 3 arguments", name))
14852                 return
14853         }
14854         if argsList.Len() > 4 {
14855                 errArg = newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at most 4 arguments", name))
14856                 return
14857         }
14858         lookupValue = argsList.Front().Value.(formulaArg)
14859         tableArray = argsList.Front().Next().Value.(formulaArg)
14860         if tableArray.Type != ArgMatrix {
14861                 errArg = newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires second argument of table array", name))
14862                 return
14863         }
14864         arg := argsList.Front().Next().Next().Value.(formulaArg)
14865         if arg.Type != ArgNumber || arg.Boolean {
14866                 errArg = newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires numeric %s argument", name, unit))
14867                 return
14868         }
14869         idx, matchMode = int(arg.Number)-1, newNumberFormulaArg(matchModeMaxLess)
14870         if argsList.Len() == 4 {
14871                 rangeLookup := argsList.Back().Value.(formulaArg).ToBool()
14872                 if rangeLookup.Type == ArgError {
14873                         errArg = rangeLookup
14874                         return
14875                 }
14876                 if rangeLookup.Number == 0 {
14877                         matchMode = newNumberFormulaArg(matchModeWildcard)
14878                 }
14879         }
14880         return
14881 }
14882
14883 // HLOOKUP function 'looks up' a given value in the top row of a data array
14884 // (or table), and returns the corresponding value from another row of the
14885 // array. The syntax of the function is:
14886 //
14887 //      HLOOKUP(lookup_value,table_array,row_index_num,[range_lookup])
14888 func (fn *formulaFuncs) HLOOKUP(argsList *list.List) formulaArg {
14889         rowIdx, lookupValue, tableArray, matchMode, errArg := checkHVLookupArgs("HLOOKUP", argsList)
14890         if errArg.Type == ArgError {
14891                 return errArg
14892         }
14893         var matchIdx int
14894         var wasExact bool
14895         if matchMode.Number == matchModeWildcard || len(tableArray.Matrix) == TotalRows {
14896                 matchIdx, wasExact = lookupLinearSearch(false, lookupValue, tableArray, matchMode, newNumberFormulaArg(searchModeLinear))
14897         } else {
14898                 matchIdx, wasExact = lookupBinarySearch(false, lookupValue, tableArray, matchMode, newNumberFormulaArg(searchModeAscBinary))
14899         }
14900         if matchIdx == -1 {
14901                 return newErrorFormulaArg(formulaErrorNA, "HLOOKUP no result found")
14902         }
14903         if rowIdx < 0 || rowIdx >= len(tableArray.Matrix) {
14904                 return newErrorFormulaArg(formulaErrorNA, "HLOOKUP has invalid row index")
14905         }
14906         row := tableArray.Matrix[rowIdx]
14907         if wasExact || matchMode.Number == matchModeWildcard {
14908                 return row[matchIdx]
14909         }
14910         return newErrorFormulaArg(formulaErrorNA, "HLOOKUP no result found")
14911 }
14912
14913 // HYPERLINK function creates a hyperlink to a specified location. The syntax
14914 // of the function is:
14915 //
14916 //      HYPERLINK(link_location,[friendly_name])
14917 func (fn *formulaFuncs) HYPERLINK(argsList *list.List) formulaArg {
14918         if argsList.Len() < 1 {
14919                 return newErrorFormulaArg(formulaErrorVALUE, "HYPERLINK requires at least 1 argument")
14920         }
14921         if argsList.Len() > 2 {
14922                 return newErrorFormulaArg(formulaErrorVALUE, "HYPERLINK allows at most 2 arguments")
14923         }
14924         return newStringFormulaArg(argsList.Back().Value.(formulaArg).Value())
14925 }
14926
14927 // calcMatch returns the position of the value by given match type, criteria
14928 // and lookup array for the formula function MATCH.
14929 func calcMatch(matchType int, criteria *formulaCriteria, lookupArray []formulaArg) formulaArg {
14930         idx := -1
14931         switch matchType {
14932         case 0:
14933                 for i, arg := range lookupArray {
14934                         if ok, _ := formulaCriteriaEval(arg, criteria); ok {
14935                                 return newNumberFormulaArg(float64(i + 1))
14936                         }
14937                 }
14938         case -1:
14939                 for i, arg := range lookupArray {
14940                         if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
14941                                 Type: criteriaGe, Condition: criteria.Condition,
14942                         }); ok {
14943                                 idx = i
14944                                 continue
14945                         }
14946                         if criteria.Condition.Type == ArgNumber {
14947                                 break
14948                         }
14949                 }
14950         case 1:
14951                 for i, arg := range lookupArray {
14952                         if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
14953                                 Type: criteriaLe, Condition: criteria.Condition,
14954                         }); ok {
14955                                 idx = i
14956                                 continue
14957                         }
14958                         if criteria.Condition.Type == ArgNumber {
14959                                 break
14960                         }
14961                 }
14962         }
14963         if idx == -1 {
14964                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
14965         }
14966         return newNumberFormulaArg(float64(idx + 1))
14967 }
14968
14969 // MATCH function looks up a value in an array, and returns the position of
14970 // the value within the array. The user can specify that the function should
14971 // only return a result if an exact match is found, or that the function
14972 // should return the position of the closest match (above or below), if an
14973 // exact match is not found. The syntax of the Match function is:
14974 //
14975 //      MATCH(lookup_value,lookup_array,[match_type])
14976 func (fn *formulaFuncs) MATCH(argsList *list.List) formulaArg {
14977         if argsList.Len() != 2 && argsList.Len() != 3 {
14978                 return newErrorFormulaArg(formulaErrorVALUE, "MATCH requires 1 or 2 arguments")
14979         }
14980         var (
14981                 matchType      = 1
14982                 lookupArray    []formulaArg
14983                 lookupArrayArg = argsList.Front().Next().Value.(formulaArg)
14984                 lookupArrayErr = "MATCH arguments lookup_array should be one-dimensional array"
14985         )
14986         if argsList.Len() == 3 {
14987                 matchTypeArg := argsList.Back().Value.(formulaArg).ToNumber()
14988                 if matchTypeArg.Type != ArgNumber {
14989                         return newErrorFormulaArg(formulaErrorVALUE, "MATCH requires numeric match_type argument")
14990                 }
14991                 if matchTypeArg.Number == -1 || matchTypeArg.Number == 0 {
14992                         matchType = int(matchTypeArg.Number)
14993                 }
14994         }
14995         switch lookupArrayArg.Type {
14996         case ArgMatrix:
14997                 if len(lookupArrayArg.Matrix) != 1 && len(lookupArrayArg.Matrix[0]) != 1 {
14998                         return newErrorFormulaArg(formulaErrorNA, lookupArrayErr)
14999                 }
15000                 lookupArray = lookupArrayArg.ToList()
15001         default:
15002                 return newErrorFormulaArg(formulaErrorNA, lookupArrayErr)
15003         }
15004         return calcMatch(matchType, formulaCriteriaParser(argsList.Front().Value.(formulaArg)), lookupArray)
15005 }
15006
15007 // TRANSPOSE function 'transposes' an array of cells (i.e. the function copies
15008 // a horizontal range of cells into a vertical range and vice versa). The
15009 // syntax of the function is:
15010 //
15011 //      TRANSPOSE(array)
15012 func (fn *formulaFuncs) TRANSPOSE(argsList *list.List) formulaArg {
15013         if argsList.Len() != 1 {
15014                 return newErrorFormulaArg(formulaErrorVALUE, "TRANSPOSE requires 1 argument")
15015         }
15016         args := argsList.Back().Value.(formulaArg).ToList()
15017         rmin, rmax := calcColsRowsMinMax(false, argsList)
15018         cmin, cmax := calcColsRowsMinMax(true, argsList)
15019         cols, rows := cmax-cmin+1, rmax-rmin+1
15020         src := make([][]formulaArg, 0)
15021         for i := 0; i < len(args); i += cols {
15022                 src = append(src, args[i:i+cols])
15023         }
15024         mtx := make([][]formulaArg, cols)
15025         for r, row := range src {
15026                 colIdx := r % rows
15027                 for c, cell := range row {
15028                         rowIdx := c % cols
15029                         if len(mtx[rowIdx]) == 0 {
15030                                 mtx[rowIdx] = make([]formulaArg, rows)
15031                         }
15032                         mtx[rowIdx][colIdx] = cell
15033                 }
15034         }
15035         return newMatrixFormulaArg(mtx)
15036 }
15037
15038 // lookupLinearSearch sequentially checks each look value of the lookup array until
15039 // a match is found or the whole list has been searched.
15040 func lookupLinearSearch(vertical bool, lookupValue, lookupArray, matchMode, searchMode formulaArg) (int, bool) {
15041         var tableArray []formulaArg
15042         if vertical {
15043                 for _, row := range lookupArray.Matrix {
15044                         tableArray = append(tableArray, row[0])
15045                 }
15046         } else {
15047                 tableArray = lookupArray.Matrix[0]
15048         }
15049         matchIdx, wasExact := -1, false
15050 start:
15051         for i, cell := range tableArray {
15052                 lhs := cell
15053                 if lookupValue.Type == ArgNumber {
15054                         if lhs = cell.ToNumber(); lhs.Type == ArgError {
15055                                 lhs = cell
15056                         }
15057                 } else if lookupValue.Type == ArgMatrix {
15058                         lhs = lookupArray
15059                 } else if lookupArray.Type == ArgString {
15060                         lhs = newStringFormulaArg(cell.Value())
15061                 }
15062                 if compareFormulaArg(lhs, lookupValue, matchMode, false) == criteriaEq {
15063                         matchIdx = i
15064                         wasExact = true
15065                         if searchMode.Number == searchModeLinear {
15066                                 break start
15067                         }
15068                 }
15069                 if matchMode.Number == matchModeMinGreater || matchMode.Number == matchModeMaxLess {
15070                         matchIdx = int(calcMatch(int(matchMode.Number), formulaCriteriaParser(lookupValue), tableArray).Number)
15071                         continue
15072                 }
15073         }
15074         return matchIdx, wasExact
15075 }
15076
15077 // VLOOKUP function 'looks up' a given value in the left-hand column of a
15078 // data array (or table), and returns the corresponding value from another
15079 // column of the array. The syntax of the function is:
15080 //
15081 //      VLOOKUP(lookup_value,table_array,col_index_num,[range_lookup])
15082 func (fn *formulaFuncs) VLOOKUP(argsList *list.List) formulaArg {
15083         colIdx, lookupValue, tableArray, matchMode, errArg := checkHVLookupArgs("VLOOKUP", argsList)
15084         if errArg.Type == ArgError {
15085                 return errArg
15086         }
15087         var matchIdx int
15088         var wasExact bool
15089         if matchMode.Number == matchModeWildcard || len(tableArray.Matrix) == TotalRows {
15090                 matchIdx, wasExact = lookupLinearSearch(true, lookupValue, tableArray, matchMode, newNumberFormulaArg(searchModeLinear))
15091         } else {
15092                 matchIdx, wasExact = lookupBinarySearch(true, lookupValue, tableArray, matchMode, newNumberFormulaArg(searchModeAscBinary))
15093         }
15094         if matchIdx == -1 {
15095                 return newErrorFormulaArg(formulaErrorNA, "VLOOKUP no result found")
15096         }
15097         mtx := tableArray.Matrix[matchIdx]
15098         if colIdx < 0 || colIdx >= len(mtx) {
15099                 return newErrorFormulaArg(formulaErrorNA, "VLOOKUP has invalid column index")
15100         }
15101         if wasExact || matchMode.Number == matchModeWildcard {
15102                 return mtx[colIdx]
15103         }
15104         return newErrorFormulaArg(formulaErrorNA, "VLOOKUP no result found")
15105 }
15106
15107 // lookupBinarySearch finds the position of a target value when range lookup
15108 // is TRUE, if the data of table array can't guarantee be sorted, it will
15109 // return wrong result.
15110 func lookupBinarySearch(vertical bool, lookupValue, lookupArray, matchMode, searchMode formulaArg) (matchIdx int, wasExact bool) {
15111         var tableArray []formulaArg
15112         if vertical {
15113                 for _, row := range lookupArray.Matrix {
15114                         tableArray = append(tableArray, row[0])
15115                 }
15116         } else {
15117                 tableArray = lookupArray.Matrix[0]
15118         }
15119         low, high, lastMatchIdx := 0, len(tableArray)-1, -1
15120         count := high
15121         for low <= high {
15122                 mid := low + (high-low)/2
15123                 cell := tableArray[mid]
15124                 lhs := cell
15125                 if lookupValue.Type == ArgNumber {
15126                         if lhs = cell.ToNumber(); lhs.Type == ArgError {
15127                                 lhs = cell
15128                         }
15129                 } else if lookupValue.Type == ArgMatrix && vertical {
15130                         lhs = lookupArray
15131                 } else if lookupValue.Type == ArgString {
15132                         lhs = newStringFormulaArg(cell.Value())
15133                 }
15134                 result := compareFormulaArg(lhs, lookupValue, matchMode, false)
15135                 if result == criteriaEq {
15136                         matchIdx, wasExact = mid, true
15137                         if searchMode.Number == searchModeDescBinary {
15138                                 matchIdx = count - matchIdx
15139                         }
15140                         return
15141                 } else if result == criteriaG {
15142                         high = mid - 1
15143                 } else if result == criteriaL {
15144                         matchIdx = mid
15145                         if cell.Type != ArgEmpty {
15146                                 lastMatchIdx = matchIdx
15147                         }
15148                         low = mid + 1
15149                 } else {
15150                         return -1, false
15151                 }
15152         }
15153         matchIdx, wasExact = lastMatchIdx, true
15154         return
15155 }
15156
15157 // checkLookupArgs checking arguments, prepare lookup value, and data for the
15158 // formula function LOOKUP.
15159 func checkLookupArgs(argsList *list.List) (arrayForm bool, lookupValue, lookupVector, errArg formulaArg) {
15160         if argsList.Len() < 2 {
15161                 errArg = newErrorFormulaArg(formulaErrorVALUE, "LOOKUP requires at least 2 arguments")
15162                 return
15163         }
15164         if argsList.Len() > 3 {
15165                 errArg = newErrorFormulaArg(formulaErrorVALUE, "LOOKUP requires at most 3 arguments")
15166                 return
15167         }
15168         lookupValue = newStringFormulaArg(argsList.Front().Value.(formulaArg).Value())
15169         lookupVector = argsList.Front().Next().Value.(formulaArg)
15170         if lookupVector.Type != ArgMatrix && lookupVector.Type != ArgList {
15171                 errArg = newErrorFormulaArg(formulaErrorVALUE, "LOOKUP requires second argument of table array")
15172                 return
15173         }
15174         arrayForm = lookupVector.Type == ArgMatrix
15175         if arrayForm && len(lookupVector.Matrix) == 0 {
15176                 errArg = newErrorFormulaArg(formulaErrorVALUE, "LOOKUP requires not empty range as second argument")
15177         }
15178         return
15179 }
15180
15181 // iterateLookupArgs iterate arguments to extract columns and calculate match
15182 // index for the formula function LOOKUP.
15183 func iterateLookupArgs(lookupValue, lookupVector formulaArg) ([]formulaArg, int, bool) {
15184         cols, matchIdx, ok := lookupCol(lookupVector, 0), -1, false
15185         for idx, col := range cols {
15186                 lhs := lookupValue
15187                 switch col.Type {
15188                 case ArgNumber:
15189                         lhs = lhs.ToNumber()
15190                         if !col.Boolean {
15191                                 if lhs.Type == ArgError {
15192                                         lhs = lookupValue
15193                                 }
15194                         }
15195                 }
15196                 compare := compareFormulaArg(lhs, col, newNumberFormulaArg(matchModeMaxLess), false)
15197                 // Find exact match
15198                 if compare == criteriaEq {
15199                         matchIdx = idx
15200                         break
15201                 }
15202                 // Find the nearest match if lookup value is more than or equal to the first value in lookup vector
15203                 if idx == 0 {
15204                         ok = compare == criteriaG
15205                 } else if ok && compare == criteriaL && matchIdx == -1 {
15206                         matchIdx = idx - 1
15207                 }
15208         }
15209         return cols, matchIdx, ok
15210 }
15211
15212 // index is an implementation of the formula function INDEX.
15213 func (fn *formulaFuncs) index(array formulaArg, rowIdx, colIdx int) formulaArg {
15214         var cells []formulaArg
15215         if array.Type == ArgMatrix {
15216                 cellMatrix := array.Matrix
15217                 if rowIdx < -1 || rowIdx >= len(cellMatrix) {
15218                         return newErrorFormulaArg(formulaErrorREF, "INDEX row_num out of range")
15219                 }
15220                 if rowIdx == -1 {
15221                         if colIdx >= len(cellMatrix[0]) {
15222                                 return newErrorFormulaArg(formulaErrorREF, "INDEX col_num out of range")
15223                         }
15224                         var column [][]formulaArg
15225                         for _, cells = range cellMatrix {
15226                                 column = append(column, []formulaArg{cells[colIdx]})
15227                         }
15228                         return newMatrixFormulaArg(column)
15229                 }
15230                 cells = cellMatrix[rowIdx]
15231         }
15232         if colIdx < -1 || colIdx >= len(cells) {
15233                 return newErrorFormulaArg(formulaErrorREF, "INDEX col_num out of range")
15234         }
15235         return newListFormulaArg(cells)
15236 }
15237
15238 // validateMatchMode check the number of match mode if be equal to 0, 1, -1 or
15239 // 2.
15240 func validateMatchMode(mode float64) bool {
15241         return mode == matchModeExact || mode == matchModeMinGreater || mode == matchModeMaxLess || mode == matchModeWildcard
15242 }
15243
15244 // validateSearchMode check the number of search mode if be equal to 1, -1, 2
15245 // or -2.
15246 func validateSearchMode(mode float64) bool {
15247         return mode == searchModeLinear || mode == searchModeReverseLinear || mode == searchModeAscBinary || mode == searchModeDescBinary
15248 }
15249
15250 // prepareXlookupArgs checking and prepare arguments for the formula function
15251 // XLOOKUP.
15252 func (fn *formulaFuncs) prepareXlookupArgs(argsList *list.List) formulaArg {
15253         if argsList.Len() < 3 {
15254                 return newErrorFormulaArg(formulaErrorVALUE, "XLOOKUP requires at least 3 arguments")
15255         }
15256         if argsList.Len() > 6 {
15257                 return newErrorFormulaArg(formulaErrorVALUE, "XLOOKUP allows at most 6 arguments")
15258         }
15259         lookupValue := argsList.Front().Value.(formulaArg)
15260         lookupArray := argsList.Front().Next().Value.(formulaArg)
15261         returnArray := argsList.Front().Next().Next().Value.(formulaArg)
15262         ifNotFond := newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
15263         matchMode, searchMode := newNumberFormulaArg(matchModeExact), newNumberFormulaArg(searchModeLinear)
15264         if argsList.Len() > 3 {
15265                 ifNotFond = argsList.Front().Next().Next().Next().Value.(formulaArg)
15266         }
15267         if argsList.Len() > 4 {
15268                 if matchMode = argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber(); matchMode.Type != ArgNumber {
15269                         return matchMode
15270                 }
15271         }
15272         if argsList.Len() > 5 {
15273                 if searchMode = argsList.Back().Value.(formulaArg).ToNumber(); searchMode.Type != ArgNumber {
15274                         return searchMode
15275                 }
15276         }
15277         if lookupArray.Type != ArgMatrix || returnArray.Type != ArgMatrix {
15278                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
15279         }
15280         if !validateMatchMode(matchMode.Number) || !validateSearchMode(searchMode.Number) {
15281                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15282         }
15283         return newListFormulaArg([]formulaArg{lookupValue, lookupArray, returnArray, ifNotFond, matchMode, searchMode})
15284 }
15285
15286 // xlookup is an implementation of the formula function XLOOKUP.
15287 func (fn *formulaFuncs) xlookup(lookupRows, lookupCols, returnArrayRows, returnArrayCols, matchIdx int,
15288         condition1, condition2, condition3, condition4 bool, returnArray formulaArg,
15289 ) formulaArg {
15290         var result [][]formulaArg
15291         for rowIdx, row := range returnArray.Matrix {
15292                 for colIdx, cell := range row {
15293                         if condition1 {
15294                                 if condition2 {
15295                                         result = append(result, []formulaArg{cell})
15296                                         continue
15297                                 }
15298                                 if returnArrayRows > 1 && returnArrayCols > 1 {
15299                                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15300                                 }
15301                         }
15302                         if condition3 {
15303                                 if returnArrayCols != lookupCols {
15304                                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15305                                 }
15306                                 if colIdx == matchIdx {
15307                                         result = append(result, []formulaArg{cell})
15308                                         continue
15309                                 }
15310                         }
15311                         if condition4 {
15312                                 if returnArrayRows != lookupRows {
15313                                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15314                                 }
15315                                 if rowIdx == matchIdx {
15316                                         if len(result) == 0 {
15317                                                 result = append(result, []formulaArg{cell})
15318                                                 continue
15319                                         }
15320                                         result[0] = append(result[0], cell)
15321                                 }
15322                         }
15323                 }
15324         }
15325         array := newMatrixFormulaArg(result)
15326         cells := array.ToList()
15327         if len(cells) == 1 {
15328                 return cells[0]
15329         }
15330         return array
15331 }
15332
15333 // XLOOKUP function searches a range or an array, and then returns the item
15334 // corresponding to the first match it finds. If no match exists, then
15335 // XLOOKUP can return the closest (approximate) match. The syntax of the
15336 // function is:
15337 //
15338 //      XLOOKUP(lookup_value,lookup_array,return_array,[if_not_found],[match_mode],[search_mode])
15339 func (fn *formulaFuncs) XLOOKUP(argsList *list.List) formulaArg {
15340         args := fn.prepareXlookupArgs(argsList)
15341         if args.Type != ArgList {
15342                 return args
15343         }
15344         lookupValue, lookupArray, returnArray, ifNotFond, matchMode, searchMode := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5]
15345         lookupRows, lookupCols := len(lookupArray.Matrix), 0
15346         if lookupRows > 0 {
15347                 lookupCols = len(lookupArray.Matrix[0])
15348         }
15349         if lookupRows != 1 && lookupCols != 1 {
15350                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15351         }
15352         verticalLookup := lookupRows >= lookupCols
15353         var matchIdx int
15354         switch searchMode.Number {
15355         case searchModeLinear, searchModeReverseLinear:
15356                 matchIdx, _ = lookupLinearSearch(verticalLookup, lookupValue, lookupArray, matchMode, searchMode)
15357         default:
15358                 matchIdx, _ = lookupBinarySearch(verticalLookup, lookupValue, lookupArray, matchMode, searchMode)
15359         }
15360         if matchIdx == -1 {
15361                 return ifNotFond
15362         }
15363         returnArrayRows, returnArrayCols := len(returnArray.Matrix), len(returnArray.Matrix[0])
15364         condition1 := lookupRows == 1 && lookupCols == 1
15365         condition2 := returnArrayRows == 1 || returnArrayCols == 1
15366         condition3 := lookupRows == 1 && lookupCols > 1
15367         condition4 := lookupRows > 1 && lookupCols == 1
15368         return fn.xlookup(lookupRows, lookupCols, returnArrayRows, returnArrayCols, matchIdx, condition1, condition2, condition3, condition4, returnArray)
15369 }
15370
15371 // INDEX function returns a reference to a cell that lies in a specified row
15372 // and column of a range of cells. The syntax of the function is:
15373 //
15374 //      INDEX(array,row_num,[col_num])
15375 func (fn *formulaFuncs) INDEX(argsList *list.List) formulaArg {
15376         if argsList.Len() < 2 || argsList.Len() > 3 {
15377                 return newErrorFormulaArg(formulaErrorVALUE, "INDEX requires 2 or 3 arguments")
15378         }
15379         array := argsList.Front().Value.(formulaArg)
15380         if array.Type != ArgMatrix && array.Type != ArgList {
15381                 array = newMatrixFormulaArg([][]formulaArg{{array}})
15382         }
15383         rowArg := argsList.Front().Next().Value.(formulaArg).ToNumber()
15384         if rowArg.Type != ArgNumber {
15385                 return rowArg
15386         }
15387         rowIdx, colIdx := int(rowArg.Number)-1, -1
15388         if argsList.Len() == 3 {
15389                 colArg := argsList.Back().Value.(formulaArg).ToNumber()
15390                 if colArg.Type != ArgNumber {
15391                         return colArg
15392                 }
15393                 colIdx = int(colArg.Number) - 1
15394         }
15395         if rowIdx == -1 && colIdx == -1 {
15396                 if len(array.ToList()) != 1 {
15397                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15398                 }
15399                 return array.ToList()[0]
15400         }
15401         cells := fn.index(array, rowIdx, colIdx)
15402         if cells.Type != ArgList {
15403                 return cells
15404         }
15405         if colIdx == -1 {
15406                 return newMatrixFormulaArg([][]formulaArg{cells.List})
15407         }
15408         return cells.List[colIdx]
15409 }
15410
15411 // INDIRECT function converts a text string into a cell reference. The syntax
15412 // of the Indirect function is:
15413 //
15414 //      INDIRECT(ref_text,[a1])
15415 func (fn *formulaFuncs) INDIRECT(argsList *list.List) formulaArg {
15416         if argsList.Len() != 1 && argsList.Len() != 2 {
15417                 return newErrorFormulaArg(formulaErrorVALUE, "INDIRECT requires 1 or 2 arguments")
15418         }
15419         refText := argsList.Front().Value.(formulaArg).Value()
15420         a1 := newBoolFormulaArg(true)
15421         if argsList.Len() == 2 {
15422                 if a1 = argsList.Back().Value.(formulaArg).ToBool(); a1.Type != ArgNumber {
15423                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15424                 }
15425         }
15426         R1C1ToA1 := func(ref string) (cell string, err error) {
15427                 parts := strings.Split(strings.TrimLeft(ref, "R"), "C")
15428                 if len(parts) != 2 {
15429                         return
15430                 }
15431                 row, err := strconv.Atoi(parts[0])
15432                 if err != nil {
15433                         return
15434                 }
15435                 col, err := strconv.Atoi(parts[1])
15436                 if err != nil {
15437                         return
15438                 }
15439                 cell, err = CoordinatesToCellName(col, row)
15440                 return
15441         }
15442         refs := strings.Split(refText, ":")
15443         fromRef, toRef := refs[0], ""
15444         if len(refs) == 2 {
15445                 toRef = refs[1]
15446         }
15447         if a1.Number == 0 {
15448                 from, err := R1C1ToA1(refs[0])
15449                 if err != nil {
15450                         return newErrorFormulaArg(formulaErrorREF, formulaErrorREF)
15451                 }
15452                 fromRef = from
15453                 if len(refs) == 2 {
15454                         to, err := R1C1ToA1(refs[1])
15455                         if err != nil {
15456                                 return newErrorFormulaArg(formulaErrorREF, formulaErrorREF)
15457                         }
15458                         toRef = to
15459                 }
15460         }
15461         if len(refs) == 1 {
15462                 value, err := fn.f.GetCellValue(fn.sheet, fromRef)
15463                 if err != nil {
15464                         return newErrorFormulaArg(formulaErrorREF, formulaErrorREF)
15465                 }
15466                 return newStringFormulaArg(value)
15467         }
15468         arg, _ := fn.f.parseReference(fn.ctx, fn.sheet, fromRef+":"+toRef)
15469         return arg
15470 }
15471
15472 // LOOKUP function performs an approximate match lookup in a one-column or
15473 // one-row range, and returns the corresponding value from another one-column
15474 // or one-row range. The syntax of the function is:
15475 //
15476 //      LOOKUP(lookup_value,lookup_vector,[result_vector])
15477 func (fn *formulaFuncs) LOOKUP(argsList *list.List) formulaArg {
15478         arrayForm, lookupValue, lookupVector, errArg := checkLookupArgs(argsList)
15479         if errArg.Type == ArgError {
15480                 return errArg
15481         }
15482         cols, matchIdx, ok := iterateLookupArgs(lookupValue, lookupVector)
15483         if ok && matchIdx == -1 {
15484                 matchIdx = len(cols) - 1
15485         }
15486         var column []formulaArg
15487         if argsList.Len() == 3 {
15488                 column = lookupCol(argsList.Back().Value.(formulaArg), 0)
15489         } else if arrayForm && len(lookupVector.Matrix[0]) > 1 {
15490                 column = lookupCol(lookupVector, 1)
15491         } else {
15492                 column = cols
15493         }
15494         if matchIdx < 0 || matchIdx >= len(column) {
15495                 return newErrorFormulaArg(formulaErrorNA, "LOOKUP no result found")
15496         }
15497         return column[matchIdx]
15498 }
15499
15500 // lookupCol extract columns for LOOKUP.
15501 func lookupCol(arr formulaArg, idx int) []formulaArg {
15502         col := arr.List
15503         if arr.Type == ArgMatrix {
15504                 col = nil
15505                 for _, r := range arr.Matrix {
15506                         if len(r) > 0 {
15507                                 col = append(col, r[idx])
15508                                 continue
15509                         }
15510                         col = append(col, newEmptyFormulaArg())
15511                 }
15512         }
15513         return col
15514 }
15515
15516 // ROW function returns the first row number within a supplied reference or
15517 // the number of the current row. The syntax of the function is:
15518 //
15519 //      ROW([reference])
15520 func (fn *formulaFuncs) ROW(argsList *list.List) formulaArg {
15521         if argsList.Len() > 1 {
15522                 return newErrorFormulaArg(formulaErrorVALUE, "ROW requires at most 1 argument")
15523         }
15524         if argsList.Len() == 1 {
15525                 if argsList.Front().Value.(formulaArg).cellRanges != nil && argsList.Front().Value.(formulaArg).cellRanges.Len() > 0 {
15526                         return newNumberFormulaArg(float64(argsList.Front().Value.(formulaArg).cellRanges.Front().Value.(cellRange).From.Row))
15527                 }
15528                 if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 {
15529                         return newNumberFormulaArg(float64(argsList.Front().Value.(formulaArg).cellRefs.Front().Value.(cellRef).Row))
15530                 }
15531                 return newErrorFormulaArg(formulaErrorVALUE, "invalid reference")
15532         }
15533         _, row, _ := CellNameToCoordinates(fn.cell)
15534         return newNumberFormulaArg(float64(row))
15535 }
15536
15537 // ROWS function takes an Excel range and returns the number of rows that are
15538 // contained within the range. The syntax of the function is:
15539 //
15540 //      ROWS(array)
15541 func (fn *formulaFuncs) ROWS(argsList *list.List) formulaArg {
15542         if argsList.Len() != 1 {
15543                 return newErrorFormulaArg(formulaErrorVALUE, "ROWS requires 1 argument")
15544         }
15545         min, max := calcColsRowsMinMax(false, argsList)
15546         if max == TotalRows {
15547                 return newNumberFormulaArg(TotalRows)
15548         }
15549         result := max - min + 1
15550         if max == min {
15551                 if min == 0 {
15552                         return newErrorFormulaArg(formulaErrorVALUE, "invalid reference")
15553                 }
15554                 return newNumberFormulaArg(float64(1))
15555         }
15556         return newNumberFormulaArg(float64(result))
15557 }
15558
15559 // Web Functions
15560
15561 // ENCODEURL function returns a URL-encoded string, replacing certain
15562 // non-alphanumeric characters with the percentage symbol (%) and a
15563 // hexadecimal number. The syntax of the function is:
15564 //
15565 //      ENCODEURL(url)
15566 func (fn *formulaFuncs) ENCODEURL(argsList *list.List) formulaArg {
15567         if argsList.Len() != 1 {
15568                 return newErrorFormulaArg(formulaErrorVALUE, "ENCODEURL requires 1 argument")
15569         }
15570         token := argsList.Front().Value.(formulaArg).Value()
15571         return newStringFormulaArg(strings.ReplaceAll(url.QueryEscape(token), "+", "%20"))
15572 }
15573
15574 // Financial Functions
15575
15576 // validateFrequency check the number of coupon payments per year if be equal to 1, 2 or 4.
15577 func validateFrequency(freq float64) bool {
15578         return freq == 1 || freq == 2 || freq == 4
15579 }
15580
15581 // ACCRINT function returns the accrued interest in a security that pays
15582 // periodic interest. The syntax of the function is:
15583 //
15584 //      ACCRINT(issue,first_interest,settlement,rate,par,frequency,[basis],[calc_method])
15585 func (fn *formulaFuncs) ACCRINT(argsList *list.List) formulaArg {
15586         if argsList.Len() < 6 {
15587                 return newErrorFormulaArg(formulaErrorVALUE, "ACCRINT requires at least 6 arguments")
15588         }
15589         if argsList.Len() > 8 {
15590                 return newErrorFormulaArg(formulaErrorVALUE, "ACCRINT allows at most 8 arguments")
15591         }
15592         args := fn.prepareDataValueArgs(3, argsList)
15593         if args.Type != ArgList {
15594                 return args
15595         }
15596         issue, settlement := args.List[0], args.List[2]
15597         rate := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
15598         par := argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
15599         frequency := argsList.Front().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
15600         if rate.Type != ArgNumber || par.Type != ArgNumber || frequency.Type != ArgNumber {
15601                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15602         }
15603         if !validateFrequency(frequency.Number) {
15604                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15605         }
15606         basis := newNumberFormulaArg(0)
15607         if argsList.Len() >= 7 {
15608                 if basis = argsList.Front().Next().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
15609                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15610                 }
15611         }
15612         if argsList.Len() == 8 {
15613                 if cm := argsList.Back().Value.(formulaArg).ToBool(); cm.Type != ArgNumber {
15614                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15615                 }
15616         }
15617         frac1 := yearFrac(issue.Number, settlement.Number, int(basis.Number))
15618         if frac1.Type != ArgNumber {
15619                 return frac1
15620         }
15621         return newNumberFormulaArg(par.Number * rate.Number * frac1.Number)
15622 }
15623
15624 // ACCRINTM function returns the accrued interest in a security that pays
15625 // interest at maturity. The syntax of the function is:
15626 //
15627 //      ACCRINTM(issue,settlement,rate,[par],[basis])
15628 func (fn *formulaFuncs) ACCRINTM(argsList *list.List) formulaArg {
15629         if argsList.Len() != 4 && argsList.Len() != 5 {
15630                 return newErrorFormulaArg(formulaErrorVALUE, "ACCRINTM requires 4 or 5 arguments")
15631         }
15632         args := fn.prepareDataValueArgs(2, argsList)
15633         if args.Type != ArgList {
15634                 return args
15635         }
15636         issue, settlement := args.List[0], args.List[1]
15637         if settlement.Number < issue.Number {
15638                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15639         }
15640         rate := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
15641         par := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
15642         if rate.Type != ArgNumber || par.Type != ArgNumber {
15643                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15644         }
15645         if par.Number <= 0 {
15646                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15647         }
15648         basis := newNumberFormulaArg(0)
15649         if argsList.Len() == 5 {
15650                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
15651                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15652                 }
15653         }
15654         frac := yearFrac(issue.Number, settlement.Number, int(basis.Number))
15655         if frac.Type != ArgNumber {
15656                 return frac
15657         }
15658         return newNumberFormulaArg(frac.Number * rate.Number * par.Number)
15659 }
15660
15661 // prepareAmorArgs checking and prepare arguments for the formula functions
15662 // AMORDEGRC and AMORLINC.
15663 func (fn *formulaFuncs) prepareAmorArgs(name string, argsList *list.List) formulaArg {
15664         cost := argsList.Front().Value.(formulaArg).ToNumber()
15665         if cost.Type != ArgNumber {
15666                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires cost to be number argument", name))
15667         }
15668         if cost.Number < 0 {
15669                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires cost >= 0", name))
15670         }
15671         args := list.New().Init()
15672         args.PushBack(argsList.Front().Next().Value.(formulaArg))
15673         datePurchased := fn.DATEVALUE(args)
15674         if datePurchased.Type != ArgNumber {
15675                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15676         }
15677         args.Init()
15678         args.PushBack(argsList.Front().Next().Next().Value.(formulaArg))
15679         firstPeriod := fn.DATEVALUE(args)
15680         if firstPeriod.Type != ArgNumber {
15681                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15682         }
15683         if firstPeriod.Number < datePurchased.Number {
15684                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15685         }
15686         salvage := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
15687         if salvage.Type != ArgNumber {
15688                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15689         }
15690         if salvage.Number < 0 || salvage.Number > cost.Number {
15691                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15692         }
15693         period := argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
15694         if period.Type != ArgNumber || period.Number < 0 {
15695                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15696         }
15697         rate := argsList.Front().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
15698         if rate.Type != ArgNumber || rate.Number < 0 {
15699                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15700         }
15701         basis := newNumberFormulaArg(0)
15702         if argsList.Len() == 7 {
15703                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
15704                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15705                 }
15706         }
15707         return newListFormulaArg([]formulaArg{cost, datePurchased, firstPeriod, salvage, period, rate, basis})
15708 }
15709
15710 // AMORDEGRC function is provided for users of the French accounting system.
15711 // The function calculates the prorated linear depreciation of an asset for a
15712 // specified accounting period. The syntax of the function is:
15713 //
15714 //      AMORDEGRC(cost,date_purchased,first_period,salvage,period,rate,[basis])
15715 func (fn *formulaFuncs) AMORDEGRC(argsList *list.List) formulaArg {
15716         if argsList.Len() != 6 && argsList.Len() != 7 {
15717                 return newErrorFormulaArg(formulaErrorVALUE, "AMORDEGRC requires 6 or 7 arguments")
15718         }
15719         args := fn.prepareAmorArgs("AMORDEGRC", argsList)
15720         if args.Type != ArgList {
15721                 return args
15722         }
15723         cost, datePurchased, firstPeriod, salvage, period, rate, basis := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5], args.List[6]
15724         if rate.Number >= 0.5 {
15725                 return newErrorFormulaArg(formulaErrorNUM, "AMORDEGRC requires rate to be < 0.5")
15726         }
15727         assetsLife, amorCoeff := 1/rate.Number, 2.5
15728         if assetsLife < 3 {
15729                 amorCoeff = 1
15730         } else if assetsLife < 5 {
15731                 amorCoeff = 1.5
15732         } else if assetsLife <= 6 {
15733                 amorCoeff = 2
15734         }
15735         rate.Number *= amorCoeff
15736         frac := yearFrac(datePurchased.Number, firstPeriod.Number, int(basis.Number))
15737         if frac.Type != ArgNumber {
15738                 return frac
15739         }
15740         nRate := float64(int((frac.Number * cost.Number * rate.Number) + 0.5))
15741         cost.Number -= nRate
15742         rest := cost.Number - salvage.Number
15743         for n := 0; n < int(period.Number); n++ {
15744                 nRate = float64(int((cost.Number * rate.Number) + 0.5))
15745                 rest -= nRate
15746                 if rest < 0 {
15747                         switch int(period.Number) - n {
15748                         case 0:
15749                         case 1:
15750                                 return newNumberFormulaArg(float64(int((cost.Number * 0.5) + 0.5)))
15751                         default:
15752                                 return newNumberFormulaArg(0)
15753                         }
15754                 }
15755                 cost.Number -= nRate
15756         }
15757         return newNumberFormulaArg(nRate)
15758 }
15759
15760 // AMORLINC function is provided for users of the French accounting system.
15761 // The function calculates the prorated linear depreciation of an asset for a
15762 // specified accounting period. The syntax of the function is:
15763 //
15764 //      AMORLINC(cost,date_purchased,first_period,salvage,period,rate,[basis])
15765 func (fn *formulaFuncs) AMORLINC(argsList *list.List) formulaArg {
15766         if argsList.Len() != 6 && argsList.Len() != 7 {
15767                 return newErrorFormulaArg(formulaErrorVALUE, "AMORLINC requires 6 or 7 arguments")
15768         }
15769         args := fn.prepareAmorArgs("AMORLINC", argsList)
15770         if args.Type != ArgList {
15771                 return args
15772         }
15773         cost, datePurchased, firstPeriod, salvage, period, rate, basis := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5], args.List[6]
15774         frac := yearFrac(datePurchased.Number, firstPeriod.Number, int(basis.Number))
15775         if frac.Type != ArgNumber {
15776                 return frac
15777         }
15778         rate1 := frac.Number * cost.Number * rate.Number
15779         if period.Number == 0 {
15780                 return newNumberFormulaArg(rate1)
15781         }
15782         rate2 := cost.Number * rate.Number
15783         delta := cost.Number - salvage.Number
15784         periods := int((delta - rate1) / rate2)
15785         if int(period.Number) <= periods {
15786                 return newNumberFormulaArg(rate2)
15787         } else if int(period.Number)-1 == periods {
15788                 return newNumberFormulaArg(delta - rate2*float64(periods) - math.Nextafter(rate1, rate1))
15789         }
15790         return newNumberFormulaArg(0)
15791 }
15792
15793 // prepareCouponArgs checking and prepare arguments for the formula functions
15794 // COUPDAYBS, COUPDAYS, COUPDAYSNC, COUPPCD, COUPNUM and COUPNCD.
15795 func (fn *formulaFuncs) prepareCouponArgs(name string, argsList *list.List) formulaArg {
15796         if argsList.Len() != 3 && argsList.Len() != 4 {
15797                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 or 4 arguments", name))
15798         }
15799         args := fn.prepareDataValueArgs(2, argsList)
15800         if args.Type != ArgList {
15801                 return args
15802         }
15803         settlement, maturity := args.List[0], args.List[1]
15804         if settlement.Number >= maturity.Number {
15805                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires maturity > settlement", name))
15806         }
15807         frequency := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
15808         if frequency.Type != ArgNumber {
15809                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
15810         }
15811         if !validateFrequency(frequency.Number) {
15812                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15813         }
15814         basis := newNumberFormulaArg(0)
15815         if argsList.Len() == 4 {
15816                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
15817                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
15818                 }
15819         }
15820         return newListFormulaArg([]formulaArg{settlement, maturity, frequency, basis})
15821 }
15822
15823 // is30BasisMethod determine if the financial day count basis rules is 30/360
15824 // methods.
15825 func is30BasisMethod(basis int) bool {
15826         return basis == 0 || basis == 4
15827 }
15828
15829 // getDaysInMonthRange return the day by given year, month range and day count
15830 // basis.
15831 func getDaysInMonthRange(fromMonth, toMonth int) int {
15832         if fromMonth > toMonth {
15833                 return 0
15834         }
15835         return (toMonth - fromMonth + 1) * 30
15836 }
15837
15838 // getDayOnBasis returns the day by given date and day count basis.
15839 func getDayOnBasis(y, m, d, basis int) int {
15840         if !is30BasisMethod(basis) {
15841                 return d
15842         }
15843         day := d
15844         dim := getDaysInMonth(y, m)
15845         if day > 30 || d >= dim || day >= dim {
15846                 day = 30
15847         }
15848         return day
15849 }
15850
15851 // coupdays returns the number of days that base on date range and the day
15852 // count basis to be used.
15853 func coupdays(from, to time.Time, basis int) float64 {
15854         days := 0
15855         fromY, fromM, fromD := from.Date()
15856         toY, toM, toD := to.Date()
15857         fromDay, toDay := getDayOnBasis(fromY, int(fromM), fromD, basis), getDayOnBasis(toY, int(toM), toD, basis)
15858         if !is30BasisMethod(basis) {
15859                 return (daysBetween(excelMinTime1900.Unix(), makeDate(toY, toM, toDay)) + 1) - (daysBetween(excelMinTime1900.Unix(), makeDate(fromY, fromM, fromDay)) + 1)
15860         }
15861         if basis == 0 {
15862                 if (int(fromM) == 2 || fromDay < 30) && toD == 31 {
15863                         toDay = 31
15864                 }
15865         } else {
15866                 if int(fromM) == 2 && fromDay == 30 {
15867                         fromDay = getDaysInMonth(fromY, 2)
15868                 }
15869                 if int(toM) == 2 && toDay == 30 {
15870                         toDay = getDaysInMonth(toY, 2)
15871                 }
15872         }
15873         if fromY < toY || (fromY == toY && int(fromM) < int(toM)) {
15874                 days = 30 - fromDay + 1
15875                 fromD = 1
15876                 fromDay = 1
15877                 date := time.Date(fromY, fromM, fromD, 0, 0, 0, 0, time.UTC).AddDate(0, 1, 0)
15878                 if date.Year() < toY {
15879                         days += getDaysInMonthRange(int(date.Month()), 12)
15880                         date = date.AddDate(0, 13-int(date.Month()), 0)
15881                 }
15882                 days += getDaysInMonthRange(int(date.Month()), int(toM)-1)
15883         }
15884         if days += toDay - fromDay; days > 0 {
15885                 return float64(days)
15886         }
15887         return 0
15888 }
15889
15890 // COUPDAYBS function calculates the number of days from the beginning of a
15891 // coupon's period to the settlement date. The syntax of the function is:
15892 //
15893 //      COUPDAYBS(settlement,maturity,frequency,[basis])
15894 func (fn *formulaFuncs) COUPDAYBS(argsList *list.List) formulaArg {
15895         args := fn.prepareCouponArgs("COUPDAYBS", argsList)
15896         if args.Type != ArgList {
15897                 return args
15898         }
15899         settlement := timeFromExcelTime(args.List[0].Number, false)
15900         pcd := timeFromExcelTime(fn.COUPPCD(argsList).Number, false)
15901         return newNumberFormulaArg(coupdays(pcd, settlement, int(args.List[3].Number)))
15902 }
15903
15904 // COUPDAYS function calculates the number of days in a coupon period that
15905 // contains the settlement date. The syntax of the function is:
15906 //
15907 //      COUPDAYS(settlement,maturity,frequency,[basis])
15908 func (fn *formulaFuncs) COUPDAYS(argsList *list.List) formulaArg {
15909         args := fn.prepareCouponArgs("COUPDAYS", argsList)
15910         if args.Type != ArgList {
15911                 return args
15912         }
15913         freq := args.List[2].Number
15914         basis := int(args.List[3].Number)
15915         if basis == 1 {
15916                 pcd := timeFromExcelTime(fn.COUPPCD(argsList).Number, false)
15917                 next := pcd.AddDate(0, 12/int(freq), 0)
15918                 return newNumberFormulaArg(coupdays(pcd, next, basis))
15919         }
15920         return newNumberFormulaArg(float64(getYearDays(0, basis)) / freq)
15921 }
15922
15923 // COUPDAYSNC function calculates the number of days from the settlement date
15924 // to the next coupon date. The syntax of the function is:
15925 //
15926 //      COUPDAYSNC(settlement,maturity,frequency,[basis])
15927 func (fn *formulaFuncs) COUPDAYSNC(argsList *list.List) formulaArg {
15928         args := fn.prepareCouponArgs("COUPDAYSNC", argsList)
15929         if args.Type != ArgList {
15930                 return args
15931         }
15932         settlement := timeFromExcelTime(args.List[0].Number, false)
15933         basis := int(args.List[3].Number)
15934         ncd := timeFromExcelTime(fn.COUPNCD(argsList).Number, false)
15935         return newNumberFormulaArg(coupdays(settlement, ncd, basis))
15936 }
15937
15938 // coupons is an implementation of the formula functions COUPNCD and COUPPCD.
15939 func (fn *formulaFuncs) coupons(name string, arg formulaArg) formulaArg {
15940         settlement := timeFromExcelTime(arg.List[0].Number, false)
15941         maturity := timeFromExcelTime(arg.List[1].Number, false)
15942         maturityDays := (maturity.Year()-settlement.Year())*12 + (int(maturity.Month()) - int(settlement.Month()))
15943         coupon := 12 / int(arg.List[2].Number)
15944         mod := maturityDays % coupon
15945         year := settlement.Year()
15946         month := int(settlement.Month())
15947         if mod == 0 && settlement.Day() >= maturity.Day() {
15948                 month += coupon
15949         } else {
15950                 month += mod
15951         }
15952         if name != "COUPNCD" {
15953                 month -= coupon
15954         }
15955         if month > 11 {
15956                 year++
15957                 month -= 12
15958         } else if month < 0 {
15959                 year--
15960                 month += 12
15961         }
15962         day, lastDay := maturity.Day(), time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.UTC)
15963         days := getDaysInMonth(lastDay.Year(), int(lastDay.Month()))
15964         if getDaysInMonth(maturity.Year(), int(maturity.Month())) == maturity.Day() {
15965                 day = days
15966         } else if day > 27 && day > days {
15967                 day = days
15968         }
15969         return newNumberFormulaArg(daysBetween(excelMinTime1900.Unix(), makeDate(year, time.Month(month), day)) + 1)
15970 }
15971
15972 // COUPNCD function calculates the number of coupons payable, between a
15973 // security's settlement date and maturity date, rounded up to the nearest
15974 // whole coupon. The syntax of the function is:
15975 //
15976 //      COUPNCD(settlement,maturity,frequency,[basis])
15977 func (fn *formulaFuncs) COUPNCD(argsList *list.List) formulaArg {
15978         args := fn.prepareCouponArgs("COUPNCD", argsList)
15979         if args.Type != ArgList {
15980                 return args
15981         }
15982         return fn.coupons("COUPNCD", args)
15983 }
15984
15985 // COUPNUM function calculates the number of coupons payable, between a
15986 // security's settlement date and maturity date, rounded up to the nearest
15987 // whole coupon. The syntax of the function is:
15988 //
15989 //      COUPNUM(settlement,maturity,frequency,[basis])
15990 func (fn *formulaFuncs) COUPNUM(argsList *list.List) formulaArg {
15991         args := fn.prepareCouponArgs("COUPNUM", argsList)
15992         if args.Type != ArgList {
15993                 return args
15994         }
15995         frac := yearFrac(args.List[0].Number, args.List[1].Number, 0)
15996         return newNumberFormulaArg(math.Ceil(frac.Number * args.List[2].Number))
15997 }
15998
15999 // COUPPCD function returns the previous coupon date, before the settlement
16000 // date for a security. The syntax of the function is:
16001 //
16002 //      COUPPCD(settlement,maturity,frequency,[basis])
16003 func (fn *formulaFuncs) COUPPCD(argsList *list.List) formulaArg {
16004         args := fn.prepareCouponArgs("COUPPCD", argsList)
16005         if args.Type != ArgList {
16006                 return args
16007         }
16008         return fn.coupons("COUPPCD", args)
16009 }
16010
16011 // CUMIPMT function calculates the cumulative interest paid on a loan or
16012 // investment, between two specified periods. The syntax of the function is:
16013 //
16014 //      CUMIPMT(rate,nper,pv,start_period,end_period,type)
16015 func (fn *formulaFuncs) CUMIPMT(argsList *list.List) formulaArg {
16016         return fn.cumip("CUMIPMT", argsList)
16017 }
16018
16019 // CUMPRINC function calculates the cumulative payment on the principal of a
16020 // loan or investment, between two specified periods. The syntax of the
16021 // function is:
16022 //
16023 //      CUMPRINC(rate,nper,pv,start_period,end_period,type)
16024 func (fn *formulaFuncs) CUMPRINC(argsList *list.List) formulaArg {
16025         return fn.cumip("CUMPRINC", argsList)
16026 }
16027
16028 // cumip is an implementation of the formula functions CUMIPMT and CUMPRINC.
16029 func (fn *formulaFuncs) cumip(name string, argsList *list.List) formulaArg {
16030         if argsList.Len() != 6 {
16031                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 6 arguments", name))
16032         }
16033         rate := argsList.Front().Value.(formulaArg).ToNumber()
16034         if rate.Type != ArgNumber {
16035                 return rate
16036         }
16037         nper := argsList.Front().Next().Value.(formulaArg).ToNumber()
16038         if nper.Type != ArgNumber {
16039                 return nper
16040         }
16041         pv := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
16042         if pv.Type != ArgNumber {
16043                 return pv
16044         }
16045         start := argsList.Back().Prev().Prev().Value.(formulaArg).ToNumber()
16046         if start.Type != ArgNumber {
16047                 return start
16048         }
16049         end := argsList.Back().Prev().Value.(formulaArg).ToNumber()
16050         if end.Type != ArgNumber {
16051                 return end
16052         }
16053         typ := argsList.Back().Value.(formulaArg).ToNumber()
16054         if typ.Type != ArgNumber {
16055                 return typ
16056         }
16057         if typ.Number != 0 && typ.Number != 1 {
16058                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
16059         }
16060         if start.Number < 1 || start.Number > end.Number {
16061                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
16062         }
16063         num := 0.0
16064         for per := start.Number; per <= end.Number; per++ {
16065                 args := list.New().Init()
16066                 args.PushBack(rate)
16067                 args.PushBack(newNumberFormulaArg(per))
16068                 args.PushBack(nper)
16069                 args.PushBack(pv)
16070                 args.PushBack(newNumberFormulaArg(0))
16071                 args.PushBack(typ)
16072                 if name == "CUMIPMT" {
16073                         num += fn.IPMT(args).Number
16074                         continue
16075                 }
16076                 num += fn.PPMT(args).Number
16077         }
16078         return newNumberFormulaArg(num)
16079 }
16080
16081 // calcDbArgsCompare implements common arguments' comparison for DB and DDB.
16082 func calcDbArgsCompare(cost, salvage, life, period formulaArg) bool {
16083         return (cost.Number <= 0) || ((salvage.Number / cost.Number) < 0) || (life.Number <= 0) || (period.Number < 1)
16084 }
16085
16086 // DB function calculates the depreciation of an asset, using the Fixed
16087 // Declining Balance Method, for each period of the asset's lifetime. The
16088 // syntax of the function is:
16089 //
16090 //      DB(cost,salvage,life,period,[month])
16091 func (fn *formulaFuncs) DB(argsList *list.List) formulaArg {
16092         if argsList.Len() < 4 {
16093                 return newErrorFormulaArg(formulaErrorVALUE, "DB requires at least 4 arguments")
16094         }
16095         if argsList.Len() > 5 {
16096                 return newErrorFormulaArg(formulaErrorVALUE, "DB allows at most 5 arguments")
16097         }
16098         cost := argsList.Front().Value.(formulaArg).ToNumber()
16099         if cost.Type != ArgNumber {
16100                 return cost
16101         }
16102         salvage := argsList.Front().Next().Value.(formulaArg).ToNumber()
16103         if salvage.Type != ArgNumber {
16104                 return salvage
16105         }
16106         life := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
16107         if life.Type != ArgNumber {
16108                 return life
16109         }
16110         period := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
16111         if period.Type != ArgNumber {
16112                 return period
16113         }
16114         month := newNumberFormulaArg(12)
16115         if argsList.Len() == 5 {
16116                 if month = argsList.Back().Value.(formulaArg).ToNumber(); month.Type != ArgNumber {
16117                         return month
16118                 }
16119         }
16120         if cost.Number == 0 {
16121                 return newNumberFormulaArg(0)
16122         }
16123         if calcDbArgsCompare(cost, salvage, life, period) || (month.Number < 1) {
16124                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
16125         }
16126         dr := 1 - math.Pow(salvage.Number/cost.Number, 1/life.Number)
16127         dr = math.Round(dr*1000) / 1000
16128         pd, depreciation := 0.0, 0.0
16129         for per := 1; per <= int(period.Number); per++ {
16130                 if per == 1 {
16131                         depreciation = cost.Number * dr * month.Number / 12
16132                 } else if per == int(life.Number+1) {
16133                         depreciation = (cost.Number - pd) * dr * (12 - month.Number) / 12
16134                 } else {
16135                         depreciation = (cost.Number - pd) * dr
16136                 }
16137                 pd += depreciation
16138         }
16139         return newNumberFormulaArg(depreciation)
16140 }
16141
16142 // DDB function calculates the depreciation of an asset, using the Double
16143 // Declining Balance Method, or another specified depreciation rate. The
16144 // syntax of the function is:
16145 //
16146 //      DDB(cost,salvage,life,period,[factor])
16147 func (fn *formulaFuncs) DDB(argsList *list.List) formulaArg {
16148         if argsList.Len() < 4 {
16149                 return newErrorFormulaArg(formulaErrorVALUE, "DDB requires at least 4 arguments")
16150         }
16151         if argsList.Len() > 5 {
16152                 return newErrorFormulaArg(formulaErrorVALUE, "DDB allows at most 5 arguments")
16153         }
16154         cost := argsList.Front().Value.(formulaArg).ToNumber()
16155         if cost.Type != ArgNumber {
16156                 return cost
16157         }
16158         salvage := argsList.Front().Next().Value.(formulaArg).ToNumber()
16159         if salvage.Type != ArgNumber {
16160                 return salvage
16161         }
16162         life := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
16163         if life.Type != ArgNumber {
16164                 return life
16165         }
16166         period := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
16167         if period.Type != ArgNumber {
16168                 return period
16169         }
16170         factor := newNumberFormulaArg(2)
16171         if argsList.Len() == 5 {
16172                 if factor = argsList.Back().Value.(formulaArg).ToNumber(); factor.Type != ArgNumber {
16173                         return factor
16174                 }
16175         }
16176         if cost.Number == 0 {
16177                 return newNumberFormulaArg(0)
16178         }
16179         if calcDbArgsCompare(cost, salvage, life, period) || (factor.Number <= 0.0) || (period.Number > life.Number) {
16180                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
16181         }
16182         pd, depreciation := 0.0, 0.0
16183         for per := 1; per <= int(period.Number); per++ {
16184                 depreciation = math.Min((cost.Number-pd)*(factor.Number/life.Number), cost.Number-salvage.Number-pd)
16185                 pd += depreciation
16186         }
16187         return newNumberFormulaArg(depreciation)
16188 }
16189
16190 // prepareDataValueArgs convert first N arguments to data value for the
16191 // formula functions.
16192 func (fn *formulaFuncs) prepareDataValueArgs(n int, argsList *list.List) formulaArg {
16193         l := list.New()
16194         var dataValues []formulaArg
16195         getDateValue := func(arg formulaArg, l *list.List) formulaArg {
16196                 switch arg.Type {
16197                 case ArgNumber:
16198                         break
16199                 case ArgString:
16200                         num := arg.ToNumber()
16201                         if num.Type == ArgNumber {
16202                                 arg = num
16203                                 break
16204                         }
16205                         l.Init()
16206                         l.PushBack(arg)
16207                         arg = fn.DATEVALUE(l)
16208                         if arg.Type == ArgError {
16209                                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
16210                         }
16211                 default:
16212                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
16213                 }
16214                 return arg
16215         }
16216         for i, arg := 0, argsList.Front(); i < n; arg = arg.Next() {
16217                 dataValue := getDateValue(arg.Value.(formulaArg), l)
16218                 if dataValue.Type != ArgNumber {
16219                         return dataValue
16220                 }
16221                 dataValues = append(dataValues, dataValue)
16222                 i++
16223         }
16224         return newListFormulaArg(dataValues)
16225 }
16226
16227 // discIntrate is an implementation of the formula functions DISC and INTRATE.
16228 func (fn *formulaFuncs) discIntrate(name string, argsList *list.List) formulaArg {
16229         if argsList.Len() != 4 && argsList.Len() != 5 {
16230                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 4 or 5 arguments", name))
16231         }
16232         args := fn.prepareDataValueArgs(2, argsList)
16233         if args.Type != ArgList {
16234                 return args
16235         }
16236         settlement, maturity, argName := args.List[0], args.List[1], "pr"
16237         if maturity.Number <= settlement.Number {
16238                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires maturity > settlement", name))
16239         }
16240         prInvestment := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
16241         if prInvestment.Type != ArgNumber {
16242                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
16243         }
16244         if prInvestment.Number <= 0 {
16245                 if name == "INTRATE" {
16246                         argName = "investment"
16247                 }
16248                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires %s > 0", name, argName))
16249         }
16250         redemption := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
16251         if redemption.Type != ArgNumber {
16252                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
16253         }
16254         if redemption.Number <= 0 {
16255                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires redemption > 0", name))
16256         }
16257         basis := newNumberFormulaArg(0)
16258         if argsList.Len() == 5 {
16259                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
16260                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
16261                 }
16262         }
16263         frac := yearFrac(settlement.Number, maturity.Number, int(basis.Number))
16264         if frac.Type != ArgNumber {
16265                 return frac
16266         }
16267         if name == "INTRATE" {
16268                 return newNumberFormulaArg((redemption.Number - prInvestment.Number) / prInvestment.Number / frac.Number)
16269         }
16270         return newNumberFormulaArg((redemption.Number - prInvestment.Number) / redemption.Number / frac.Number)
16271 }
16272
16273 // DISC function calculates the Discount Rate for a security. The syntax of
16274 // the function is:
16275 //
16276 //      DISC(settlement,maturity,pr,redemption,[basis])
16277 func (fn *formulaFuncs) DISC(argsList *list.List) formulaArg {
16278         return fn.discIntrate("DISC", argsList)
16279 }
16280
16281 // DOLLARDE function converts a dollar value in fractional notation, into a
16282 // dollar value expressed as a decimal. The syntax of the function is:
16283 //
16284 //      DOLLARDE(fractional_dollar,fraction)
16285 func (fn *formulaFuncs) DOLLARDE(argsList *list.List) formulaArg {
16286         return fn.dollar("DOLLARDE", argsList)
16287 }
16288
16289 // DOLLARFR function converts a dollar value in decimal notation, into a
16290 // dollar value that is expressed in fractional notation. The syntax of the
16291 // function is:
16292 //
16293 //      DOLLARFR(decimal_dollar,fraction)
16294 func (fn *formulaFuncs) DOLLARFR(argsList *list.List) formulaArg {
16295         return fn.dollar("DOLLARFR", argsList)
16296 }
16297
16298 // dollar is an implementation of the formula functions DOLLARDE and DOLLARFR.
16299 func (fn *formulaFuncs) dollar(name string, argsList *list.List) formulaArg {
16300         if argsList.Len() != 2 {
16301                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 arguments", name))
16302         }
16303         dollar := argsList.Front().Value.(formulaArg).ToNumber()
16304         if dollar.Type != ArgNumber {
16305                 return dollar
16306         }
16307         frac := argsList.Back().Value.(formulaArg).ToNumber()
16308         if frac.Type != ArgNumber {
16309                 return frac
16310         }
16311         if frac.Number < 0 {
16312                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
16313         }
16314         if frac.Number == 0 {
16315                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
16316         }
16317         cents := math.Mod(dollar.Number, 1)
16318         if name == "DOLLARDE" {
16319                 cents /= frac.Number
16320                 cents *= math.Pow(10, math.Ceil(math.Log10(frac.Number)))
16321         } else {
16322                 cents *= frac.Number
16323                 cents *= math.Pow(10, -math.Ceil(math.Log10(frac.Number)))
16324         }
16325         return newNumberFormulaArg(math.Floor(dollar.Number) + cents)
16326 }
16327
16328 // prepareDurationArgs checking and prepare arguments for the formula
16329 // functions DURATION and MDURATION.
16330 func (fn *formulaFuncs) prepareDurationArgs(name string, argsList *list.List) formulaArg {
16331         if argsList.Len() != 5 && argsList.Len() != 6 {
16332                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 5 or 6 arguments", name))
16333         }
16334         args := fn.prepareDataValueArgs(2, argsList)
16335         if args.Type != ArgList {
16336                 return args
16337         }
16338         settlement, maturity := args.List[0], args.List[1]
16339         if settlement.Number >= maturity.Number {
16340                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires maturity > settlement", name))
16341         }
16342         coupon := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
16343         if coupon.Type != ArgNumber {
16344                 return coupon
16345         }
16346         if coupon.Number < 0 {
16347                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires coupon >= 0", name))
16348         }
16349         yld := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
16350         if yld.Type != ArgNumber {
16351                 return yld
16352         }
16353         if yld.Number < 0 {
16354                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires yld >= 0", name))
16355         }
16356         frequency := argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
16357         if frequency.Type != ArgNumber {
16358                 return frequency
16359         }
16360         if !validateFrequency(frequency.Number) {
16361                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
16362         }
16363         basis := newNumberFormulaArg(0)
16364         if argsList.Len() == 6 {
16365                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
16366                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
16367                 }
16368         }
16369         return newListFormulaArg([]formulaArg{settlement, maturity, coupon, yld, frequency, basis})
16370 }
16371
16372 // duration is an implementation of the formula function DURATION.
16373 func (fn *formulaFuncs) duration(settlement, maturity, coupon, yld, frequency, basis formulaArg) formulaArg {
16374         frac := yearFrac(settlement.Number, maturity.Number, int(basis.Number))
16375         if frac.Type != ArgNumber {
16376                 return frac
16377         }
16378         argumments := list.New().Init()
16379         argumments.PushBack(settlement)
16380         argumments.PushBack(maturity)
16381         argumments.PushBack(frequency)
16382         argumments.PushBack(basis)
16383         coups := fn.COUPNUM(argumments)
16384         duration := 0.0
16385         p := 0.0
16386         coupon.Number *= 100 / frequency.Number
16387         yld.Number /= frequency.Number
16388         yld.Number++
16389         diff := frac.Number*frequency.Number - coups.Number
16390         for t := 1.0; t < coups.Number; t++ {
16391                 tDiff := t + diff
16392                 add := coupon.Number / math.Pow(yld.Number, tDiff)
16393                 p += add
16394                 duration += tDiff * add
16395         }
16396         add := (coupon.Number + 100) / math.Pow(yld.Number, coups.Number+diff)
16397         p += add
16398         duration += (coups.Number + diff) * add
16399         duration /= p
16400         duration /= frequency.Number
16401         return newNumberFormulaArg(duration)
16402 }
16403
16404 // DURATION function calculates the Duration (specifically, the Macaulay
16405 // Duration) of a security that pays periodic interest, assuming a par value
16406 // of $100. The syntax of the function is:
16407 //
16408 //      DURATION(settlement,maturity,coupon,yld,frequency,[basis])
16409 func (fn *formulaFuncs) DURATION(argsList *list.List) formulaArg {
16410         args := fn.prepareDurationArgs("DURATION", argsList)
16411         if args.Type != ArgList {
16412                 return args
16413         }
16414         return fn.duration(args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5])
16415 }
16416
16417 // EFFECT function returns the effective annual interest rate for a given
16418 // nominal interest rate and number of compounding periods per year. The
16419 // syntax of the function is:
16420 //
16421 //      EFFECT(nominal_rate,npery)
16422 func (fn *formulaFuncs) EFFECT(argsList *list.List) formulaArg {
16423         if argsList.Len() != 2 {
16424                 return newErrorFormulaArg(formulaErrorVALUE, "EFFECT requires 2 arguments")
16425         }
16426         rate := argsList.Front().Value.(formulaArg).ToNumber()
16427         if rate.Type != ArgNumber {
16428                 return rate
16429         }
16430         npery := argsList.Back().Value.(formulaArg).ToNumber()
16431         if npery.Type != ArgNumber {
16432                 return npery
16433         }
16434         if rate.Number <= 0 || npery.Number < 1 {
16435                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
16436         }
16437         return newNumberFormulaArg(math.Pow(1+rate.Number/npery.Number, npery.Number) - 1)
16438 }
16439
16440 // EUROCONVERT function convert a number to euro or from euro to a
16441 // participating currency. You can also use it to convert a number from one
16442 // participating currency to another by using the euro as an intermediary
16443 // (triangulation). The syntax of the function is:
16444 //
16445 //      EUROCONVERT(number,sourcecurrency,targetcurrency[,fullprecision,triangulationprecision])
16446 func (fn *formulaFuncs) EUROCONVERT(argsList *list.List) formulaArg {
16447         if argsList.Len() < 3 {
16448                 return newErrorFormulaArg(formulaErrorVALUE, "EUROCONVERT requires at least 3 arguments")
16449         }
16450         if argsList.Len() > 5 {
16451                 return newErrorFormulaArg(formulaErrorVALUE, "EUROCONVERT allows at most 5 arguments")
16452         }
16453         number := argsList.Front().Value.(formulaArg).ToNumber()
16454         if number.Type != ArgNumber {
16455                 return number
16456         }
16457         sourceCurrency := argsList.Front().Next().Value.(formulaArg).Value()
16458         targetCurrency := argsList.Front().Next().Next().Value.(formulaArg).Value()
16459         fullPrec, triangulationPrec := newBoolFormulaArg(false), newNumberFormulaArg(0)
16460         if argsList.Len() >= 4 {
16461                 if fullPrec = argsList.Front().Next().Next().Next().Value.(formulaArg).ToBool(); fullPrec.Type != ArgNumber {
16462                         return fullPrec
16463                 }
16464         }
16465         if argsList.Len() == 5 {
16466                 if triangulationPrec = argsList.Back().Value.(formulaArg).ToNumber(); triangulationPrec.Type != ArgNumber {
16467                         return triangulationPrec
16468                 }
16469         }
16470         convertTable := map[string][]float64{
16471                 "EUR": {1.0, 2},
16472                 "ATS": {13.7603, 2},
16473                 "BEF": {40.3399, 0},
16474                 "DEM": {1.95583, 2},
16475                 "ESP": {166.386, 0},
16476                 "FIM": {5.94573, 2},
16477                 "FRF": {6.55957, 2},
16478                 "IEP": {0.787564, 2},
16479                 "ITL": {1936.27, 0},
16480                 "LUF": {40.3399, 0},
16481                 "NLG": {2.20371, 2},
16482                 "PTE": {200.482, 2},
16483                 "GRD": {340.750, 2},
16484                 "SIT": {239.640, 2},
16485                 "MTL": {0.429300, 2},
16486                 "CYP": {0.585274, 2},
16487                 "SKK": {30.1260, 2},
16488                 "EEK": {15.6466, 2},
16489                 "LVL": {0.702804, 2},
16490                 "LTL": {3.45280, 2},
16491         }
16492         source, ok := convertTable[sourceCurrency]
16493         if !ok {
16494                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
16495         }
16496         target, ok := convertTable[targetCurrency]
16497         if !ok {
16498                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
16499         }
16500         if sourceCurrency == targetCurrency {
16501                 return number
16502         }
16503         var res float64
16504         if sourceCurrency == "EUR" {
16505                 res = number.Number * target[0]
16506         } else {
16507                 intermediate := number.Number / source[0]
16508                 if triangulationPrec.Number != 0 {
16509                         ratio := math.Pow(10, triangulationPrec.Number)
16510                         intermediate = math.Round(intermediate*ratio) / ratio
16511                 }
16512                 res = intermediate * target[0]
16513         }
16514         if fullPrec.Number != 1 {
16515                 ratio := math.Pow(10, target[1])
16516                 res = math.Round(res*ratio) / ratio
16517         }
16518         return newNumberFormulaArg(res)
16519 }
16520
16521 // FV function calculates the Future Value of an investment with periodic
16522 // constant payments and a constant interest rate. The syntax of the function
16523 // is:
16524 //
16525 //      FV(rate,nper,[pmt],[pv],[type])
16526 func (fn *formulaFuncs) FV(argsList *list.List) formulaArg {
16527         if argsList.Len() < 3 {
16528                 return newErrorFormulaArg(formulaErrorVALUE, "FV requires at least 3 arguments")
16529         }
16530         if argsList.Len() > 5 {
16531                 return newErrorFormulaArg(formulaErrorVALUE, "FV allows at most 5 arguments")
16532         }
16533         rate := argsList.Front().Value.(formulaArg).ToNumber()
16534         if rate.Type != ArgNumber {
16535                 return rate
16536         }
16537         nper := argsList.Front().Next().Value.(formulaArg).ToNumber()
16538         if nper.Type != ArgNumber {
16539                 return nper
16540         }
16541         pmt := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
16542         if pmt.Type != ArgNumber {
16543                 return pmt
16544         }
16545         pv, typ := newNumberFormulaArg(0), newNumberFormulaArg(0)
16546         if argsList.Len() >= 4 {
16547                 if pv = argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber(); pv.Type != ArgNumber {
16548                         return pv
16549                 }
16550         }
16551         if argsList.Len() == 5 {
16552                 if typ = argsList.Back().Value.(formulaArg).ToNumber(); typ.Type != ArgNumber {
16553                         return typ
16554                 }
16555         }
16556         if typ.Number != 0 && typ.Number != 1 {
16557                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
16558         }
16559         if rate.Number != 0 {
16560                 return newNumberFormulaArg(-pv.Number*math.Pow(1+rate.Number, nper.Number) - pmt.Number*(1+rate.Number*typ.Number)*(math.Pow(1+rate.Number, nper.Number)-1)/rate.Number)
16561         }
16562         return newNumberFormulaArg(-pv.Number - pmt.Number*nper.Number)
16563 }
16564
16565 // FVSCHEDULE function calculates the Future Value of an investment with a
16566 // variable interest rate. The syntax of the function is:
16567 //
16568 //      FVSCHEDULE(principal,schedule)
16569 func (fn *formulaFuncs) FVSCHEDULE(argsList *list.List) formulaArg {
16570         if argsList.Len() != 2 {
16571                 return newErrorFormulaArg(formulaErrorVALUE, "FVSCHEDULE requires 2 arguments")
16572         }
16573         pri := argsList.Front().Value.(formulaArg).ToNumber()
16574         if pri.Type != ArgNumber {
16575                 return pri
16576         }
16577         principal := pri.Number
16578         for _, arg := range argsList.Back().Value.(formulaArg).ToList() {
16579                 if arg.Value() == "" {
16580                         continue
16581                 }
16582                 rate := arg.ToNumber()
16583                 if rate.Type != ArgNumber {
16584                         return rate
16585                 }
16586                 principal *= 1 + rate.Number
16587         }
16588         return newNumberFormulaArg(principal)
16589 }
16590
16591 // INTRATE function calculates the interest rate for a fully invested
16592 // security. The syntax of the function is:
16593 //
16594 //      INTRATE(settlement,maturity,investment,redemption,[basis])
16595 func (fn *formulaFuncs) INTRATE(argsList *list.List) formulaArg {
16596         return fn.discIntrate("INTRATE", argsList)
16597 }
16598
16599 // IPMT function calculates the interest payment, during a specific period of a
16600 // loan or investment that is paid in constant periodic payments, with a
16601 // constant interest rate. The syntax of the function is:
16602 //
16603 //      IPMT(rate,per,nper,pv,[fv],[type])
16604 func (fn *formulaFuncs) IPMT(argsList *list.List) formulaArg {
16605         return fn.ipmt("IPMT", argsList)
16606 }
16607
16608 // calcIpmt is part of the implementation ipmt.
16609 func calcIpmt(name string, typ, per, pmt, pv, rate formulaArg) formulaArg {
16610         capital, interest, principal := pv.Number, 0.0, 0.0
16611         for i := 1; i <= int(per.Number); i++ {
16612                 if typ.Number != 0 && i == 1 {
16613                         interest = 0
16614                 } else {
16615                         interest = -capital * rate.Number
16616                 }
16617                 principal = pmt.Number - interest
16618                 capital += principal
16619         }
16620         if name == "IPMT" {
16621                 return newNumberFormulaArg(interest)
16622         }
16623         return newNumberFormulaArg(principal)
16624 }
16625
16626 // ipmt is an implementation of the formula functions IPMT and PPMT.
16627 func (fn *formulaFuncs) ipmt(name string, argsList *list.List) formulaArg {
16628         if argsList.Len() < 4 {
16629                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 4 arguments", name))
16630         }
16631         if argsList.Len() > 6 {
16632                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s allows at most 6 arguments", name))
16633         }
16634         rate := argsList.Front().Value.(formulaArg).ToNumber()
16635         if rate.Type != ArgNumber {
16636                 return rate
16637         }
16638         per := argsList.Front().Next().Value.(formulaArg).ToNumber()
16639         if per.Type != ArgNumber {
16640                 return per
16641         }
16642         nper := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
16643         if nper.Type != ArgNumber {
16644                 return nper
16645         }
16646         pv := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
16647         if pv.Type != ArgNumber {
16648                 return pv
16649         }
16650         fv, typ := newNumberFormulaArg(0), newNumberFormulaArg(0)
16651         if argsList.Len() >= 5 {
16652                 if fv = argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber(); fv.Type != ArgNumber {
16653                         return fv
16654                 }
16655         }
16656         if argsList.Len() == 6 {
16657                 if typ = argsList.Back().Value.(formulaArg).ToNumber(); typ.Type != ArgNumber {
16658                         return typ
16659                 }
16660         }
16661         if typ.Number != 0 && typ.Number != 1 {
16662                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
16663         }
16664         if per.Number <= 0 || per.Number > nper.Number {
16665                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
16666         }
16667         args := list.New().Init()
16668         args.PushBack(rate)
16669         args.PushBack(nper)
16670         args.PushBack(pv)
16671         args.PushBack(fv)
16672         args.PushBack(typ)
16673         pmt := fn.PMT(args)
16674         return calcIpmt(name, typ, per, pmt, pv, rate)
16675 }
16676
16677 // IRR function returns the Internal Rate of Return for a supplied series of
16678 // periodic cash flows (i.e. an initial investment value and a series of net
16679 // income values). The syntax of the function is:
16680 //
16681 //      IRR(values,[guess])
16682 func (fn *formulaFuncs) IRR(argsList *list.List) formulaArg {
16683         if argsList.Len() < 1 {
16684                 return newErrorFormulaArg(formulaErrorVALUE, "IRR requires at least 1 argument")
16685         }
16686         if argsList.Len() > 2 {
16687                 return newErrorFormulaArg(formulaErrorVALUE, "IRR allows at most 2 arguments")
16688         }
16689         values, guess := argsList.Front().Value.(formulaArg).ToList(), newNumberFormulaArg(0.1)
16690         if argsList.Len() > 1 {
16691                 if guess = argsList.Back().Value.(formulaArg).ToNumber(); guess.Type != ArgNumber {
16692                         return guess
16693                 }
16694         }
16695         x1, x2 := newNumberFormulaArg(0), guess
16696         args := list.New().Init()
16697         args.PushBack(x1)
16698         for _, v := range values {
16699                 args.PushBack(v)
16700         }
16701         f1 := fn.NPV(args)
16702         args.Front().Value = x2
16703         f2 := fn.NPV(args)
16704         for i := 0; i < maxFinancialIterations; i++ {
16705                 if f1.Number*f2.Number < 0 {
16706                         break
16707                 }
16708                 if math.Abs(f1.Number) < math.Abs(f2.Number) {
16709                         x1.Number += 1.6 * (x1.Number - x2.Number)
16710                         args.Front().Value = x1
16711                         f1 = fn.NPV(args)
16712                         continue
16713                 }
16714                 x2.Number += 1.6 * (x2.Number - x1.Number)
16715                 args.Front().Value = x2
16716                 f2 = fn.NPV(args)
16717         }
16718         if f1.Number*f2.Number > 0 {
16719                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
16720         }
16721         args.Front().Value = x1
16722         f := fn.NPV(args)
16723         var rtb, dx, xMid, fMid float64
16724         if f.Number < 0 {
16725                 rtb = x1.Number
16726                 dx = x2.Number - x1.Number
16727         } else {
16728                 rtb = x2.Number
16729                 dx = x1.Number - x2.Number
16730         }
16731         for i := 0; i < maxFinancialIterations; i++ {
16732                 dx *= 0.5
16733                 xMid = rtb + dx
16734                 args.Front().Value = newNumberFormulaArg(xMid)
16735                 fMid = fn.NPV(args).Number
16736                 if fMid <= 0 {
16737                         rtb = xMid
16738                 }
16739                 if math.Abs(fMid) < financialPrecision || math.Abs(dx) < financialPrecision {
16740                         break
16741                 }
16742         }
16743         return newNumberFormulaArg(xMid)
16744 }
16745
16746 // ISPMT function calculates the interest paid during a specific period of a
16747 // loan or investment. The syntax of the function is:
16748 //
16749 //      ISPMT(rate,per,nper,pv)
16750 func (fn *formulaFuncs) ISPMT(argsList *list.List) formulaArg {
16751         if argsList.Len() != 4 {
16752                 return newErrorFormulaArg(formulaErrorVALUE, "ISPMT requires 4 arguments")
16753         }
16754         rate := argsList.Front().Value.(formulaArg).ToNumber()
16755         if rate.Type != ArgNumber {
16756                 return rate
16757         }
16758         per := argsList.Front().Next().Value.(formulaArg).ToNumber()
16759         if per.Type != ArgNumber {
16760                 return per
16761         }
16762         nper := argsList.Back().Prev().Value.(formulaArg).ToNumber()
16763         if nper.Type != ArgNumber {
16764                 return nper
16765         }
16766         pv := argsList.Back().Value.(formulaArg).ToNumber()
16767         if pv.Type != ArgNumber {
16768                 return pv
16769         }
16770         pr, payment, num := pv.Number, pv.Number/nper.Number, 0.0
16771         for i := 0; i <= int(per.Number); i++ {
16772                 num = rate.Number * pr * -1
16773                 pr -= payment
16774                 if i == int(nper.Number) {
16775                         num = 0
16776                 }
16777         }
16778         return newNumberFormulaArg(num)
16779 }
16780
16781 // MDURATION function calculates the Modified Macaulay Duration of a security
16782 // that pays periodic interest, assuming a par value of $100. The syntax of
16783 // the function is:
16784 //
16785 //      MDURATION(settlement,maturity,coupon,yld,frequency,[basis])
16786 func (fn *formulaFuncs) MDURATION(argsList *list.List) formulaArg {
16787         args := fn.prepareDurationArgs("MDURATION", argsList)
16788         if args.Type != ArgList {
16789                 return args
16790         }
16791         duration := fn.duration(args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5])
16792         if duration.Type != ArgNumber {
16793                 return duration
16794         }
16795         return newNumberFormulaArg(duration.Number / (1 + args.List[3].Number/args.List[4].Number))
16796 }
16797
16798 // MIRR function returns the Modified Internal Rate of Return for a supplied
16799 // series of periodic cash flows (i.e. a set of values, which includes an
16800 // initial investment value and a series of net income values). The syntax of
16801 // the function is:
16802 //
16803 //      MIRR(values,finance_rate,reinvest_rate)
16804 func (fn *formulaFuncs) MIRR(argsList *list.List) formulaArg {
16805         if argsList.Len() != 3 {
16806                 return newErrorFormulaArg(formulaErrorVALUE, "MIRR requires 3 arguments")
16807         }
16808         values := argsList.Front().Value.(formulaArg).ToList()
16809         financeRate := argsList.Front().Next().Value.(formulaArg).ToNumber()
16810         if financeRate.Type != ArgNumber {
16811                 return financeRate
16812         }
16813         reinvestRate := argsList.Back().Value.(formulaArg).ToNumber()
16814         if reinvestRate.Type != ArgNumber {
16815                 return reinvestRate
16816         }
16817         n, fr, rr, npvPos, npvNeg := len(values), 1+financeRate.Number, 1+reinvestRate.Number, 0.0, 0.0
16818         for i, v := range values {
16819                 val := v.ToNumber()
16820                 if val.Number >= 0 {
16821                         npvPos += val.Number / math.Pow(rr, float64(i))
16822                         continue
16823                 }
16824                 npvNeg += val.Number / math.Pow(fr, float64(i))
16825         }
16826         if npvNeg == 0 || npvPos == 0 || reinvestRate.Number <= -1 {
16827                 return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
16828         }
16829         return newNumberFormulaArg(math.Pow(-npvPos*math.Pow(rr, float64(n))/(npvNeg*rr), 1/(float64(n)-1)) - 1)
16830 }
16831
16832 // NOMINAL function returns the nominal interest rate for a given effective
16833 // interest rate and number of compounding periods per year. The syntax of
16834 // the function is:
16835 //
16836 //      NOMINAL(effect_rate,npery)
16837 func (fn *formulaFuncs) NOMINAL(argsList *list.List) formulaArg {
16838         if argsList.Len() != 2 {
16839                 return newErrorFormulaArg(formulaErrorVALUE, "NOMINAL requires 2 arguments")
16840         }
16841         rate := argsList.Front().Value.(formulaArg).ToNumber()
16842         if rate.Type != ArgNumber {
16843                 return rate
16844         }
16845         npery := argsList.Back().Value.(formulaArg).ToNumber()
16846         if npery.Type != ArgNumber {
16847                 return npery
16848         }
16849         if rate.Number <= 0 || npery.Number < 1 {
16850                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
16851         }
16852         return newNumberFormulaArg(npery.Number * (math.Pow(rate.Number+1, 1/npery.Number) - 1))
16853 }
16854
16855 // NPER function calculates the number of periods required to pay off a loan,
16856 // for a constant periodic payment and a constant interest rate. The syntax
16857 // of the function is:
16858 //
16859 //      NPER(rate,pmt,pv,[fv],[type])
16860 func (fn *formulaFuncs) NPER(argsList *list.List) formulaArg {
16861         if argsList.Len() < 3 {
16862                 return newErrorFormulaArg(formulaErrorVALUE, "NPER requires at least 3 arguments")
16863         }
16864         if argsList.Len() > 5 {
16865                 return newErrorFormulaArg(formulaErrorVALUE, "NPER allows at most 5 arguments")
16866         }
16867         rate := argsList.Front().Value.(formulaArg).ToNumber()
16868         if rate.Type != ArgNumber {
16869                 return rate
16870         }
16871         pmt := argsList.Front().Next().Value.(formulaArg).ToNumber()
16872         if pmt.Type != ArgNumber {
16873                 return pmt
16874         }
16875         pv := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
16876         if pv.Type != ArgNumber {
16877                 return pv
16878         }
16879         fv, typ := newNumberFormulaArg(0), newNumberFormulaArg(0)
16880         if argsList.Len() >= 4 {
16881                 if fv = argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber(); fv.Type != ArgNumber {
16882                         return fv
16883                 }
16884         }
16885         if argsList.Len() == 5 {
16886                 if typ = argsList.Back().Value.(formulaArg).ToNumber(); typ.Type != ArgNumber {
16887                         return typ
16888                 }
16889         }
16890         if typ.Number != 0 && typ.Number != 1 {
16891                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
16892         }
16893         if pmt.Number == 0 {
16894                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
16895         }
16896         if rate.Number != 0 {
16897                 p := math.Log((pmt.Number*(1+rate.Number*typ.Number)/rate.Number-fv.Number)/(pv.Number+pmt.Number*(1+rate.Number*typ.Number)/rate.Number)) / math.Log(1+rate.Number)
16898                 return newNumberFormulaArg(p)
16899         }
16900         return newNumberFormulaArg((-pv.Number - fv.Number) / pmt.Number)
16901 }
16902
16903 // NPV function calculates the Net Present Value of an investment, based on a
16904 // supplied discount rate, and a series of future payments and income. The
16905 // syntax of the function is:
16906 //
16907 //      NPV(rate,value1,[value2],[value3],...)
16908 func (fn *formulaFuncs) NPV(argsList *list.List) formulaArg {
16909         if argsList.Len() < 2 {
16910                 return newErrorFormulaArg(formulaErrorVALUE, "NPV requires at least 2 arguments")
16911         }
16912         rate := argsList.Front().Value.(formulaArg).ToNumber()
16913         if rate.Type != ArgNumber {
16914                 return rate
16915         }
16916         val, i := 0.0, 1
16917         for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() {
16918                 num := arg.Value.(formulaArg).ToNumber()
16919                 if num.Type != ArgNumber {
16920                         continue
16921                 }
16922                 val += num.Number / math.Pow(1+rate.Number, float64(i))
16923                 i++
16924         }
16925         return newNumberFormulaArg(val)
16926 }
16927
16928 // aggrBetween is a part of implementation of the formula function ODDFPRICE.
16929 func aggrBetween(startPeriod, endPeriod float64, initialValue []float64, f func(acc []float64, index float64) []float64) []float64 {
16930         var s []float64
16931         if startPeriod <= endPeriod {
16932                 for i := startPeriod; i <= endPeriod; i++ {
16933                         s = append(s, i)
16934                 }
16935         } else {
16936                 for i := startPeriod; i >= endPeriod; i-- {
16937                         s = append(s, i)
16938                 }
16939         }
16940         return fold(f, initialValue, s)
16941 }
16942
16943 // fold is a part of implementation of the formula function ODDFPRICE.
16944 func fold(f func(acc []float64, index float64) []float64, state []float64, source []float64) []float64 {
16945         length, value := len(source), state
16946         for index := 0; length > index; index++ {
16947                 value = f(value, source[index])
16948         }
16949         return value
16950 }
16951
16952 // changeMonth is a part of implementation of the formula function ODDFPRICE.
16953 func changeMonth(date time.Time, numMonths float64, returnLastMonth bool) time.Time {
16954         offsetDay := 0
16955         if returnLastMonth && date.Day() == getDaysInMonth(date.Year(), int(date.Month())) {
16956                 offsetDay--
16957         }
16958         newDate := date.AddDate(0, int(numMonths), offsetDay)
16959         if returnLastMonth {
16960                 lastDay := getDaysInMonth(newDate.Year(), int(newDate.Month()))
16961                 return timeFromExcelTime(daysBetween(excelMinTime1900.Unix(), makeDate(newDate.Year(), newDate.Month(), lastDay))+1, false)
16962         }
16963         return newDate
16964 }
16965
16966 // datesAggregate is a part of implementation of the formula function
16967 // ODDFPRICE.
16968 func datesAggregate(startDate, endDate time.Time, numMonths float64, f func(pcd, ncd time.Time) float64, acc float64, returnLastMonth bool) (time.Time, time.Time, float64) {
16969         frontDate, trailingDate := startDate, endDate
16970         s1 := frontDate.After(endDate) || frontDate.Equal(endDate)
16971         s2 := endDate.After(frontDate) || endDate.Equal(frontDate)
16972         stop := s2
16973         if numMonths > 0 {
16974                 stop = s1
16975         }
16976         for !stop {
16977                 trailingDate = frontDate
16978                 frontDate = changeMonth(frontDate, numMonths, returnLastMonth)
16979                 fn := f(frontDate, trailingDate)
16980                 acc += fn
16981                 s1 = frontDate.After(endDate) || frontDate.Equal(endDate)
16982                 s2 = endDate.After(frontDate) || endDate.Equal(frontDate)
16983                 stop = s2
16984                 if numMonths > 0 {
16985                         stop = s1
16986                 }
16987         }
16988         return frontDate, trailingDate, acc
16989 }
16990
16991 // coupNumber is a part of implementation of the formula function ODDFPRICE.
16992 func coupNumber(maturity, settlement, numMonths float64) float64 {
16993         maturityTime, settlementTime := timeFromExcelTime(maturity, false), timeFromExcelTime(settlement, false)
16994         my, mm, md := maturityTime.Year(), maturityTime.Month(), maturityTime.Day()
16995         sy, sm, sd := settlementTime.Year(), settlementTime.Month(), settlementTime.Day()
16996         couponsTemp, endOfMonthTemp := 0.0, getDaysInMonth(my, int(mm)) == md
16997         endOfMonth := endOfMonthTemp
16998         if !endOfMonthTemp && mm != 2 && md > 28 && md < getDaysInMonth(my, int(mm)) {
16999                 endOfMonth = getDaysInMonth(sy, int(sm)) == sd
17000         }
17001         startDate := changeMonth(settlementTime, 0, endOfMonth)
17002         coupons := couponsTemp
17003         if startDate.After(settlementTime) {
17004                 coupons++
17005         }
17006         date := changeMonth(startDate, numMonths, endOfMonth)
17007         f := func(pcd, ncd time.Time) float64 {
17008                 return 1
17009         }
17010         _, _, result := datesAggregate(date, maturityTime, numMonths, f, coupons, endOfMonth)
17011         return result
17012 }
17013
17014 // prepareOddYldOrPrArg checking and prepare yield or price arguments for the
17015 // formula functions ODDFPRICE, ODDFYIELD, ODDLPRICE and ODDLYIELD.
17016 func prepareOddYldOrPrArg(name string, arg formulaArg) formulaArg {
17017         yldOrPr := arg.ToNumber()
17018         if yldOrPr.Type != ArgNumber {
17019                 return yldOrPr
17020         }
17021         if (name == "ODDFPRICE" || name == "ODDLPRICE") && yldOrPr.Number < 0 {
17022                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires yld >= 0", name))
17023         }
17024         if (name == "ODDFYIELD" || name == "ODDLYIELD") && yldOrPr.Number <= 0 {
17025                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires pr > 0", name))
17026         }
17027         return yldOrPr
17028 }
17029
17030 // prepareOddfArgs checking and prepare arguments for the formula
17031 // functions ODDFPRICE and ODDFYIELD.
17032 func (fn *formulaFuncs) prepareOddfArgs(name string, argsList *list.List) formulaArg {
17033         dateValues := fn.prepareDataValueArgs(4, argsList)
17034         if dateValues.Type != ArgList {
17035                 return dateValues
17036         }
17037         settlement, maturity, issue, firstCoupon := dateValues.List[0], dateValues.List[1], dateValues.List[2], dateValues.List[3]
17038         if issue.Number >= settlement.Number {
17039                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires settlement > issue", name))
17040         }
17041         if settlement.Number >= firstCoupon.Number {
17042                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires first_coupon > settlement", name))
17043         }
17044         if firstCoupon.Number >= maturity.Number {
17045                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires maturity > first_coupon", name))
17046         }
17047         rate := argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
17048         if rate.Type != ArgNumber {
17049                 return rate
17050         }
17051         if rate.Number < 0 {
17052                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires rate >= 0", name))
17053         }
17054         yldOrPr := prepareOddYldOrPrArg(name, argsList.Front().Next().Next().Next().Next().Next().Value.(formulaArg))
17055         if yldOrPr.Type != ArgNumber {
17056                 return yldOrPr
17057         }
17058         redemption := argsList.Front().Next().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
17059         if redemption.Type != ArgNumber {
17060                 return redemption
17061         }
17062         if redemption.Number <= 0 {
17063                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires redemption > 0", name))
17064         }
17065         frequency := argsList.Front().Next().Next().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
17066         if frequency.Type != ArgNumber {
17067                 return frequency
17068         }
17069         if !validateFrequency(frequency.Number) {
17070                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17071         }
17072         basis := newNumberFormulaArg(0)
17073         if argsList.Len() == 9 {
17074                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
17075                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17076                 }
17077         }
17078         return newListFormulaArg([]formulaArg{settlement, maturity, issue, firstCoupon, rate, yldOrPr, redemption, frequency, basis})
17079 }
17080
17081 // ODDFPRICE function calculates the price per $100 face value of a security
17082 // with an odd (short or long) first period. The syntax of the function is:
17083 //
17084 //      ODDFPRICE(settlement,maturity,issue,first_coupon,rate,yld,redemption,frequency,[basis])
17085 func (fn *formulaFuncs) ODDFPRICE(argsList *list.List) formulaArg {
17086         if argsList.Len() != 8 && argsList.Len() != 9 {
17087                 return newErrorFormulaArg(formulaErrorVALUE, "ODDFPRICE requires 8 or 9 arguments")
17088         }
17089         args := fn.prepareOddfArgs("ODDFPRICE", argsList)
17090         if args.Type != ArgList {
17091                 return args
17092         }
17093         settlement, maturity, issue, firstCoupon, rate, yld, redemption, frequency, basisArg := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5], args.List[6], args.List[7], args.List[8]
17094         if basisArg.Number < 0 || basisArg.Number > 4 {
17095                 return newErrorFormulaArg(formulaErrorNUM, "invalid basis")
17096         }
17097         issueTime := timeFromExcelTime(issue.Number, false)
17098         settlementTime := timeFromExcelTime(settlement.Number, false)
17099         maturityTime := timeFromExcelTime(maturity.Number, false)
17100         firstCouponTime := timeFromExcelTime(firstCoupon.Number, false)
17101         basis := int(basisArg.Number)
17102         monthDays := getDaysInMonth(maturityTime.Year(), int(maturityTime.Month()))
17103         returnLastMonth := monthDays == maturityTime.Day()
17104         numMonths := 12 / frequency.Number
17105         numMonthsNeg := -numMonths
17106         mat := changeMonth(maturityTime, numMonthsNeg, returnLastMonth)
17107         pcd, _, _ := datesAggregate(mat, firstCouponTime, numMonthsNeg, func(d1, d2 time.Time) float64 {
17108                 return 0
17109         }, 0, returnLastMonth)
17110         if !pcd.Equal(firstCouponTime) {
17111                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17112         }
17113         fnArgs := list.New().Init()
17114         fnArgs.PushBack(settlement)
17115         fnArgs.PushBack(maturity)
17116         fnArgs.PushBack(frequency)
17117         fnArgs.PushBack(basisArg)
17118         e := fn.COUPDAYS(fnArgs)
17119         n := fn.COUPNUM(fnArgs)
17120         m := frequency.Number
17121         dfc := coupdays(issueTime, firstCouponTime, basis)
17122         if dfc < e.Number {
17123                 dsc := coupdays(settlementTime, firstCouponTime, basis)
17124                 a := coupdays(issueTime, settlementTime, basis)
17125                 x := yld.Number/m + 1
17126                 y := dsc / e.Number
17127                 p1 := x
17128                 p3 := math.Pow(p1, n.Number-1+y)
17129                 term1 := redemption.Number / p3
17130                 term2 := 100 * rate.Number / m * dfc / e.Number / math.Pow(p1, y)
17131                 f := func(acc []float64, index float64) []float64 {
17132                         return []float64{acc[0] + 100*rate.Number/m/math.Pow(p1, index-1+y)}
17133                 }
17134                 term3 := aggrBetween(2, math.Floor(n.Number), []float64{0}, f)
17135                 p2 := rate.Number / m
17136                 term4 := a / e.Number * p2 * 100
17137                 return newNumberFormulaArg(term1 + term2 + term3[0] - term4)
17138         }
17139         fnArgs.Init()
17140         fnArgs.PushBack(issue)
17141         fnArgs.PushBack(firstCoupon)
17142         fnArgs.PushBack(frequency)
17143         nc := fn.COUPNUM(fnArgs)
17144         lastCoupon := firstCoupon.Number
17145         aggrFunc := func(acc []float64, index float64) []float64 {
17146                 lastCouponTime := timeFromExcelTime(lastCoupon, false)
17147                 earlyCoupon := daysBetween(excelMinTime1900.Unix(), makeDate(lastCouponTime.Year(), time.Month(float64(lastCouponTime.Month())+numMonthsNeg), lastCouponTime.Day())) + 1
17148                 earlyCouponTime := timeFromExcelTime(earlyCoupon, false)
17149                 nl := e.Number
17150                 if basis == 1 {
17151                         nl = coupdays(earlyCouponTime, lastCouponTime, basis)
17152                 }
17153                 dci := coupdays(issueTime, lastCouponTime, basis)
17154                 if index > 1 {
17155                         dci = nl
17156                 }
17157                 startDate := earlyCoupon
17158                 if issue.Number > earlyCoupon {
17159                         startDate = issue.Number
17160                 }
17161                 endDate := lastCoupon
17162                 if settlement.Number < lastCoupon {
17163                         endDate = settlement.Number
17164                 }
17165                 startDateTime := timeFromExcelTime(startDate, false)
17166                 endDateTime := timeFromExcelTime(endDate, false)
17167                 a := coupdays(startDateTime, endDateTime, basis)
17168                 lastCoupon = earlyCoupon
17169                 dcnl := acc[0]
17170                 anl := acc[1]
17171                 return []float64{dcnl + dci/nl, anl + a/nl}
17172         }
17173         ag := aggrBetween(math.Floor(nc.Number), 1, []float64{0, 0}, aggrFunc)
17174         dcnl, anl := ag[0], ag[1]
17175         dsc := 0.0
17176         fnArgs.Init()
17177         fnArgs.PushBack(settlement)
17178         fnArgs.PushBack(firstCoupon)
17179         fnArgs.PushBack(frequency)
17180         if basis == 2 || basis == 3 {
17181                 d := timeFromExcelTime(fn.COUPNCD(fnArgs).Number, false)
17182                 dsc = coupdays(settlementTime, d, basis)
17183         } else {
17184                 d := timeFromExcelTime(fn.COUPPCD(fnArgs).Number, false)
17185                 a := coupdays(d, settlementTime, basis)
17186                 dsc = e.Number - a
17187         }
17188         nq := coupNumber(firstCoupon.Number, settlement.Number, numMonths)
17189         fnArgs.Init()
17190         fnArgs.PushBack(firstCoupon)
17191         fnArgs.PushBack(maturity)
17192         fnArgs.PushBack(frequency)
17193         fnArgs.PushBack(basisArg)
17194         n = fn.COUPNUM(fnArgs)
17195         x := yld.Number/m + 1
17196         y := dsc / e.Number
17197         p1 := x
17198         p3 := math.Pow(p1, y+nq+n.Number)
17199         term1 := redemption.Number / p3
17200         term2 := 100 * rate.Number / m * dcnl / math.Pow(p1, nq+y)
17201         f := func(acc []float64, index float64) []float64 {
17202                 return []float64{acc[0] + 100*rate.Number/m/math.Pow(p1, index+nq+y)}
17203         }
17204         term3 := aggrBetween(1, math.Floor(n.Number), []float64{0}, f)
17205         term4 := 100 * rate.Number / m * anl
17206         return newNumberFormulaArg(term1 + term2 + term3[0] - term4)
17207 }
17208
17209 // getODDFPRICE is a part of implementation of the formula function ODDFPRICE.
17210 func getODDFPRICE(f func(yld float64) float64, x, cnt, prec float64) float64 {
17211         const maxCnt = 20.0
17212         d := func(f func(yld float64) float64, x float64) float64 {
17213                 return (f(x+prec) - f(x-prec)) / (2 * prec)
17214         }
17215         fx, Fx := f(x), d(f, x)
17216         newX := x - (fx / Fx)
17217         if math.Abs(newX-x) < prec {
17218                 return newX
17219         } else if cnt > maxCnt {
17220                 return newX
17221         }
17222         return getODDFPRICE(f, newX, cnt+1, prec)
17223 }
17224
17225 // ODDFYIELD function calculates the yield of a security with an odd (short or
17226 // long) first period. The syntax of the function is:
17227 //
17228 //      ODDFYIELD(settlement,maturity,issue,first_coupon,rate,pr,redemption,frequency,[basis])
17229 func (fn *formulaFuncs) ODDFYIELD(argsList *list.List) formulaArg {
17230         if argsList.Len() != 8 && argsList.Len() != 9 {
17231                 return newErrorFormulaArg(formulaErrorVALUE, "ODDFYIELD requires 8 or 9 arguments")
17232         }
17233         args := fn.prepareOddfArgs("ODDFYIELD", argsList)
17234         if args.Type != ArgList {
17235                 return args
17236         }
17237         settlement, maturity, issue, firstCoupon, rate, pr, redemption, frequency, basisArg := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5], args.List[6], args.List[7], args.List[8]
17238         if basisArg.Number < 0 || basisArg.Number > 4 {
17239                 return newErrorFormulaArg(formulaErrorNUM, "invalid basis")
17240         }
17241         settlementTime := timeFromExcelTime(settlement.Number, false)
17242         maturityTime := timeFromExcelTime(maturity.Number, false)
17243         years := coupdays(settlementTime, maturityTime, int(basisArg.Number))
17244         px := pr.Number - 100
17245         num := rate.Number*years*100 - px
17246         denum := px/4 + years*px/2 + years*100
17247         guess := num / denum
17248         f := func(yld float64) float64 {
17249                 fnArgs := list.New().Init()
17250                 fnArgs.PushBack(settlement)
17251                 fnArgs.PushBack(maturity)
17252                 fnArgs.PushBack(issue)
17253                 fnArgs.PushBack(firstCoupon)
17254                 fnArgs.PushBack(rate)
17255                 fnArgs.PushBack(newNumberFormulaArg(yld))
17256                 fnArgs.PushBack(redemption)
17257                 fnArgs.PushBack(frequency)
17258                 fnArgs.PushBack(basisArg)
17259                 return pr.Number - fn.ODDFPRICE(fnArgs).Number
17260         }
17261         if result := getODDFPRICE(f, guess, 0, 1e-7); !math.IsInf(result, 0) {
17262                 return newNumberFormulaArg(result)
17263         }
17264         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17265 }
17266
17267 // prepareOddlArgs checking and prepare arguments for the formula
17268 // functions ODDLPRICE and ODDLYIELD.
17269 func (fn *formulaFuncs) prepareOddlArgs(name string, argsList *list.List) formulaArg {
17270         dateValues := fn.prepareDataValueArgs(3, argsList)
17271         if dateValues.Type != ArgList {
17272                 return dateValues
17273         }
17274         settlement, maturity, lastInterest := dateValues.List[0], dateValues.List[1], dateValues.List[2]
17275         if lastInterest.Number >= settlement.Number {
17276                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires settlement > last_interest", name))
17277         }
17278         if settlement.Number >= maturity.Number {
17279                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires maturity > settlement", name))
17280         }
17281         rate := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
17282         if rate.Type != ArgNumber {
17283                 return rate
17284         }
17285         if rate.Number < 0 {
17286                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires rate >= 0", name))
17287         }
17288         yldOrPr := prepareOddYldOrPrArg(name, argsList.Front().Next().Next().Next().Next().Value.(formulaArg))
17289         if yldOrPr.Type != ArgNumber {
17290                 return yldOrPr
17291         }
17292         redemption := argsList.Front().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
17293         if redemption.Type != ArgNumber {
17294                 return redemption
17295         }
17296         if redemption.Number <= 0 {
17297                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires redemption > 0", name))
17298         }
17299         frequency := argsList.Front().Next().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
17300         if frequency.Type != ArgNumber {
17301                 return frequency
17302         }
17303         if !validateFrequency(frequency.Number) {
17304                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17305         }
17306         basis := newNumberFormulaArg(0)
17307         if argsList.Len() == 8 {
17308                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
17309                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17310                 }
17311         }
17312         return newListFormulaArg([]formulaArg{settlement, maturity, lastInterest, rate, yldOrPr, redemption, frequency, basis})
17313 }
17314
17315 // oddl is an implementation of the formula functions ODDLPRICE and ODDLYIELD.
17316 func (fn *formulaFuncs) oddl(name string, argsList *list.List) formulaArg {
17317         if argsList.Len() != 7 && argsList.Len() != 8 {
17318                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 7 or 8 arguments", name))
17319         }
17320         args := fn.prepareOddlArgs(name, argsList)
17321         if args.Type != ArgList {
17322                 return args
17323         }
17324         settlement, maturity, lastInterest, rate, prOrYld, redemption, frequency, basisArg := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5], args.List[6], args.List[7]
17325         if basisArg.Number < 0 || basisArg.Number > 4 {
17326                 return newErrorFormulaArg(formulaErrorNUM, "invalid basis")
17327         }
17328         settlementTime := timeFromExcelTime(settlement.Number, false)
17329         maturityTime := timeFromExcelTime(maturity.Number, false)
17330         basis := int(basisArg.Number)
17331         numMonths := 12 / frequency.Number
17332         fnArgs := list.New().Init()
17333         fnArgs.PushBack(lastInterest)
17334         fnArgs.PushBack(maturity)
17335         fnArgs.PushBack(frequency)
17336         fnArgs.PushBack(basisArg)
17337         nc := fn.COUPNUM(fnArgs)
17338         earlyCoupon := lastInterest.Number
17339         aggrFunc := func(acc []float64, index float64) []float64 {
17340                 earlyCouponTime := timeFromExcelTime(earlyCoupon, false)
17341                 lateCouponTime := changeMonth(earlyCouponTime, numMonths, false)
17342                 lateCoupon, _ := timeToExcelTime(lateCouponTime, false)
17343                 nl := coupdays(earlyCouponTime, lateCouponTime, basis)
17344                 dci := coupdays(earlyCouponTime, maturityTime, basis)
17345                 if index < nc.Number {
17346                         dci = nl
17347                 }
17348                 var a float64
17349                 if lateCoupon < settlement.Number {
17350                         a = dci
17351                 } else if earlyCoupon < settlement.Number {
17352                         a = coupdays(earlyCouponTime, settlementTime, basis)
17353                 }
17354                 startDate := earlyCoupon
17355                 if settlement.Number > earlyCoupon {
17356                         startDate = settlement.Number
17357                 }
17358                 endDate := lateCoupon
17359                 if maturity.Number < lateCoupon {
17360                         endDate = maturity.Number
17361                 }
17362                 startDateTime := timeFromExcelTime(startDate, false)
17363                 endDateTime := timeFromExcelTime(endDate, false)
17364                 dsc := coupdays(startDateTime, endDateTime, basis)
17365                 earlyCoupon = lateCoupon
17366                 dcnl := acc[0]
17367                 anl := acc[1]
17368                 dscnl := acc[2]
17369                 return []float64{dcnl + dci/nl, anl + a/nl, dscnl + dsc/nl}
17370         }
17371         ag := aggrBetween(1, math.Floor(nc.Number), []float64{0, 0, 0}, aggrFunc)
17372         dcnl, anl, dscnl := ag[0], ag[1], ag[2]
17373         x := 100.0 * rate.Number / frequency.Number
17374         term1 := dcnl*x + redemption.Number
17375         if name == "ODDLPRICE" {
17376                 term2 := dscnl*prOrYld.Number/frequency.Number + 1
17377                 term3 := anl * x
17378                 return newNumberFormulaArg(term1/term2 - term3)
17379         }
17380         term2 := anl*x + prOrYld.Number
17381         term3 := frequency.Number / dscnl
17382         return newNumberFormulaArg((term1 - term2) / term2 * term3)
17383 }
17384
17385 // ODDLPRICE function calculates the price per $100 face value of a security
17386 // with an odd (short or long) last period. The syntax of the function is:
17387 //
17388 //      ODDLPRICE(settlement,maturity,last_interest,rate,yld,redemption,frequency,[basis])
17389 func (fn *formulaFuncs) ODDLPRICE(argsList *list.List) formulaArg {
17390         return fn.oddl("ODDLPRICE", argsList)
17391 }
17392
17393 // ODDLYIELD function calculates the yield of a security with an odd (short or
17394 // long) last period. The syntax of the function is:
17395 //
17396 //      ODDLYIELD(settlement,maturity,last_interest,rate,pr,redemption,frequency,[basis])
17397 func (fn *formulaFuncs) ODDLYIELD(argsList *list.List) formulaArg {
17398         return fn.oddl("ODDLYIELD", argsList)
17399 }
17400
17401 // PDURATION function calculates the number of periods required for an
17402 // investment to reach a specified future value. The syntax of the function
17403 // is:
17404 //
17405 //      PDURATION(rate,pv,fv)
17406 func (fn *formulaFuncs) PDURATION(argsList *list.List) formulaArg {
17407         if argsList.Len() != 3 {
17408                 return newErrorFormulaArg(formulaErrorVALUE, "PDURATION requires 3 arguments")
17409         }
17410         rate := argsList.Front().Value.(formulaArg).ToNumber()
17411         if rate.Type != ArgNumber {
17412                 return rate
17413         }
17414         pv := argsList.Front().Next().Value.(formulaArg).ToNumber()
17415         if pv.Type != ArgNumber {
17416                 return pv
17417         }
17418         fv := argsList.Back().Value.(formulaArg).ToNumber()
17419         if fv.Type != ArgNumber {
17420                 return fv
17421         }
17422         if rate.Number <= 0 || pv.Number <= 0 || fv.Number <= 0 {
17423                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17424         }
17425         return newNumberFormulaArg((math.Log(fv.Number) - math.Log(pv.Number)) / math.Log(1+rate.Number))
17426 }
17427
17428 // PMT function calculates the constant periodic payment required to pay off
17429 // (or partially pay off) a loan or investment, with a constant interest
17430 // rate, over a specified period. The syntax of the function is:
17431 //
17432 //      PMT(rate,nper,pv,[fv],[type])
17433 func (fn *formulaFuncs) PMT(argsList *list.List) formulaArg {
17434         if argsList.Len() < 3 {
17435                 return newErrorFormulaArg(formulaErrorVALUE, "PMT requires at least 3 arguments")
17436         }
17437         if argsList.Len() > 5 {
17438                 return newErrorFormulaArg(formulaErrorVALUE, "PMT allows at most 5 arguments")
17439         }
17440         rate := argsList.Front().Value.(formulaArg).ToNumber()
17441         if rate.Type != ArgNumber {
17442                 return rate
17443         }
17444         nper := argsList.Front().Next().Value.(formulaArg).ToNumber()
17445         if nper.Type != ArgNumber {
17446                 return nper
17447         }
17448         pv := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
17449         if pv.Type != ArgNumber {
17450                 return pv
17451         }
17452         fv, typ := newNumberFormulaArg(0), newNumberFormulaArg(0)
17453         if argsList.Len() >= 4 {
17454                 if fv = argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber(); fv.Type != ArgNumber {
17455                         return fv
17456                 }
17457         }
17458         if argsList.Len() == 5 {
17459                 if typ = argsList.Back().Value.(formulaArg).ToNumber(); typ.Type != ArgNumber {
17460                         return typ
17461                 }
17462         }
17463         if typ.Number != 0 && typ.Number != 1 {
17464                 return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
17465         }
17466         if rate.Number != 0 {
17467                 p := (-fv.Number - pv.Number*math.Pow(1+rate.Number, nper.Number)) / (1 + rate.Number*typ.Number) / ((math.Pow(1+rate.Number, nper.Number) - 1) / rate.Number)
17468                 return newNumberFormulaArg(p)
17469         }
17470         return newNumberFormulaArg((-pv.Number - fv.Number) / nper.Number)
17471 }
17472
17473 // PPMT function calculates the payment on the principal, during a specific
17474 // period of a loan or investment that is paid in constant periodic payments,
17475 // with a constant interest rate. The syntax of the function is:
17476 //
17477 //      PPMT(rate,per,nper,pv,[fv],[type])
17478 func (fn *formulaFuncs) PPMT(argsList *list.List) formulaArg {
17479         return fn.ipmt("PPMT", argsList)
17480 }
17481
17482 // price is an implementation of the formula function PRICE.
17483 func (fn *formulaFuncs) price(settlement, maturity, rate, yld, redemption, frequency, basis formulaArg) formulaArg {
17484         if basis.Number < 0 || basis.Number > 4 {
17485                 return newErrorFormulaArg(formulaErrorNUM, "invalid basis")
17486         }
17487         argsList := list.New().Init()
17488         argsList.PushBack(settlement)
17489         argsList.PushBack(maturity)
17490         argsList.PushBack(frequency)
17491         argsList.PushBack(basis)
17492         e := fn.COUPDAYS(argsList)
17493         dsc := fn.COUPDAYSNC(argsList).Number / e.Number
17494         n := fn.COUPNUM(argsList)
17495         a := fn.COUPDAYBS(argsList)
17496         ret := 0.0
17497         if n.Number > 1 {
17498                 ret = redemption.Number / math.Pow(1+yld.Number/frequency.Number, n.Number-1+dsc)
17499                 ret -= 100 * rate.Number / frequency.Number * a.Number / e.Number
17500                 t1 := 100 * rate.Number / frequency.Number
17501                 t2 := 1 + yld.Number/frequency.Number
17502                 for k := 0.0; k < n.Number; k++ {
17503                         ret += t1 / math.Pow(t2, k+dsc)
17504                 }
17505         } else {
17506                 dsc = e.Number - a.Number
17507                 t1 := 100*(rate.Number/frequency.Number) + redemption.Number
17508                 t2 := (yld.Number/frequency.Number)*(dsc/e.Number) + 1
17509                 t3 := 100 * (rate.Number / frequency.Number) * (a.Number / e.Number)
17510                 ret = t1/t2 - t3
17511         }
17512         return newNumberFormulaArg(ret)
17513 }
17514
17515 // checkPriceYieldArgs checking and prepare arguments for the formula functions
17516 // PRICE and YIELD.
17517 func checkPriceYieldArgs(name string, rate, prYld, redemption, frequency formulaArg) formulaArg {
17518         if rate.Type != ArgNumber {
17519                 return rate
17520         }
17521         if rate.Number < 0 {
17522                 return newErrorFormulaArg(formulaErrorNUM, fmt.Sprintf("%s requires rate >= 0", name))
17523         }
17524         if prYld.Type != ArgNumber {
17525                 return prYld
17526         }
17527         if redemption.Type != ArgNumber {
17528                 return redemption
17529         }
17530         if name == "PRICE" {
17531                 if prYld.Number < 0 {
17532                         return newErrorFormulaArg(formulaErrorNUM, "PRICE requires yld >= 0")
17533                 }
17534                 if redemption.Number <= 0 {
17535                         return newErrorFormulaArg(formulaErrorNUM, "PRICE requires redemption > 0")
17536                 }
17537         }
17538         if name == "YIELD" {
17539                 if prYld.Number <= 0 {
17540                         return newErrorFormulaArg(formulaErrorNUM, "YIELD requires pr > 0")
17541                 }
17542                 if redemption.Number < 0 {
17543                         return newErrorFormulaArg(formulaErrorNUM, "YIELD requires redemption >= 0")
17544                 }
17545         }
17546         if frequency.Type != ArgNumber {
17547                 return frequency
17548         }
17549         if !validateFrequency(frequency.Number) {
17550                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17551         }
17552         return newEmptyFormulaArg()
17553 }
17554
17555 // priceYield is an implementation of the formula functions PRICE and YIELD.
17556 func (fn *formulaFuncs) priceYield(name string, argsList *list.List) formulaArg {
17557         if argsList.Len() != 6 && argsList.Len() != 7 {
17558                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 6 or 7 arguments", name))
17559         }
17560         args := fn.prepareDataValueArgs(2, argsList)
17561         if args.Type != ArgList {
17562                 return args
17563         }
17564         settlement, maturity := args.List[0], args.List[1]
17565         rate := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
17566         prYld := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
17567         redemption := argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
17568         frequency := argsList.Front().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
17569         if arg := checkPriceYieldArgs(name, rate, prYld, redemption, frequency); arg.Type != ArgEmpty {
17570                 return arg
17571         }
17572         basis := newNumberFormulaArg(0)
17573         if argsList.Len() == 7 {
17574                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
17575                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17576                 }
17577         }
17578         if name == "PRICE" {
17579                 return fn.price(settlement, maturity, rate, prYld, redemption, frequency, basis)
17580         }
17581         return fn.yield(settlement, maturity, rate, prYld, redemption, frequency, basis)
17582 }
17583
17584 // PRICE function calculates the price, per $100 face value of a security that
17585 // pays periodic interest. The syntax of the function is:
17586 //
17587 //      PRICE(settlement,maturity,rate,yld,redemption,frequency,[basis])
17588 func (fn *formulaFuncs) PRICE(argsList *list.List) formulaArg {
17589         return fn.priceYield("PRICE", argsList)
17590 }
17591
17592 // PRICEDISC function calculates the price, per $100 face value of a
17593 // discounted security. The syntax of the function is:
17594 //
17595 //      PRICEDISC(settlement,maturity,discount,redemption,[basis])
17596 func (fn *formulaFuncs) PRICEDISC(argsList *list.List) formulaArg {
17597         if argsList.Len() != 4 && argsList.Len() != 5 {
17598                 return newErrorFormulaArg(formulaErrorVALUE, "PRICEDISC requires 4 or 5 arguments")
17599         }
17600         args := fn.prepareDataValueArgs(2, argsList)
17601         if args.Type != ArgList {
17602                 return args
17603         }
17604         settlement, maturity := args.List[0], args.List[1]
17605         if maturity.Number <= settlement.Number {
17606                 return newErrorFormulaArg(formulaErrorNUM, "PRICEDISC requires maturity > settlement")
17607         }
17608         discount := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
17609         if discount.Type != ArgNumber {
17610                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
17611         }
17612         if discount.Number <= 0 {
17613                 return newErrorFormulaArg(formulaErrorNUM, "PRICEDISC requires discount > 0")
17614         }
17615         redemption := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
17616         if redemption.Type != ArgNumber {
17617                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
17618         }
17619         if redemption.Number <= 0 {
17620                 return newErrorFormulaArg(formulaErrorNUM, "PRICEDISC requires redemption > 0")
17621         }
17622         basis := newNumberFormulaArg(0)
17623         if argsList.Len() == 5 {
17624                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
17625                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17626                 }
17627         }
17628         frac := yearFrac(settlement.Number, maturity.Number, int(basis.Number))
17629         if frac.Type != ArgNumber {
17630                 return frac
17631         }
17632         return newNumberFormulaArg(redemption.Number * (1 - discount.Number*frac.Number))
17633 }
17634
17635 // PRICEMAT function calculates the price, per $100 face value of a security
17636 // that pays interest at maturity. The syntax of the function is:
17637 //
17638 //      PRICEMAT(settlement,maturity,issue,rate,yld,[basis])
17639 func (fn *formulaFuncs) PRICEMAT(argsList *list.List) formulaArg {
17640         if argsList.Len() != 5 && argsList.Len() != 6 {
17641                 return newErrorFormulaArg(formulaErrorVALUE, "PRICEMAT requires 5 or 6 arguments")
17642         }
17643         args := fn.prepareDataValueArgs(3, argsList)
17644         if args.Type != ArgList {
17645                 return args
17646         }
17647         settlement, maturity, issue := args.List[0], args.List[1], args.List[2]
17648         if settlement.Number >= maturity.Number {
17649                 return newErrorFormulaArg(formulaErrorNUM, "PRICEMAT requires maturity > settlement")
17650         }
17651         if issue.Number >= settlement.Number {
17652                 return newErrorFormulaArg(formulaErrorNUM, "PRICEMAT requires settlement > issue")
17653         }
17654         rate := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
17655         if rate.Type != ArgNumber {
17656                 return rate
17657         }
17658         if rate.Number < 0 {
17659                 return newErrorFormulaArg(formulaErrorNUM, "PRICEMAT requires rate >= 0")
17660         }
17661         yld := argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
17662         if yld.Type != ArgNumber {
17663                 return yld
17664         }
17665         if yld.Number < 0 {
17666                 return newErrorFormulaArg(formulaErrorNUM, "PRICEMAT requires yld >= 0")
17667         }
17668         basis := newNumberFormulaArg(0)
17669         if argsList.Len() == 6 {
17670                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
17671                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17672                 }
17673         }
17674         dsm := yearFrac(settlement.Number, maturity.Number, int(basis.Number))
17675         if dsm.Type != ArgNumber {
17676                 return dsm
17677         }
17678         dis := yearFrac(issue.Number, settlement.Number, int(basis.Number))
17679         dim := yearFrac(issue.Number, maturity.Number, int(basis.Number))
17680         return newNumberFormulaArg(((1+dim.Number*rate.Number)/(1+dsm.Number*yld.Number) - dis.Number*rate.Number) * 100)
17681 }
17682
17683 // PV function calculates the Present Value of an investment, based on a
17684 // series of future payments. The syntax of the function is:
17685 //
17686 //      PV(rate,nper,pmt,[fv],[type])
17687 func (fn *formulaFuncs) PV(argsList *list.List) formulaArg {
17688         if argsList.Len() < 3 {
17689                 return newErrorFormulaArg(formulaErrorVALUE, "PV requires at least 3 arguments")
17690         }
17691         if argsList.Len() > 5 {
17692                 return newErrorFormulaArg(formulaErrorVALUE, "PV allows at most 5 arguments")
17693         }
17694         rate := argsList.Front().Value.(formulaArg).ToNumber()
17695         if rate.Type != ArgNumber {
17696                 return rate
17697         }
17698         nper := argsList.Front().Next().Value.(formulaArg).ToNumber()
17699         if nper.Type != ArgNumber {
17700                 return nper
17701         }
17702         pmt := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
17703         if pmt.Type != ArgNumber {
17704                 return pmt
17705         }
17706         fv := newNumberFormulaArg(0)
17707         if argsList.Len() >= 4 {
17708                 if fv = argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber(); fv.Type != ArgNumber {
17709                         return fv
17710                 }
17711         }
17712         t := newNumberFormulaArg(0)
17713         if argsList.Len() == 5 {
17714                 if t = argsList.Back().Value.(formulaArg).ToNumber(); t.Type != ArgNumber {
17715                         return t
17716                 }
17717                 if t.Number != 0 {
17718                         t.Number = 1
17719                 }
17720         }
17721         if rate.Number == 0 {
17722                 return newNumberFormulaArg(-pmt.Number*nper.Number - fv.Number)
17723         }
17724         return newNumberFormulaArg((((1-math.Pow(1+rate.Number, nper.Number))/rate.Number)*pmt.Number*(1+rate.Number*t.Number) - fv.Number) / math.Pow(1+rate.Number, nper.Number))
17725 }
17726
17727 // rate is an implementation of the formula function RATE.
17728 func (fn *formulaFuncs) rate(nper, pmt, pv, fv, t, guess formulaArg) formulaArg {
17729         maxIter, iter, isClose, epsMax, rate := 100, 0, false, 1e-6, guess.Number
17730         for iter < maxIter && !isClose {
17731                 t1 := math.Pow(rate+1, nper.Number)
17732                 t2 := math.Pow(rate+1, nper.Number-1)
17733                 rt := rate*t.Number + 1
17734                 p0 := pmt.Number * (t1 - 1)
17735                 f1 := fv.Number + t1*pv.Number + p0*rt/rate
17736                 n1 := nper.Number * t2 * pv.Number
17737                 n2 := p0 * rt / math.Pow(rate, 2)
17738                 f2 := math.Nextafter(n1, n1) - math.Nextafter(n2, n2)
17739                 f3 := (nper.Number*pmt.Number*t2*rt + p0*t.Number) / rate
17740                 delta := f1 / (f2 + f3)
17741                 if math.Abs(delta) < epsMax {
17742                         isClose = true
17743                 }
17744                 iter++
17745                 rate -= delta
17746         }
17747         return newNumberFormulaArg(rate)
17748 }
17749
17750 // RATE function calculates the interest rate required to pay off a specified
17751 // amount of a loan, or to reach a target amount on an investment, over a
17752 // given period. The syntax of the function is:
17753 //
17754 //      RATE(nper,pmt,pv,[fv],[type],[guess])
17755 func (fn *formulaFuncs) RATE(argsList *list.List) formulaArg {
17756         if argsList.Len() < 3 {
17757                 return newErrorFormulaArg(formulaErrorVALUE, "RATE requires at least 3 arguments")
17758         }
17759         if argsList.Len() > 6 {
17760                 return newErrorFormulaArg(formulaErrorVALUE, "RATE allows at most 6 arguments")
17761         }
17762         nper := argsList.Front().Value.(formulaArg).ToNumber()
17763         if nper.Type != ArgNumber {
17764                 return nper
17765         }
17766         pmt := argsList.Front().Next().Value.(formulaArg).ToNumber()
17767         if pmt.Type != ArgNumber {
17768                 return pmt
17769         }
17770         pv := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
17771         if pv.Type != ArgNumber {
17772                 return pv
17773         }
17774         fv := newNumberFormulaArg(0)
17775         if argsList.Len() >= 4 {
17776                 if fv = argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber(); fv.Type != ArgNumber {
17777                         return fv
17778                 }
17779         }
17780         t := newNumberFormulaArg(0)
17781         if argsList.Len() >= 5 {
17782                 if t = argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber(); t.Type != ArgNumber {
17783                         return t
17784                 }
17785                 if t.Number != 0 {
17786                         t.Number = 1
17787                 }
17788         }
17789         guess := newNumberFormulaArg(0.1)
17790         if argsList.Len() == 6 {
17791                 if guess = argsList.Back().Value.(formulaArg).ToNumber(); guess.Type != ArgNumber {
17792                         return guess
17793                 }
17794         }
17795         return fn.rate(nper, pmt, pv, fv, t, guess)
17796 }
17797
17798 // RECEIVED function calculates the amount received at maturity for a fully
17799 // invested security. The syntax of the function is:
17800 //
17801 //      RECEIVED(settlement,maturity,investment,discount,[basis])
17802 func (fn *formulaFuncs) RECEIVED(argsList *list.List) formulaArg {
17803         if argsList.Len() < 4 {
17804                 return newErrorFormulaArg(formulaErrorVALUE, "RECEIVED requires at least 4 arguments")
17805         }
17806         if argsList.Len() > 5 {
17807                 return newErrorFormulaArg(formulaErrorVALUE, "RECEIVED allows at most 5 arguments")
17808         }
17809         args := fn.prepareDataValueArgs(2, argsList)
17810         if args.Type != ArgList {
17811                 return args
17812         }
17813         settlement, maturity := args.List[0], args.List[1]
17814         investment := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
17815         if investment.Type != ArgNumber {
17816                 return investment
17817         }
17818         discount := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
17819         if discount.Type != ArgNumber {
17820                 return discount
17821         }
17822         if discount.Number <= 0 {
17823                 return newErrorFormulaArg(formulaErrorNUM, "RECEIVED requires discount > 0")
17824         }
17825         basis := newNumberFormulaArg(0)
17826         if argsList.Len() == 5 {
17827                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
17828                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17829                 }
17830         }
17831         frac := yearFrac(settlement.Number, maturity.Number, int(basis.Number))
17832         if frac.Type != ArgNumber {
17833                 return frac
17834         }
17835         return newNumberFormulaArg(investment.Number / (1 - discount.Number*frac.Number))
17836 }
17837
17838 // RRI function calculates the equivalent interest rate for an investment with
17839 // specified present value, future value and duration. The syntax of the
17840 // function is:
17841 //
17842 //      RRI(nper,pv,fv)
17843 func (fn *formulaFuncs) RRI(argsList *list.List) formulaArg {
17844         if argsList.Len() != 3 {
17845                 return newErrorFormulaArg(formulaErrorVALUE, "RRI requires 3 arguments")
17846         }
17847         nper := argsList.Front().Value.(formulaArg).ToNumber()
17848         pv := argsList.Front().Next().Value.(formulaArg).ToNumber()
17849         fv := argsList.Back().Value.(formulaArg).ToNumber()
17850         if nper.Type != ArgNumber || pv.Type != ArgNumber || fv.Type != ArgNumber {
17851                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17852         }
17853         if nper.Number <= 0 {
17854                 return newErrorFormulaArg(formulaErrorNUM, "RRI requires nper argument to be > 0")
17855         }
17856         if pv.Number <= 0 {
17857                 return newErrorFormulaArg(formulaErrorNUM, "RRI requires pv argument to be > 0")
17858         }
17859         if fv.Number < 0 {
17860                 return newErrorFormulaArg(formulaErrorNUM, "RRI requires fv argument to be >= 0")
17861         }
17862         return newNumberFormulaArg(math.Pow(fv.Number/pv.Number, 1/nper.Number) - 1)
17863 }
17864
17865 // SLN function calculates the straight line depreciation of an asset for one
17866 // period. The syntax of the function is:
17867 //
17868 //      SLN(cost,salvage,life)
17869 func (fn *formulaFuncs) SLN(argsList *list.List) formulaArg {
17870         if argsList.Len() != 3 {
17871                 return newErrorFormulaArg(formulaErrorVALUE, "SLN requires 3 arguments")
17872         }
17873         cost := argsList.Front().Value.(formulaArg).ToNumber()
17874         salvage := argsList.Front().Next().Value.(formulaArg).ToNumber()
17875         life := argsList.Back().Value.(formulaArg).ToNumber()
17876         if cost.Type != ArgNumber || salvage.Type != ArgNumber || life.Type != ArgNumber {
17877                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17878         }
17879         if life.Number == 0 {
17880                 return newErrorFormulaArg(formulaErrorNUM, "SLN requires life argument to be > 0")
17881         }
17882         return newNumberFormulaArg((cost.Number - salvage.Number) / life.Number)
17883 }
17884
17885 // SYD function calculates the sum-of-years' digits depreciation for a
17886 // specified period in the lifetime of an asset. The syntax of the function
17887 // is:
17888 //
17889 //      SYD(cost,salvage,life,per)
17890 func (fn *formulaFuncs) SYD(argsList *list.List) formulaArg {
17891         if argsList.Len() != 4 {
17892                 return newErrorFormulaArg(formulaErrorVALUE, "SYD requires 4 arguments")
17893         }
17894         cost := argsList.Front().Value.(formulaArg).ToNumber()
17895         salvage := argsList.Front().Next().Value.(formulaArg).ToNumber()
17896         life := argsList.Back().Prev().Value.(formulaArg).ToNumber()
17897         per := argsList.Back().Value.(formulaArg).ToNumber()
17898         if cost.Type != ArgNumber || salvage.Type != ArgNumber || life.Type != ArgNumber || per.Type != ArgNumber {
17899                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17900         }
17901         if life.Number <= 0 {
17902                 return newErrorFormulaArg(formulaErrorNUM, "SYD requires life argument to be > 0")
17903         }
17904         if per.Number <= 0 {
17905                 return newErrorFormulaArg(formulaErrorNUM, "SYD requires per argument to be > 0")
17906         }
17907         if per.Number > life.Number {
17908                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17909         }
17910         return newNumberFormulaArg(((cost.Number - salvage.Number) * (life.Number - per.Number + 1) * 2) / (life.Number * (life.Number + 1)))
17911 }
17912
17913 // TBILLEQ function calculates the bond-equivalent yield for a Treasury Bill.
17914 // The syntax of the function is:
17915 //
17916 //      TBILLEQ(settlement,maturity,discount)
17917 func (fn *formulaFuncs) TBILLEQ(argsList *list.List) formulaArg {
17918         if argsList.Len() != 3 {
17919                 return newErrorFormulaArg(formulaErrorVALUE, "TBILLEQ requires 3 arguments")
17920         }
17921         args := fn.prepareDataValueArgs(2, argsList)
17922         if args.Type != ArgList {
17923                 return args
17924         }
17925         settlement, maturity := args.List[0], args.List[1]
17926         dsm := maturity.Number - settlement.Number
17927         if dsm > 365 || maturity.Number <= settlement.Number {
17928                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17929         }
17930         discount := argsList.Back().Value.(formulaArg).ToNumber()
17931         if discount.Type != ArgNumber {
17932                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
17933         }
17934         if discount.Number <= 0 {
17935                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17936         }
17937         return newNumberFormulaArg((365 * discount.Number) / (360 - discount.Number*dsm))
17938 }
17939
17940 // TBILLPRICE function returns the price, per $100 face value, of a Treasury
17941 // Bill. The syntax of the function is:
17942 //
17943 //      TBILLPRICE(settlement,maturity,discount)
17944 func (fn *formulaFuncs) TBILLPRICE(argsList *list.List) formulaArg {
17945         if argsList.Len() != 3 {
17946                 return newErrorFormulaArg(formulaErrorVALUE, "TBILLPRICE requires 3 arguments")
17947         }
17948         args := fn.prepareDataValueArgs(2, argsList)
17949         if args.Type != ArgList {
17950                 return args
17951         }
17952         settlement, maturity := args.List[0], args.List[1]
17953         dsm := maturity.Number - settlement.Number
17954         if dsm > 365 || maturity.Number <= settlement.Number {
17955                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17956         }
17957         discount := argsList.Back().Value.(formulaArg).ToNumber()
17958         if discount.Type != ArgNumber {
17959                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
17960         }
17961         if discount.Number <= 0 {
17962                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17963         }
17964         return newNumberFormulaArg(100 * (1 - discount.Number*dsm/360))
17965 }
17966
17967 // TBILLYIELD function calculates the yield of a Treasury Bill. The syntax of
17968 // the function is:
17969 //
17970 //      TBILLYIELD(settlement,maturity,pr)
17971 func (fn *formulaFuncs) TBILLYIELD(argsList *list.List) formulaArg {
17972         if argsList.Len() != 3 {
17973                 return newErrorFormulaArg(formulaErrorVALUE, "TBILLYIELD requires 3 arguments")
17974         }
17975         args := fn.prepareDataValueArgs(2, argsList)
17976         if args.Type != ArgList {
17977                 return args
17978         }
17979         settlement, maturity := args.List[0], args.List[1]
17980         dsm := maturity.Number - settlement.Number
17981         if dsm > 365 || maturity.Number <= settlement.Number {
17982                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17983         }
17984         pr := argsList.Back().Value.(formulaArg).ToNumber()
17985         if pr.Type != ArgNumber {
17986                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
17987         }
17988         if pr.Number <= 0 {
17989                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
17990         }
17991         return newNumberFormulaArg(((100 - pr.Number) / pr.Number) * (360 / dsm))
17992 }
17993
17994 // prepareVdbArgs checking and prepare arguments for the formula function
17995 // VDB.
17996 func (fn *formulaFuncs) prepareVdbArgs(argsList *list.List) formulaArg {
17997         cost := argsList.Front().Value.(formulaArg).ToNumber()
17998         if cost.Type != ArgNumber {
17999                 return cost
18000         }
18001         if cost.Number < 0 {
18002                 return newErrorFormulaArg(formulaErrorNUM, "VDB requires cost >= 0")
18003         }
18004         salvage := argsList.Front().Next().Value.(formulaArg).ToNumber()
18005         if salvage.Type != ArgNumber {
18006                 return salvage
18007         }
18008         if salvage.Number < 0 {
18009                 return newErrorFormulaArg(formulaErrorNUM, "VDB requires salvage >= 0")
18010         }
18011         life := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
18012         if life.Type != ArgNumber {
18013                 return life
18014         }
18015         if life.Number <= 0 {
18016                 return newErrorFormulaArg(formulaErrorNUM, "VDB requires life > 0")
18017         }
18018         startPeriod := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
18019         if startPeriod.Type != ArgNumber {
18020                 return startPeriod
18021         }
18022         if startPeriod.Number < 0 {
18023                 return newErrorFormulaArg(formulaErrorNUM, "VDB requires start_period > 0")
18024         }
18025         endPeriod := argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
18026         if endPeriod.Type != ArgNumber {
18027                 return endPeriod
18028         }
18029         if startPeriod.Number > endPeriod.Number {
18030                 return newErrorFormulaArg(formulaErrorNUM, "VDB requires start_period <= end_period")
18031         }
18032         if endPeriod.Number > life.Number {
18033                 return newErrorFormulaArg(formulaErrorNUM, "VDB requires end_period <= life")
18034         }
18035         factor := newNumberFormulaArg(2)
18036         if argsList.Len() > 5 {
18037                 if factor = argsList.Front().Next().Next().Next().Next().Next().Value.(formulaArg).ToNumber(); factor.Type != ArgNumber {
18038                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18039                 }
18040                 if factor.Number < 0 {
18041                         return newErrorFormulaArg(formulaErrorVALUE, "VDB requires factor >= 0")
18042                 }
18043         }
18044         return newListFormulaArg([]formulaArg{cost, salvage, life, startPeriod, endPeriod, factor})
18045 }
18046
18047 // vdb is a part of implementation of the formula function VDB.
18048 func (fn *formulaFuncs) vdb(cost, salvage, life, life1, period, factor formulaArg) formulaArg {
18049         var ddb, vdb, sln, term float64
18050         endInt, cs, nowSln := math.Ceil(period.Number), cost.Number-salvage.Number, false
18051         ddbArgs := list.New()
18052         for i := 1.0; i <= endInt; i++ {
18053                 if !nowSln {
18054                         ddbArgs.Init()
18055                         ddbArgs.PushBack(cost)
18056                         ddbArgs.PushBack(salvage)
18057                         ddbArgs.PushBack(life)
18058                         ddbArgs.PushBack(newNumberFormulaArg(i))
18059                         ddbArgs.PushBack(factor)
18060                         ddb = fn.DDB(ddbArgs).Number
18061                         sln = cs / (life1.Number - i + 1)
18062                         if sln > ddb {
18063                                 term = sln
18064                                 nowSln = true
18065                         } else {
18066                                 term = ddb
18067                                 cs -= ddb
18068                         }
18069                 } else {
18070                         term = sln
18071                 }
18072                 if i == endInt {
18073                         term *= period.Number + 1 - endInt
18074                 }
18075                 vdb += term
18076         }
18077         return newNumberFormulaArg(vdb)
18078 }
18079
18080 // VDB function calculates the depreciation of an asset, using the Double
18081 // Declining Balance Method, or another specified depreciation rate, for a
18082 // specified period (including partial periods). The syntax of the function
18083 // is:
18084 //
18085 //      VDB(cost,salvage,life,start_period,end_period,[factor],[no_switch])
18086 func (fn *formulaFuncs) VDB(argsList *list.List) formulaArg {
18087         if argsList.Len() < 5 || argsList.Len() > 7 {
18088                 return newErrorFormulaArg(formulaErrorVALUE, "VDB requires 5 or 7 arguments")
18089         }
18090         args := fn.prepareVdbArgs(argsList)
18091         if args.Type != ArgList {
18092                 return args
18093         }
18094         cost, salvage, life, startPeriod, endPeriod, factor := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5]
18095         noSwitch := newBoolFormulaArg(false)
18096         if argsList.Len() > 6 {
18097                 if noSwitch = argsList.Back().Value.(formulaArg).ToBool(); noSwitch.Type != ArgNumber {
18098                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18099                 }
18100         }
18101         startInt, endInt, vdb, ddbArgs := math.Floor(startPeriod.Number), math.Ceil(endPeriod.Number), newNumberFormulaArg(0), list.New()
18102         if noSwitch.Number == 1 {
18103                 for i := startInt + 1; i <= endInt; i++ {
18104                         ddbArgs.Init()
18105                         ddbArgs.PushBack(cost)
18106                         ddbArgs.PushBack(salvage)
18107                         ddbArgs.PushBack(life)
18108                         ddbArgs.PushBack(newNumberFormulaArg(i))
18109                         ddbArgs.PushBack(factor)
18110                         term := fn.DDB(ddbArgs)
18111                         if i == startInt+1 {
18112                                 term.Number *= math.Min(endPeriod.Number, startInt+1) - startPeriod.Number
18113                         } else if i == endInt {
18114                                 term.Number *= endPeriod.Number + 1 - endInt
18115                         }
18116                         vdb.Number += term.Number
18117                 }
18118                 return vdb
18119         }
18120         life1, part := life, 0.0
18121         if startPeriod.Number != math.Floor(startPeriod.Number) && factor.Number > 1.0 && startPeriod.Number >= life.Number/2.0 {
18122                 part = startPeriod.Number - life.Number/2.0
18123                 startPeriod.Number = life.Number / 2.0
18124                 endPeriod.Number -= part
18125         }
18126         cost.Number -= fn.vdb(cost, salvage, life, life1, startPeriod, factor).Number
18127         return fn.vdb(cost, salvage, life, newNumberFormulaArg(life.Number-startPeriod.Number), newNumberFormulaArg(endPeriod.Number-startPeriod.Number), factor)
18128 }
18129
18130 // prepareXArgs prepare arguments for the formula function XIRR and XNPV.
18131 func (fn *formulaFuncs) prepareXArgs(values, dates formulaArg) (valuesArg, datesArg []float64, err formulaArg) {
18132         for _, arg := range values.ToList() {
18133                 if numArg := arg.ToNumber(); numArg.Type == ArgNumber {
18134                         valuesArg = append(valuesArg, numArg.Number)
18135                         continue
18136                 }
18137                 err = newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18138                 return
18139         }
18140         if len(valuesArg) < 2 {
18141                 err = newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18142                 return
18143         }
18144         args, date := list.New(), 0.0
18145         for _, arg := range dates.ToList() {
18146                 args.Init()
18147                 args.PushBack(arg)
18148                 dateValue := fn.DATEVALUE(args)
18149                 if dateValue.Type != ArgNumber {
18150                         err = newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18151                         return
18152                 }
18153                 if dateValue.Number < date {
18154                         err = newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
18155                         return
18156                 }
18157                 datesArg = append(datesArg, dateValue.Number)
18158                 date = dateValue.Number
18159         }
18160         if len(valuesArg) != len(datesArg) {
18161                 err = newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18162                 return
18163         }
18164         err = newEmptyFormulaArg()
18165         return
18166 }
18167
18168 // xirr is an implementation of the formula function XIRR.
18169 func (fn *formulaFuncs) xirr(values, dates []float64, guess float64) formulaArg {
18170         positive, negative := false, false
18171         for i := 0; i < len(values); i++ {
18172                 if values[i] > 0 {
18173                         positive = true
18174                 }
18175                 if values[i] < 0 {
18176                         negative = true
18177                 }
18178         }
18179         if !positive || !negative {
18180                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18181         }
18182         result, epsMax, count, maxIterate, err := guess, 1e-10, 0, 50, false
18183         for {
18184                 resultValue := xirrPart1(values, dates, result)
18185                 newRate := result - resultValue/xirrPart2(values, dates, result)
18186                 epsRate := math.Abs(newRate - result)
18187                 result = newRate
18188                 count++
18189                 if epsRate <= epsMax || math.Abs(resultValue) <= epsMax {
18190                         break
18191                 }
18192                 if count > maxIterate {
18193                         err = true
18194                         break
18195                 }
18196         }
18197         if err || math.IsNaN(result) || math.IsInf(result, 0) {
18198                 return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18199         }
18200         return newNumberFormulaArg(result)
18201 }
18202
18203 // xirrPart1 is a part of implementation of the formula function XIRR.
18204 func xirrPart1(values, dates []float64, rate float64) float64 {
18205         r := rate + 1
18206         result := values[0]
18207         vlen := len(values)
18208         firstDate := dates[0]
18209         for i := 1; i < vlen; i++ {
18210                 result += values[i] / math.Pow(r, (dates[i]-firstDate)/365)
18211         }
18212         return result
18213 }
18214
18215 // xirrPart2 is a part of implementation of the formula function XIRR.
18216 func xirrPart2(values, dates []float64, rate float64) float64 {
18217         r := rate + 1
18218         result := 0.0
18219         vlen := len(values)
18220         firstDate := dates[0]
18221         for i := 1; i < vlen; i++ {
18222                 frac := (dates[i] - firstDate) / 365
18223                 result -= frac * values[i] / math.Pow(r, frac+1)
18224         }
18225         return result
18226 }
18227
18228 // XIRR function returns the Internal Rate of Return for a supplied series of
18229 // cash flows (i.e. a set of values, which includes an initial investment
18230 // value and a series of net income values) occurring at a series of supplied
18231 // dates. The syntax of the function is:
18232 //
18233 //      XIRR(values,dates,[guess])
18234 func (fn *formulaFuncs) XIRR(argsList *list.List) formulaArg {
18235         if argsList.Len() != 2 && argsList.Len() != 3 {
18236                 return newErrorFormulaArg(formulaErrorVALUE, "XIRR requires 2 or 3 arguments")
18237         }
18238         values, dates, err := fn.prepareXArgs(argsList.Front().Value.(formulaArg), argsList.Front().Next().Value.(formulaArg))
18239         if err.Type != ArgEmpty {
18240                 return err
18241         }
18242         guess := newNumberFormulaArg(0)
18243         if argsList.Len() == 3 {
18244                 if guess = argsList.Back().Value.(formulaArg).ToNumber(); guess.Type != ArgNumber {
18245                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18246                 }
18247                 if guess.Number <= -1 {
18248                         return newErrorFormulaArg(formulaErrorVALUE, "XIRR requires guess > -1")
18249                 }
18250         }
18251         return fn.xirr(values, dates, guess.Number)
18252 }
18253
18254 // XNPV function calculates the Net Present Value for a schedule of cash flows
18255 // that is not necessarily periodic. The syntax of the function is:
18256 //
18257 //      XNPV(rate,values,dates)
18258 func (fn *formulaFuncs) XNPV(argsList *list.List) formulaArg {
18259         if argsList.Len() != 3 {
18260                 return newErrorFormulaArg(formulaErrorVALUE, "XNPV requires 3 arguments")
18261         }
18262         rate := argsList.Front().Value.(formulaArg).ToNumber()
18263         if rate.Type != ArgNumber {
18264                 return rate
18265         }
18266         if rate.Number <= 0 {
18267                 return newErrorFormulaArg(formulaErrorVALUE, "XNPV requires rate > 0")
18268         }
18269         values, dates, err := fn.prepareXArgs(argsList.Front().Next().Value.(formulaArg), argsList.Back().Value.(formulaArg))
18270         if err.Type != ArgEmpty {
18271                 return err
18272         }
18273         date1, xnpv := dates[0], 0.0
18274         for idx, value := range values {
18275                 xnpv += value / math.Pow(1+rate.Number, (dates[idx]-date1)/365)
18276         }
18277         return newNumberFormulaArg(xnpv)
18278 }
18279
18280 // yield is an implementation of the formula function YIELD.
18281 func (fn *formulaFuncs) yield(settlement, maturity, rate, pr, redemption, frequency, basis formulaArg) formulaArg {
18282         priceN, yield1, yield2 := newNumberFormulaArg(0), newNumberFormulaArg(0), newNumberFormulaArg(1)
18283         price1 := fn.price(settlement, maturity, rate, yield1, redemption, frequency, basis)
18284         if price1.Type != ArgNumber {
18285                 return price1
18286         }
18287         price2 := fn.price(settlement, maturity, rate, yield2, redemption, frequency, basis)
18288         yieldN := newNumberFormulaArg((yield2.Number - yield1.Number) * 0.5)
18289         for iter := 0; iter < 100 && priceN.Number != pr.Number; iter++ {
18290                 priceN = fn.price(settlement, maturity, rate, yieldN, redemption, frequency, basis)
18291                 if pr.Number == price1.Number {
18292                         return yield1
18293                 } else if pr.Number == price2.Number {
18294                         return yield2
18295                 } else if pr.Number == priceN.Number {
18296                         return yieldN
18297                 } else if pr.Number < price2.Number {
18298                         yield2.Number *= 2.0
18299                         price2 = fn.price(settlement, maturity, rate, yield2, redemption, frequency, basis)
18300                         yieldN.Number = (yield2.Number - yield1.Number) * 0.5
18301                 } else {
18302                         if pr.Number < priceN.Number {
18303                                 yield1 = yieldN
18304                                 price1 = priceN
18305                         } else {
18306                                 yield2 = yieldN
18307                                 price2 = priceN
18308                         }
18309                         f1 := (yield2.Number - yield1.Number) * ((pr.Number - price2.Number) / (price1.Number - price2.Number))
18310                         yieldN.Number = yield2.Number - math.Nextafter(f1, f1)
18311                 }
18312         }
18313         return yieldN
18314 }
18315
18316 // YIELD function calculates the Yield of a security that pays periodic
18317 // interest. The syntax of the function is:
18318 //
18319 //      YIELD(settlement,maturity,rate,pr,redemption,frequency,[basis])
18320 func (fn *formulaFuncs) YIELD(argsList *list.List) formulaArg {
18321         return fn.priceYield("YIELD", argsList)
18322 }
18323
18324 // YIELDDISC function calculates the annual yield of a discounted security.
18325 // The syntax of the function is:
18326 //
18327 //      YIELDDISC(settlement,maturity,pr,redemption,[basis])
18328 func (fn *formulaFuncs) YIELDDISC(argsList *list.List) formulaArg {
18329         if argsList.Len() != 4 && argsList.Len() != 5 {
18330                 return newErrorFormulaArg(formulaErrorVALUE, "YIELDDISC requires 4 or 5 arguments")
18331         }
18332         args := fn.prepareDataValueArgs(2, argsList)
18333         if args.Type != ArgList {
18334                 return args
18335         }
18336         settlement, maturity := args.List[0], args.List[1]
18337         pr := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
18338         if pr.Type != ArgNumber {
18339                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
18340         }
18341         if pr.Number <= 0 {
18342                 return newErrorFormulaArg(formulaErrorNUM, "YIELDDISC requires pr > 0")
18343         }
18344         redemption := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
18345         if redemption.Type != ArgNumber {
18346                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
18347         }
18348         if redemption.Number <= 0 {
18349                 return newErrorFormulaArg(formulaErrorNUM, "YIELDDISC requires redemption > 0")
18350         }
18351         basis := newNumberFormulaArg(0)
18352         if argsList.Len() == 5 {
18353                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
18354                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18355                 }
18356         }
18357         frac := yearFrac(settlement.Number, maturity.Number, int(basis.Number))
18358         if frac.Type != ArgNumber {
18359                 return frac
18360         }
18361         return newNumberFormulaArg((redemption.Number/pr.Number - 1) / frac.Number)
18362 }
18363
18364 // YIELDMAT function calculates the annual yield of a security that pays
18365 // interest at maturity. The syntax of the function is:
18366 //
18367 //      YIELDMAT(settlement,maturity,issue,rate,pr,[basis])
18368 func (fn *formulaFuncs) YIELDMAT(argsList *list.List) formulaArg {
18369         if argsList.Len() != 5 && argsList.Len() != 6 {
18370                 return newErrorFormulaArg(formulaErrorVALUE, "YIELDMAT requires 5 or 6 arguments")
18371         }
18372         args := fn.prepareDataValueArgs(2, argsList)
18373         if args.Type != ArgList {
18374                 return args
18375         }
18376         settlement, maturity := args.List[0], args.List[1]
18377         arg := list.New().Init()
18378         issue := argsList.Front().Next().Next().Value.(formulaArg).ToNumber()
18379         if issue.Type != ArgNumber {
18380                 arg.PushBack(argsList.Front().Next().Next().Value.(formulaArg))
18381                 issue = fn.DATEVALUE(arg)
18382                 if issue.Type != ArgNumber {
18383                         return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
18384                 }
18385         }
18386         if issue.Number >= settlement.Number {
18387                 return newErrorFormulaArg(formulaErrorNUM, "YIELDMAT requires settlement > issue")
18388         }
18389         rate := argsList.Front().Next().Next().Next().Value.(formulaArg).ToNumber()
18390         if rate.Type != ArgNumber {
18391                 return rate
18392         }
18393         if rate.Number < 0 {
18394                 return newErrorFormulaArg(formulaErrorNUM, "YIELDMAT requires rate >= 0")
18395         }
18396         pr := argsList.Front().Next().Next().Next().Next().Value.(formulaArg).ToNumber()
18397         if pr.Type != ArgNumber {
18398                 return pr
18399         }
18400         if pr.Number <= 0 {
18401                 return newErrorFormulaArg(formulaErrorNUM, "YIELDMAT requires pr > 0")
18402         }
18403         basis := newNumberFormulaArg(0)
18404         if argsList.Len() == 6 {
18405                 if basis = argsList.Back().Value.(formulaArg).ToNumber(); basis.Type != ArgNumber {
18406                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18407                 }
18408         }
18409         dim := yearFrac(issue.Number, maturity.Number, int(basis.Number))
18410         if dim.Type != ArgNumber {
18411                 return dim
18412         }
18413         dis := yearFrac(issue.Number, settlement.Number, int(basis.Number))
18414         dsm := yearFrac(settlement.Number, maturity.Number, int(basis.Number))
18415         f1 := dim.Number * rate.Number
18416         result := 1 + math.Nextafter(f1, f1)
18417         result /= pr.Number/100 + dis.Number*rate.Number
18418         result--
18419         result /= dsm.Number
18420         return newNumberFormulaArg(result)
18421 }
18422
18423 // Database Functions
18424
18425 // calcDatabase defines the structure for formula database.
18426 type calcDatabase struct {
18427         col, row int
18428         indexMap map[int]int
18429         database [][]formulaArg
18430         criteria [][]formulaArg
18431 }
18432
18433 // newCalcDatabase function returns formula database by given data range of
18434 // cells containing the database, field and criteria range.
18435 func newCalcDatabase(database, field, criteria formulaArg) *calcDatabase {
18436         db := calcDatabase{
18437                 indexMap: make(map[int]int),
18438                 database: database.Matrix,
18439                 criteria: criteria.Matrix,
18440         }
18441         exp := len(database.Matrix) < 2 || len(database.Matrix[0]) < 1 ||
18442                 len(criteria.Matrix) < 2 || len(criteria.Matrix[0]) < 1
18443         if field.Type != ArgEmpty {
18444                 if db.col = db.columnIndex(database.Matrix, field); exp || db.col < 0 || len(db.database[0]) <= db.col {
18445                         return nil
18446                 }
18447                 return &db
18448         }
18449         if db.col = -1; exp {
18450                 return nil
18451         }
18452         return &db
18453 }
18454
18455 // columnIndex return index by specifies column field within the database for
18456 // which user want to return the count of non-blank cells.
18457 func (db *calcDatabase) columnIndex(database [][]formulaArg, field formulaArg) int {
18458         num := field.ToNumber()
18459         if num.Type != ArgNumber && len(database) > 0 {
18460                 for i := 0; i < len(database[0]); i++ {
18461                         if title := database[0][i]; strings.EqualFold(title.Value(), field.Value()) {
18462                                 return i
18463                         }
18464                 }
18465                 return -1
18466         }
18467         return int(num.Number - 1)
18468 }
18469
18470 // criteriaEval evaluate formula criteria expression.
18471 func (db *calcDatabase) criteriaEval() bool {
18472         var (
18473                 columns, rows = len(db.criteria[0]), len(db.criteria)
18474                 criteria      = db.criteria
18475                 k             int
18476                 matched       bool
18477         )
18478         if len(db.indexMap) == 0 {
18479                 fields := criteria[0]
18480                 for j := 0; j < columns; j++ {
18481                         if k = db.columnIndex(db.database, fields[j]); k < 0 {
18482                                 return false
18483                         }
18484                         db.indexMap[j] = k
18485                 }
18486         }
18487         for i := 1; !matched && i < rows; i++ {
18488                 matched = true
18489                 for j := 0; matched && j < columns; j++ {
18490                         criteriaExp := db.criteria[i][j]
18491                         if criteriaExp.Value() == "" {
18492                                 continue
18493                         }
18494                         criteria := formulaCriteriaParser(criteriaExp)
18495                         cell := db.database[db.row][db.indexMap[j]]
18496                         matched, _ = formulaCriteriaEval(cell, criteria)
18497                 }
18498         }
18499         return matched
18500 }
18501
18502 // value returns the current cell value.
18503 func (db *calcDatabase) value() formulaArg {
18504         if db.col == -1 {
18505                 return db.database[db.row][len(db.database[db.row])-1]
18506         }
18507         return db.database[db.row][db.col]
18508 }
18509
18510 // next will return true if find the matched cell in the database.
18511 func (db *calcDatabase) next() bool {
18512         matched, rows := false, len(db.database)
18513         for !matched && db.row < rows {
18514                 if db.row++; db.row < rows {
18515                         matched = db.criteriaEval()
18516                 }
18517         }
18518         return matched
18519 }
18520
18521 // database is an implementation of the formula functions DAVERAGE, DMAX and DMIN.
18522 func (fn *formulaFuncs) database(name string, argsList *list.List) formulaArg {
18523         if argsList.Len() != 3 {
18524                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 arguments", name))
18525         }
18526         database := argsList.Front().Value.(formulaArg)
18527         field := argsList.Front().Next().Value.(formulaArg)
18528         criteria := argsList.Back().Value.(formulaArg)
18529         db := newCalcDatabase(database, field, criteria)
18530         if db == nil {
18531                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
18532         }
18533         args := list.New()
18534         for db.next() {
18535                 args.PushBack(db.value())
18536         }
18537         switch name {
18538         case "DMAX":
18539                 return fn.MAX(args)
18540         case "DMIN":
18541                 return fn.MIN(args)
18542         case "DPRODUCT":
18543                 return fn.PRODUCT(args)
18544         case "DSTDEV":
18545                 return fn.STDEV(args)
18546         case "DSTDEVP":
18547                 return fn.STDEVP(args)
18548         case "DSUM":
18549                 return fn.SUM(args)
18550         case "DVAR":
18551                 return fn.VAR(args)
18552         case "DVARP":
18553                 return fn.VARP(args)
18554         default:
18555                 return fn.AVERAGE(args)
18556         }
18557 }
18558
18559 // DAVERAGE function calculates the average (statistical mean) of values in a
18560 // field (column) in a database for selected records, that satisfy
18561 // user-specified criteria. The syntax of the function is:
18562 //
18563 //      DAVERAGE(database,field,criteria)
18564 func (fn *formulaFuncs) DAVERAGE(argsList *list.List) formulaArg {
18565         return fn.database("DAVERAGE", argsList)
18566 }
18567
18568 // dcount is an implementation of the formula functions DCOUNT and DCOUNTA.
18569 func (fn *formulaFuncs) dcount(name string, argsList *list.List) formulaArg {
18570         if argsList.Len() < 2 {
18571                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 2 arguments", name))
18572         }
18573         if argsList.Len() > 3 {
18574                 return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s allows at most 3 arguments", name))
18575         }
18576         field := newEmptyFormulaArg()
18577         criteria := argsList.Back().Value.(formulaArg)
18578         if argsList.Len() > 2 {
18579                 field = argsList.Front().Next().Value.(formulaArg)
18580         }
18581         database := argsList.Front().Value.(formulaArg)
18582         db := newCalcDatabase(database, field, criteria)
18583         if db == nil {
18584                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
18585         }
18586         args := list.New()
18587         for db.next() {
18588                 args.PushBack(db.value())
18589         }
18590         if name == "DCOUNT" {
18591                 return fn.COUNT(args)
18592         }
18593         return fn.COUNTA(args)
18594 }
18595
18596 // DCOUNT function returns the number of cells containing numeric values, in a
18597 // field (column) of a database for selected records only. The records to be
18598 // included in the count are those that satisfy a set of one or more
18599 // user-specified criteria. The syntax of the function is:
18600 //
18601 //      DCOUNT(database,[field],criteria)
18602 func (fn *formulaFuncs) DCOUNT(argsList *list.List) formulaArg {
18603         return fn.dcount("DCOUNT", argsList)
18604 }
18605
18606 // DCOUNTA function returns the number of non-blank cells, in a field
18607 // (column) of a database for selected records only. The records to be
18608 // included in the count are those that satisfy a set of one or more
18609 // user-specified criteria. The syntax of the function is:
18610 //
18611 //      DCOUNTA(database,[field],criteria)
18612 func (fn *formulaFuncs) DCOUNTA(argsList *list.List) formulaArg {
18613         return fn.dcount("DCOUNTA", argsList)
18614 }
18615
18616 // DGET function returns a single value from a column of a database. The record
18617 // is selected via a set of one or more user-specified criteria. The syntax of
18618 // the function is:
18619 //
18620 //      DGET(database,field,criteria)
18621 func (fn *formulaFuncs) DGET(argsList *list.List) formulaArg {
18622         if argsList.Len() != 3 {
18623                 return newErrorFormulaArg(formulaErrorVALUE, "DGET requires 3 arguments")
18624         }
18625         database := argsList.Front().Value.(formulaArg)
18626         field := argsList.Front().Next().Value.(formulaArg)
18627         criteria := argsList.Back().Value.(formulaArg)
18628         db := newCalcDatabase(database, field, criteria)
18629         if db == nil {
18630                 return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
18631         }
18632         value := newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
18633         if db.next() {
18634                 if value = db.value(); db.next() {
18635                         return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
18636                 }
18637         }
18638         return value
18639 }
18640
18641 // DMAX function finds the maximum value in a field (column) in a database for
18642 // selected records only. The records to be included in the calculation are
18643 // defined by a set of one or more user-specified criteria. The syntax of the
18644 // function is:
18645 //
18646 //      DMAX(database,field,criteria)
18647 func (fn *formulaFuncs) DMAX(argsList *list.List) formulaArg {
18648         return fn.database("DMAX", argsList)
18649 }
18650
18651 // DMIN function finds the minimum value in a field (column) in a database for
18652 // selected records only. The records to be included in the calculation are
18653 // defined by a set of one or more user-specified criteria. The syntax of the
18654 // function is:
18655 //
18656 //      DMIN(database,field,criteria)
18657 func (fn *formulaFuncs) DMIN(argsList *list.List) formulaArg {
18658         return fn.database("DMIN", argsList)
18659 }
18660
18661 // DPRODUCT function calculates the product of a field (column) in a database
18662 // for selected records, that satisfy user-specified criteria. The syntax of
18663 // the function is:
18664 //
18665 //      DPRODUCT(database,field,criteria)
18666 func (fn *formulaFuncs) DPRODUCT(argsList *list.List) formulaArg {
18667         return fn.database("DPRODUCT", argsList)
18668 }
18669
18670 // DSTDEV function calculates the sample standard deviation of a field
18671 // (column) in a database for selected records only. The records to be
18672 // included in the calculation are defined by a set of one or more
18673 // user-specified criteria. The syntax of the function is:
18674 //
18675 //      DSTDEV(database,field,criteria)
18676 func (fn *formulaFuncs) DSTDEV(argsList *list.List) formulaArg {
18677         return fn.database("DSTDEV", argsList)
18678 }
18679
18680 // DSTDEVP function calculates the standard deviation of a field (column) in a
18681 // database for selected records only. The records to be included in the
18682 // calculation are defined by a set of one or more user-specified criteria.
18683 // The syntax of the function is:
18684 //
18685 //      DSTDEVP(database,field,criteria)
18686 func (fn *formulaFuncs) DSTDEVP(argsList *list.List) formulaArg {
18687         return fn.database("DSTDEVP", argsList)
18688 }
18689
18690 // DSUM function calculates the sum of a field (column) in a database for
18691 // selected records, that satisfy user-specified criteria. The syntax of the
18692 // function is:
18693 //
18694 //      DSUM(database,field,criteria)
18695 func (fn *formulaFuncs) DSUM(argsList *list.List) formulaArg {
18696         return fn.database("DSUM", argsList)
18697 }
18698
18699 // DVAR function calculates the sample variance of a field (column) in a
18700 // database for selected records only. The records to be included in the
18701 // calculation are defined by a set of one or more user-specified criteria.
18702 // The syntax of the function is:
18703 //
18704 //      DVAR(database,field,criteria)
18705 func (fn *formulaFuncs) DVAR(argsList *list.List) formulaArg {
18706         return fn.database("DVAR", argsList)
18707 }
18708
18709 // DVARP function calculates the variance (for an entire population), of the
18710 // values in a field (column) in a database for selected records only. The
18711 // records to be included in the calculation are defined by a set of one or
18712 // more user-specified criteria. The syntax of the function is:
18713 //
18714 //      DVARP(database,field,criteria)
18715 func (fn *formulaFuncs) DVARP(argsList *list.List) formulaArg {
18716         return fn.database("DVARP", argsList)
18717 }
18718
18719 // DISPIMG function calculates the Kingsoft WPS Office embedded image ID. The
18720 // syntax of the function is:
18721 //
18722 //      DISPIMG(picture_name,display_mode)
18723 func (fn *formulaFuncs) DISPIMG(argsList *list.List) formulaArg {
18724         if argsList.Len() != 2 {
18725                 return newErrorFormulaArg(formulaErrorVALUE, "DISPIMG requires 2 numeric arguments")
18726         }
18727         return argsList.Front().Value.(formulaArg)
18728 }