7
7
// spreadsheet documents generated by Microsoft Excel™ 2007 and later. Supports
8
8
// complex components by high compatibility, and provided streaming API for
9
9
// generating or reading data from a worksheet with huge amounts of data. This
10
- // library needs Go version 1.10 or later.
10
+ // library needs Go version 1.15 or later.
11
11
12
12
package excelize
13
13
@@ -17,6 +17,7 @@ import (
17
17
"errors"
18
18
"fmt"
19
19
"math"
20
+ "math/cmplx"
20
21
"math/rand"
21
22
"net/url"
22
23
"reflect"
@@ -292,6 +293,15 @@ var tokenPriority = map[string]int{
292
293
// HLOOKUP
293
294
// IF
294
295
// IFERROR
296
+ // IMABS
297
+ // IMCOS
298
+ // IMCOSH
299
+ // IMCOT
300
+ // IMCSC
301
+ // IMCSCH
302
+ // IMEXP
303
+ // IMLN
304
+ // IMLOG10
295
305
// INT
296
306
// ISBLANK
297
307
// ISERR
@@ -1475,8 +1485,38 @@ func (fn *formulaFuncs) COMPLEX(argsList *list.List) formulaArg {
1475
1485
return newErrorFormulaArg (formulaErrorVALUE , formulaErrorVALUE )
1476
1486
}
1477
1487
}
1478
- r := strings .NewReplacer ("(" , "" , ")" , "" , "0+" , "" , "+0i" , "" , "0+0i" , "0" , "i" , suffix )
1479
- return newStringFormulaArg (r .Replace (fmt .Sprint (complex (real .Number , i .Number ))))
1488
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (complex (real .Number , i .Number )), suffix ))
1489
+ }
1490
+
1491
+ // cmplx2str replace complex number string characters.
1492
+ func cmplx2str (c , suffix string ) string {
1493
+ if c == "(0+0i)" || c == "(0-0i)" {
1494
+ return "0"
1495
+ }
1496
+ c = strings .TrimPrefix (c , "(" )
1497
+ c = strings .TrimPrefix (c , "+0+" )
1498
+ c = strings .TrimPrefix (c , "-0+" )
1499
+ c = strings .TrimSuffix (c , ")" )
1500
+ c = strings .TrimPrefix (c , "0+" )
1501
+ if strings .HasPrefix (c , "0-" ) {
1502
+ c = "-" + strings .TrimPrefix (c , "0-" )
1503
+ }
1504
+ c = strings .TrimPrefix (c , "0+" )
1505
+ c = strings .TrimSuffix (c , "+0i" )
1506
+ c = strings .TrimSuffix (c , "-0i" )
1507
+ c = strings .NewReplacer ("+1i" , "i" , "-1i" , "-i" ).Replace (c )
1508
+ c = strings .Replace (c , "i" , suffix , - 1 )
1509
+ return c
1510
+ }
1511
+
1512
+ // str2cmplx convert complex number string characters.
1513
+ func str2cmplx (c string ) string {
1514
+ c = strings .Replace (c , "j" , "i" , - 1 )
1515
+ if c == "i" {
1516
+ c = "1i"
1517
+ }
1518
+ c = strings .NewReplacer ("+i" , "+1i" , "-i" , "-1i" ).Replace (c )
1519
+ return c
1480
1520
}
1481
1521
1482
1522
// DEC2BIN function converts a decimal number into a Binary (Base 2) number.
@@ -1651,6 +1691,166 @@ func (fn *formulaFuncs) hex2dec(number string) formulaArg {
1651
1691
return newNumberFormulaArg (decimal )
1652
1692
}
1653
1693
1694
+ // IMABS function returns the absolute value (the modulus) of a complex
1695
+ // number. The syntax of the function is:
1696
+ //
1697
+ // IMABS(inumber)
1698
+ //
1699
+ func (fn * formulaFuncs ) IMABS (argsList * list.List ) formulaArg {
1700
+ if argsList .Len () != 1 {
1701
+ return newErrorFormulaArg (formulaErrorVALUE , "IMABS requires 1 argument" )
1702
+ }
1703
+ inumber , err := strconv .ParseComplex (strings .Replace (argsList .Front ().Value .(formulaArg ).Value (), "j" , "i" , - 1 ), 128 )
1704
+ if err != nil {
1705
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1706
+ }
1707
+ return newNumberFormulaArg (cmplx .Abs (inumber ))
1708
+ }
1709
+
1710
+ // IMCOS function returns the cosine of a supplied complex number. The syntax
1711
+ // of the function is:
1712
+ //
1713
+ // IMCOS(inumber)
1714
+ //
1715
+ func (fn * formulaFuncs ) IMCOS (argsList * list.List ) formulaArg {
1716
+ if argsList .Len () != 1 {
1717
+ return newErrorFormulaArg (formulaErrorVALUE , "IMCOS requires 1 argument" )
1718
+ }
1719
+ inumber , err := strconv .ParseComplex (strings .Replace (argsList .Front ().Value .(formulaArg ).Value (), "j" , "i" , - 1 ), 128 )
1720
+ if err != nil {
1721
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1722
+ }
1723
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (cmplx .Cos (inumber )), "i" ))
1724
+ }
1725
+
1726
+ // IMCOSH function returns the hyperbolic cosine of a supplied complex number. The syntax
1727
+ // of the function is:
1728
+ //
1729
+ // IMCOSH(inumber)
1730
+ //
1731
+ func (fn * formulaFuncs ) IMCOSH (argsList * list.List ) formulaArg {
1732
+ if argsList .Len () != 1 {
1733
+ return newErrorFormulaArg (formulaErrorVALUE , "IMCOSH requires 1 argument" )
1734
+ }
1735
+ inumber , err := strconv .ParseComplex (str2cmplx (argsList .Front ().Value .(formulaArg ).Value ()), 128 )
1736
+ if err != nil {
1737
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1738
+ }
1739
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (cmplx .Cosh (inumber )), "i" ))
1740
+ }
1741
+
1742
+ // IMCOT function returns the cotangent of a supplied complex number. The syntax
1743
+ // of the function is:
1744
+ //
1745
+ // IMCOT(inumber)
1746
+ //
1747
+ func (fn * formulaFuncs ) IMCOT (argsList * list.List ) formulaArg {
1748
+ if argsList .Len () != 1 {
1749
+ return newErrorFormulaArg (formulaErrorVALUE , "IMCOT requires 1 argument" )
1750
+ }
1751
+ inumber , err := strconv .ParseComplex (str2cmplx (argsList .Front ().Value .(formulaArg ).Value ()), 128 )
1752
+ if err != nil {
1753
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1754
+ }
1755
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (cmplx .Cot (inumber )), "i" ))
1756
+ }
1757
+
1758
+ // IMCSC function returns the cosecant of a supplied complex number. The syntax
1759
+ // of the function is:
1760
+ //
1761
+ // IMCSC(inumber)
1762
+ //
1763
+ func (fn * formulaFuncs ) IMCSC (argsList * list.List ) formulaArg {
1764
+ if argsList .Len () != 1 {
1765
+ return newErrorFormulaArg (formulaErrorVALUE , "IMCSC requires 1 argument" )
1766
+ }
1767
+ inumber , err := strconv .ParseComplex (str2cmplx (argsList .Front ().Value .(formulaArg ).Value ()), 128 )
1768
+ if err != nil {
1769
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1770
+ }
1771
+ num := 1 / cmplx .Sin (inumber )
1772
+ if cmplx .IsInf (num ) {
1773
+ return newErrorFormulaArg (formulaErrorNUM , formulaErrorNUM )
1774
+ }
1775
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (num ), "i" ))
1776
+ }
1777
+
1778
+ // IMCSCH function returns the hyperbolic cosecant of a supplied complex
1779
+ // number. The syntax of the function is:
1780
+ //
1781
+ // IMCSCH(inumber)
1782
+ //
1783
+ func (fn * formulaFuncs ) IMCSCH (argsList * list.List ) formulaArg {
1784
+ if argsList .Len () != 1 {
1785
+ return newErrorFormulaArg (formulaErrorVALUE , "IMCSCH requires 1 argument" )
1786
+ }
1787
+ inumber , err := strconv .ParseComplex (str2cmplx (argsList .Front ().Value .(formulaArg ).Value ()), 128 )
1788
+ if err != nil {
1789
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1790
+ }
1791
+ num := 1 / cmplx .Sinh (inumber )
1792
+ if cmplx .IsInf (num ) {
1793
+ return newErrorFormulaArg (formulaErrorNUM , formulaErrorNUM )
1794
+ }
1795
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (num ), "i" ))
1796
+ }
1797
+
1798
+ // IMEXP function returns the exponential of a supplied complex number. The
1799
+ // syntax of the function is:
1800
+ //
1801
+ // IMEXP(inumber)
1802
+ //
1803
+ func (fn * formulaFuncs ) IMEXP (argsList * list.List ) formulaArg {
1804
+ if argsList .Len () != 1 {
1805
+ return newErrorFormulaArg (formulaErrorVALUE , "IMEXP requires 1 argument" )
1806
+ }
1807
+ inumber , err := strconv .ParseComplex (str2cmplx (argsList .Front ().Value .(formulaArg ).Value ()), 128 )
1808
+ if err != nil {
1809
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1810
+ }
1811
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (cmplx .Exp (inumber )), "i" ))
1812
+ }
1813
+
1814
+ // IMLN function returns the natural logarithm of a supplied complex number.
1815
+ // The syntax of the function is:
1816
+ //
1817
+ // IMLN(inumber)
1818
+ //
1819
+ func (fn * formulaFuncs ) IMLN (argsList * list.List ) formulaArg {
1820
+ if argsList .Len () != 1 {
1821
+ return newErrorFormulaArg (formulaErrorVALUE , "IMLN requires 1 argument" )
1822
+ }
1823
+ inumber , err := strconv .ParseComplex (str2cmplx (argsList .Front ().Value .(formulaArg ).Value ()), 128 )
1824
+ if err != nil {
1825
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1826
+ }
1827
+ num := cmplx .Log (inumber )
1828
+ if cmplx .IsInf (num ) {
1829
+ return newErrorFormulaArg (formulaErrorNUM , formulaErrorNUM )
1830
+ }
1831
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (num ), "i" ))
1832
+ }
1833
+
1834
+ // IMLOG10 function returns the common (base 10) logarithm of a supplied
1835
+ // complex number. The syntax of the function is:
1836
+ //
1837
+ // IMLOG10(inumber)
1838
+ //
1839
+ func (fn * formulaFuncs ) IMLOG10 (argsList * list.List ) formulaArg {
1840
+ if argsList .Len () != 1 {
1841
+ return newErrorFormulaArg (formulaErrorVALUE , "IMLOG10 requires 1 argument" )
1842
+ }
1843
+ inumber , err := strconv .ParseComplex (str2cmplx (argsList .Front ().Value .(formulaArg ).Value ()), 128 )
1844
+ if err != nil {
1845
+ return newErrorFormulaArg (formulaErrorNUM , err .Error ())
1846
+ }
1847
+ num := cmplx .Log10 (inumber )
1848
+ if cmplx .IsInf (num ) {
1849
+ return newErrorFormulaArg (formulaErrorNUM , formulaErrorNUM )
1850
+ }
1851
+ return newStringFormulaArg (cmplx2str (fmt .Sprint (num ), "i" ))
1852
+ }
1853
+
1654
1854
// OCT2BIN function converts an Octal (Base 8) number into a Binary (Base 2)
1655
1855
// number. The syntax of the function is:
1656
1856
//
0 commit comments