@ -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.1 0 or later.
// library needs Go version 1.1 5 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:
//