summaryrefslogtreecommitdiff
path: root/calc.go
diff options
context:
space:
mode:
Diffstat (limited to 'calc.go')
-rw-r--r--calc.go206
1 files changed, 203 insertions, 3 deletions
diff --git a/calc.go b/calc.go
index ae22c02..9cb67a1 100644
--- a/calc.go
+++ b/calc.go
@@ -7,7 +7,7 @@
// spreadsheet documents generated by Microsoft Excelâ„¢ 2007 and later. Supports
// complex components by high compatibility, and provided streaming API for
// generating or reading data from a worksheet with huge amounts of data. This
-// library needs Go version 1.10 or later.
+// library needs Go version 1.15 or later.
package excelize
@@ -17,6 +17,7 @@ import (
"errors"
"fmt"
"math"
+ "math/cmplx"
"math/rand"
"net/url"
"reflect"
@@ -292,6 +293,15 @@ var tokenPriority = map[string]int{
// HLOOKUP
// IF
// IFERROR
+// IMABS
+// IMCOS
+// IMCOSH
+// IMCOT
+// IMCSC
+// IMCSCH
+// IMEXP
+// IMLN
+// IMLOG10
// INT
// ISBLANK
// ISERR
@@ -1475,8 +1485,38 @@ func (fn *formulaFuncs) COMPLEX(argsList *list.List) formulaArg {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
}
- r := strings.NewReplacer("(", "", ")", "", "0+", "", "+0i", "", "0+0i", "0", "i", suffix)
- return newStringFormulaArg(r.Replace(fmt.Sprint(complex(real.Number, i.Number))))
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(complex(real.Number, i.Number)), suffix))
+}
+
+// cmplx2str replace complex number string characters.
+func cmplx2str(c, suffix string) string {
+ if c == "(0+0i)" || c == "(0-0i)" {
+ return "0"
+ }
+ c = strings.TrimPrefix(c, "(")
+ c = strings.TrimPrefix(c, "+0+")
+ c = strings.TrimPrefix(c, "-0+")
+ c = strings.TrimSuffix(c, ")")
+ c = strings.TrimPrefix(c, "0+")
+ if strings.HasPrefix(c, "0-") {
+ c = "-" + strings.TrimPrefix(c, "0-")
+ }
+ c = strings.TrimPrefix(c, "0+")
+ c = strings.TrimSuffix(c, "+0i")
+ c = strings.TrimSuffix(c, "-0i")
+ c = strings.NewReplacer("+1i", "i", "-1i", "-i").Replace(c)
+ c = strings.Replace(c, "i", suffix, -1)
+ return c
+}
+
+// str2cmplx convert complex number string characters.
+func str2cmplx(c string) string {
+ c = strings.Replace(c, "j", "i", -1)
+ if c == "i" {
+ c = "1i"
+ }
+ c = strings.NewReplacer("+i", "+1i", "-i", "-1i").Replace(c)
+ return c
}
// DEC2BIN function converts a decimal number into a Binary (Base 2) number.
@@ -1651,6 +1691,166 @@ func (fn *formulaFuncs) hex2dec(number string) formulaArg {
return newNumberFormulaArg(decimal)
}
+// IMABS function returns the absolute value (the modulus) of a complex
+// number. The syntax of the function is:
+//
+// IMABS(inumber)
+//
+func (fn *formulaFuncs) IMABS(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMABS requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(strings.Replace(argsList.Front().Value.(formulaArg).Value(), "j", "i", -1), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ return newNumberFormulaArg(cmplx.Abs(inumber))
+}
+
+// IMCOS function returns the cosine of a supplied complex number. The syntax
+// of the function is:
+//
+// IMCOS(inumber)
+//
+func (fn *formulaFuncs) IMCOS(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMCOS requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(strings.Replace(argsList.Front().Value.(formulaArg).Value(), "j", "i", -1), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(cmplx.Cos(inumber)), "i"))
+}
+
+// IMCOSH function returns the hyperbolic cosine of a supplied complex number. The syntax
+// of the function is:
+//
+// IMCOSH(inumber)
+//
+func (fn *formulaFuncs) IMCOSH(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMCOSH requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(cmplx.Cosh(inumber)), "i"))
+}
+
+// IMCOT function returns the cotangent of a supplied complex number. The syntax
+// of the function is:
+//
+// IMCOT(inumber)
+//
+func (fn *formulaFuncs) IMCOT(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMCOT requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(cmplx.Cot(inumber)), "i"))
+}
+
+// IMCSC function returns the cosecant of a supplied complex number. The syntax
+// of the function is:
+//
+// IMCSC(inumber)
+//
+func (fn *formulaFuncs) IMCSC(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMCSC requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ num := 1 / cmplx.Sin(inumber)
+ if cmplx.IsInf(num) {
+ return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
+ }
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(num), "i"))
+}
+
+// IMCSCH function returns the hyperbolic cosecant of a supplied complex
+// number. The syntax of the function is:
+//
+// IMCSCH(inumber)
+//
+func (fn *formulaFuncs) IMCSCH(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMCSCH requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ num := 1 / cmplx.Sinh(inumber)
+ if cmplx.IsInf(num) {
+ return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
+ }
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(num), "i"))
+}
+
+// IMEXP function returns the exponential of a supplied complex number. The
+// syntax of the function is:
+//
+// IMEXP(inumber)
+//
+func (fn *formulaFuncs) IMEXP(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMEXP requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(cmplx.Exp(inumber)), "i"))
+}
+
+// IMLN function returns the natural logarithm of a supplied complex number.
+// The syntax of the function is:
+//
+// IMLN(inumber)
+//
+func (fn *formulaFuncs) IMLN(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMLN requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ num := cmplx.Log(inumber)
+ if cmplx.IsInf(num) {
+ return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
+ }
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(num), "i"))
+}
+
+// IMLOG10 function returns the common (base 10) logarithm of a supplied
+// complex number. The syntax of the function is:
+//
+// IMLOG10(inumber)
+//
+func (fn *formulaFuncs) IMLOG10(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMLOG10 requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ num := cmplx.Log10(inumber)
+ if cmplx.IsInf(num) {
+ return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
+ }
+ return newStringFormulaArg(cmplx2str(fmt.Sprint(num), "i"))
+}
+
// OCT2BIN function converts an Octal (Base 8) number into a Binary (Base 2)
// number. The syntax of the function is:
//