summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--calc.go80
-rw-r--r--calc_test.go34
-rw-r--r--lib.go3
3 files changed, 115 insertions, 2 deletions
diff --git a/calc.go b/calc.go
index 4d2bdcc..e3e7c4d 100644
--- a/calc.go
+++ b/calc.go
@@ -294,11 +294,15 @@ var tokenPriority = map[string]int{
// IF
// IFERROR
// IMABS
+// IMAGINARY
+// IMARGUMENT
+// IMCONJUGATE
// IMCOS
// IMCOSH
// IMCOT
// IMCSC
// IMCSCH
+// IMDIV
// IMEXP
// IMLN
// IMLOG10
@@ -1712,13 +1716,61 @@ 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)
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
if err != nil {
return newErrorFormulaArg(formulaErrorNUM, err.Error())
}
return newNumberFormulaArg(cmplx.Abs(inumber))
}
+// IMAGINARY function returns the imaginary coefficient of a supplied complex
+// number. The syntax of the function is:
+//
+// IMAGINARY(inumber)
+//
+func (fn *formulaFuncs) IMAGINARY(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMAGINARY requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ return newNumberFormulaArg(imag(inumber))
+}
+
+// IMARGUMENT function returns the phase (also called the argument) of a
+// supplied complex number. The syntax of the function is:
+//
+// IMARGUMENT(inumber)
+//
+func (fn *formulaFuncs) IMARGUMENT(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMARGUMENT requires 1 argument")
+ }
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ return newNumberFormulaArg(cmplx.Phase(inumber))
+}
+
+// IMCONJUGATE function returns the complex conjugate of a supplied complex
+// number. The syntax of the function is:
+//
+// IMCONJUGATE(inumber)
+//
+func (fn *formulaFuncs) IMCONJUGATE(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMCONJUGATE 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.Conj(inumber)), "i"))
+}
+
// IMCOS function returns the cosine of a supplied complex number. The syntax
// of the function is:
//
@@ -1728,7 +1780,7 @@ 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)
+ inumber, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
if err != nil {
return newErrorFormulaArg(formulaErrorNUM, err.Error())
}
@@ -1807,6 +1859,30 @@ func (fn *formulaFuncs) IMCSCH(argsList *list.List) formulaArg {
return newStringFormulaArg(cmplx2str(fmt.Sprint(num), "i"))
}
+// IMDIV function calculates the quotient of two complex numbers (i.e. divides
+// one complex number by another). The syntax of the function is:
+//
+// IMDIV(inumber1,inumber2)
+//
+func (fn *formulaFuncs) IMDIV(argsList *list.List) formulaArg {
+ if argsList.Len() != 2 {
+ return newErrorFormulaArg(formulaErrorVALUE, "IMDIV requires 2 arguments")
+ }
+ inumber1, err := strconv.ParseComplex(str2cmplx(argsList.Front().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ inumber2, err := strconv.ParseComplex(str2cmplx(argsList.Back().Value.(formulaArg).Value()), 128)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorNUM, err.Error())
+ }
+ num := inumber1 / inumber2
+ 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:
//
diff --git a/calc_test.go b/calc_test.go
index afbf880..26f8875 100644
--- a/calc_test.go
+++ b/calc_test.go
@@ -134,6 +134,22 @@ func TestCalcCellValue(t *testing.T) {
"=IMABS(\"2j\")": "2",
"=IMABS(\"-1+2i\")": "2.23606797749979",
"=IMABS(COMPLEX(-1,2,\"j\"))": "2.23606797749979",
+ // IMAGINARY
+ "=IMAGINARY(\"5+2i\")": "2",
+ "=IMAGINARY(\"2-i\")": "-1",
+ "=IMAGINARY(6)": "0",
+ "=IMAGINARY(\"3i\")": "3",
+ "=IMAGINARY(\"4+i\")": "1",
+ // IMARGUMENT
+ "=IMARGUMENT(\"5+2i\")": "0.380506377112365",
+ "=IMARGUMENT(\"2-i\")": "-0.463647609000806",
+ "=IMARGUMENT(6)": "0",
+ // IMCONJUGATE
+ "=IMCONJUGATE(\"5+2i\")": "5-2i",
+ "=IMCONJUGATE(\"2-i\")": "2+i",
+ "=IMCONJUGATE(6)": "6",
+ "=IMCONJUGATE(\"3i\")": "-3i",
+ "=IMCONJUGATE(\"4+i\")": "4-i",
// IMCOS
"=IMCOS(0)": "1",
"=IMCOS(0.5)": "0.877582561890373",
@@ -152,6 +168,10 @@ func TestCalcCellValue(t *testing.T) {
"=IMCSC(\"j\")": "-0.8509181282393216i",
// IMCSCH
"=IMCSCH(COMPLEX(1,-1))": "0.30393100162842646+0.6215180171704284i",
+ // IMDIV
+ "=IMDIV(\"5+2i\",\"1+i\")": "3.5-1.5i",
+ "=IMDIV(\"2+2i\",\"2+i\")": "1.2+0.4i",
+ "=IMDIV(COMPLEX(5,2),COMPLEX(0,1))": "2-5i",
// IMEXP
"=IMEXP(0)": "1",
"=IMEXP(0.5)": "1.648721270700128",
@@ -1241,6 +1261,15 @@ func TestCalcCellValue(t *testing.T) {
// IMABS
"=IMABS()": "IMABS requires 1 argument",
"=IMABS(\"\")": "strconv.ParseComplex: parsing \"\": invalid syntax",
+ // IMAGINARY
+ "=IMAGINARY()": "IMAGINARY requires 1 argument",
+ "=IMAGINARY(\"\")": "strconv.ParseComplex: parsing \"\": invalid syntax",
+ // IMARGUMENT
+ "=IMARGUMENT()": "IMARGUMENT requires 1 argument",
+ "=IMARGUMENT(\"\")": "strconv.ParseComplex: parsing \"\": invalid syntax",
+ // IMCONJUGATE
+ "=IMCONJUGATE()": "IMCONJUGATE requires 1 argument",
+ "=IMCONJUGATE(\"\")": "strconv.ParseComplex: parsing \"\": invalid syntax",
// IMCOS
"=IMCOS()": "IMCOS requires 1 argument",
"=IMCOS(\"\")": "strconv.ParseComplex: parsing \"\": invalid syntax",
@@ -1258,6 +1287,11 @@ func TestCalcCellValue(t *testing.T) {
"=IMCSCH()": "IMCSCH requires 1 argument",
"=IMCSCH(\"\")": "strconv.ParseComplex: parsing \"\": invalid syntax",
"=IMCSCH(0)": "#NUM!",
+ // IMDIV
+ "=IMDIV()": "IMDIV requires 2 arguments",
+ "=IMDIV(0,\"\")": "strconv.ParseComplex: parsing \"\": invalid syntax",
+ "=IMDIV(\"\",0)": "strconv.ParseComplex: parsing \"\": invalid syntax",
+ "=IMDIV(1,0)": "#NUM!",
// IMEXP
"=IMEXP()": "IMEXP requires 1 argument",
"=IMEXP(\"\")": "strconv.ParseComplex: parsing \"\": invalid syntax",
diff --git a/lib.go b/lib.go
index 0c1938a..26d402a 100644
--- a/lib.go
+++ b/lib.go
@@ -52,6 +52,9 @@ func (f *File) readXML(name string) []byte {
if content, ok := f.XLSX[name]; ok {
return content
}
+ if content, ok := f.streams[name]; ok {
+ return content.rawData.buf.Bytes()
+ }
return []byte{}
}