calc.go 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. // Copyright 2016 - 2020 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
  6. // and read from XLSX / XLSM / XLTM files. Supports reading and writing
  7. // spreadsheet documents generated by Microsoft Exce™ 2007 and later. Supports
  8. // complex components by high compatibility, and provided streaming API for
  9. // generating or reading data from a worksheet with huge amounts of data. This
  10. // library needs Go version 1.10 or later.
  11. package excelize
  12. import (
  13. "container/list"
  14. "errors"
  15. "fmt"
  16. "math"
  17. "reflect"
  18. "strconv"
  19. "strings"
  20. "github.com/xuri/efp"
  21. )
  22. // Excel formula errors
  23. const (
  24. formulaErrorDIV = "#DIV/0!"
  25. formulaErrorNAME = "#NAME?"
  26. formulaErrorNA = "#N/A"
  27. formulaErrorNUM = "#NUM!"
  28. formulaErrorVALUE = "#VALUE!"
  29. formulaErrorREF = "#REF!"
  30. formulaErrorNULL = "#NULL"
  31. formulaErrorSPILL = "#SPILL!"
  32. formulaErrorCALC = "#CALC!"
  33. formulaErrorGETTINGDATA = "#GETTING_DATA"
  34. )
  35. // cellRef defines the structure of a cell reference
  36. type cellRef struct {
  37. Col int
  38. Row int
  39. Sheet string
  40. }
  41. // cellRef defines the structure of a cell range
  42. type cellRange struct {
  43. From cellRef
  44. To cellRef
  45. }
  46. type formulaFuncs struct{}
  47. // CalcCellValue provides a function to get calculated cell value. This
  48. // feature is currently in beta. Array formula, table formula and some other
  49. // formulas are not supported currently.
  50. func (f *File) CalcCellValue(sheet, cell string) (result string, err error) {
  51. var (
  52. formula string
  53. token efp.Token
  54. )
  55. if formula, err = f.GetCellFormula(sheet, cell); err != nil {
  56. return
  57. }
  58. ps := efp.ExcelParser()
  59. tokens := ps.Parse(formula)
  60. if tokens == nil {
  61. return
  62. }
  63. if token, err = f.evalInfixExp(sheet, tokens); err != nil {
  64. return
  65. }
  66. result = token.TValue
  67. return
  68. }
  69. // getPriority calculate arithmetic operator priority.
  70. func getPriority(token efp.Token) (pri int) {
  71. var priority = map[string]int{
  72. "*": 2,
  73. "/": 2,
  74. "+": 1,
  75. "-": 1,
  76. }
  77. pri, _ = priority[token.TValue]
  78. if token.TValue == "-" && token.TType == efp.TokenTypeOperatorPrefix {
  79. pri = 3
  80. }
  81. if token.TSubType == efp.TokenSubTypeStart && token.TType == efp.TokenTypeSubexpression { // (
  82. pri = 0
  83. }
  84. return
  85. }
  86. // evalInfixExp evaluate syntax analysis by given infix expression after
  87. // lexical analysis. Evaluate an infix expression containing formulas by
  88. // stacks:
  89. //
  90. // opd - Operand
  91. // opt - Operator
  92. // opf - Operation formula
  93. // opfd - Operand of the operation formula
  94. // opft - Operator of the operation formula
  95. //
  96. // Evaluate arguments of the operation formula by list:
  97. //
  98. // args - Arguments of the operation formula
  99. //
  100. // TODO: handle subtypes: Nothing, Text, Logical, Error, Concatenation, Intersection, Union
  101. //
  102. func (f *File) evalInfixExp(sheet string, tokens []efp.Token) (efp.Token, error) {
  103. var err error
  104. opdStack, optStack, opfStack, opfdStack, opftStack := NewStack(), NewStack(), NewStack(), NewStack(), NewStack()
  105. argsList := list.New()
  106. for i := 0; i < len(tokens); i++ {
  107. token := tokens[i]
  108. // out of function stack
  109. if opfStack.Len() == 0 {
  110. if err = f.parseToken(sheet, token, opdStack, optStack); err != nil {
  111. return efp.Token{}, err
  112. }
  113. }
  114. // function start
  115. if token.TType == efp.TokenTypeFunction && token.TSubType == efp.TokenSubTypeStart {
  116. opfStack.Push(token)
  117. continue
  118. }
  119. // in function stack, walk 2 token at once
  120. if opfStack.Len() > 0 {
  121. var nextToken efp.Token
  122. if i+1 < len(tokens) {
  123. nextToken = tokens[i+1]
  124. }
  125. // current token is args or range, skip next token, order required: parse reference first
  126. if token.TSubType == efp.TokenSubTypeRange {
  127. if !opftStack.Empty() {
  128. // parse reference: must reference at here
  129. result, err := f.parseReference(sheet, token.TValue)
  130. if err != nil {
  131. return efp.Token{TValue: formulaErrorNAME}, err
  132. }
  133. if len(result) != 1 {
  134. return efp.Token{}, errors.New(formulaErrorVALUE)
  135. }
  136. opfdStack.Push(efp.Token{
  137. TType: efp.TokenTypeOperand,
  138. TSubType: efp.TokenSubTypeNumber,
  139. TValue: result[0],
  140. })
  141. continue
  142. }
  143. if nextToken.TType == efp.TokenTypeArgument || nextToken.TType == efp.TokenTypeFunction {
  144. // parse reference: reference or range at here
  145. result, err := f.parseReference(sheet, token.TValue)
  146. if err != nil {
  147. return efp.Token{TValue: formulaErrorNAME}, err
  148. }
  149. for _, val := range result {
  150. argsList.PushBack(efp.Token{
  151. TType: efp.TokenTypeOperand,
  152. TSubType: efp.TokenSubTypeNumber,
  153. TValue: val,
  154. })
  155. }
  156. if len(result) == 0 {
  157. return efp.Token{}, errors.New(formulaErrorVALUE)
  158. }
  159. continue
  160. }
  161. }
  162. // check current token is opft
  163. if err = f.parseToken(sheet, token, opfdStack, opftStack); err != nil {
  164. return efp.Token{}, err
  165. }
  166. // current token is arg
  167. if token.TType == efp.TokenTypeArgument {
  168. for !opftStack.Empty() {
  169. // calculate trigger
  170. topOpt := opftStack.Peek().(efp.Token)
  171. if err := calculate(opfdStack, topOpt); err != nil {
  172. return efp.Token{}, err
  173. }
  174. opftStack.Pop()
  175. }
  176. if !opfdStack.Empty() {
  177. argsList.PushBack(opfdStack.Pop())
  178. }
  179. continue
  180. }
  181. // current token is logical
  182. if token.TType == efp.OperatorsInfix && token.TSubType == efp.TokenSubTypeLogical {
  183. }
  184. // current token is text
  185. if token.TType == efp.TokenTypeOperand && token.TSubType == efp.TokenSubTypeText {
  186. argsList.PushBack(token)
  187. }
  188. // current token is function stop
  189. if token.TType == efp.TokenTypeFunction && token.TSubType == efp.TokenSubTypeStop {
  190. for !opftStack.Empty() {
  191. // calculate trigger
  192. topOpt := opftStack.Peek().(efp.Token)
  193. if err := calculate(opfdStack, topOpt); err != nil {
  194. return efp.Token{}, err
  195. }
  196. opftStack.Pop()
  197. }
  198. // push opfd to args
  199. if opfdStack.Len() > 0 {
  200. argsList.PushBack(opfdStack.Pop())
  201. }
  202. // call formula function to evaluate
  203. result, err := callFuncByName(&formulaFuncs{}, strings.ReplaceAll(opfStack.Peek().(efp.Token).TValue, "_xlfn.", ""), []reflect.Value{reflect.ValueOf(argsList)})
  204. if err != nil {
  205. return efp.Token{}, err
  206. }
  207. argsList.Init()
  208. opfStack.Pop()
  209. if opfStack.Len() > 0 { // still in function stack
  210. opfdStack.Push(efp.Token{TValue: result, TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  211. } else {
  212. opdStack.Push(efp.Token{TValue: result, TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  213. }
  214. }
  215. }
  216. }
  217. for optStack.Len() != 0 {
  218. topOpt := optStack.Peek().(efp.Token)
  219. if err = calculate(opdStack, topOpt); err != nil {
  220. return efp.Token{}, err
  221. }
  222. optStack.Pop()
  223. }
  224. return opdStack.Peek().(efp.Token), err
  225. }
  226. // calculate evaluate basic arithmetic operations.
  227. func calculate(opdStack *Stack, opt efp.Token) error {
  228. if opt.TValue == "-" && opt.TType == efp.TokenTypeOperatorPrefix {
  229. opd := opdStack.Pop().(efp.Token)
  230. opdVal, err := strconv.ParseFloat(opd.TValue, 64)
  231. if err != nil {
  232. return err
  233. }
  234. result := 0 - opdVal
  235. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  236. }
  237. if opt.TValue == "+" {
  238. rOpd := opdStack.Pop().(efp.Token)
  239. lOpd := opdStack.Pop().(efp.Token)
  240. lOpdVal, err := strconv.ParseFloat(lOpd.TValue, 64)
  241. if err != nil {
  242. return err
  243. }
  244. rOpdVal, err := strconv.ParseFloat(rOpd.TValue, 64)
  245. if err != nil {
  246. return err
  247. }
  248. result := lOpdVal + rOpdVal
  249. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  250. }
  251. if opt.TValue == "-" && opt.TType == efp.TokenTypeOperatorInfix {
  252. rOpd := opdStack.Pop().(efp.Token)
  253. lOpd := opdStack.Pop().(efp.Token)
  254. lOpdVal, err := strconv.ParseFloat(lOpd.TValue, 64)
  255. if err != nil {
  256. return err
  257. }
  258. rOpdVal, err := strconv.ParseFloat(rOpd.TValue, 64)
  259. if err != nil {
  260. return err
  261. }
  262. result := lOpdVal - rOpdVal
  263. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  264. }
  265. if opt.TValue == "*" {
  266. rOpd := opdStack.Pop().(efp.Token)
  267. lOpd := opdStack.Pop().(efp.Token)
  268. lOpdVal, err := strconv.ParseFloat(lOpd.TValue, 64)
  269. if err != nil {
  270. return err
  271. }
  272. rOpdVal, err := strconv.ParseFloat(rOpd.TValue, 64)
  273. if err != nil {
  274. return err
  275. }
  276. result := lOpdVal * rOpdVal
  277. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  278. }
  279. if opt.TValue == "/" {
  280. rOpd := opdStack.Pop().(efp.Token)
  281. lOpd := opdStack.Pop().(efp.Token)
  282. lOpdVal, err := strconv.ParseFloat(lOpd.TValue, 64)
  283. if err != nil {
  284. return err
  285. }
  286. rOpdVal, err := strconv.ParseFloat(rOpd.TValue, 64)
  287. if err != nil {
  288. return err
  289. }
  290. result := lOpdVal / rOpdVal
  291. if rOpdVal == 0 {
  292. return errors.New(formulaErrorDIV)
  293. }
  294. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  295. }
  296. return nil
  297. }
  298. // parseToken parse basic arithmetic operator priority and evaluate based on
  299. // operators and operands.
  300. func (f *File) parseToken(sheet string, token efp.Token, opdStack, optStack *Stack) error {
  301. // parse reference: must reference at here
  302. if token.TSubType == efp.TokenSubTypeRange {
  303. result, err := f.parseReference(sheet, token.TValue)
  304. if err != nil {
  305. return errors.New(formulaErrorNAME)
  306. }
  307. if len(result) != 1 {
  308. return errors.New(formulaErrorVALUE)
  309. }
  310. token.TValue = result[0]
  311. token.TType = efp.TokenTypeOperand
  312. token.TSubType = efp.TokenSubTypeNumber
  313. }
  314. if (token.TValue == "-" && token.TType == efp.TokenTypeOperatorPrefix) || token.TValue == "+" || token.TValue == "-" || token.TValue == "*" || token.TValue == "/" {
  315. if optStack.Len() == 0 {
  316. optStack.Push(token)
  317. } else {
  318. tokenPriority := getPriority(token)
  319. topOpt := optStack.Peek().(efp.Token)
  320. topOptPriority := getPriority(topOpt)
  321. if tokenPriority > topOptPriority {
  322. optStack.Push(token)
  323. } else {
  324. for tokenPriority <= topOptPriority {
  325. optStack.Pop()
  326. if err := calculate(opdStack, topOpt); err != nil {
  327. return err
  328. }
  329. if optStack.Len() > 0 {
  330. topOpt = optStack.Peek().(efp.Token)
  331. topOptPriority = getPriority(topOpt)
  332. continue
  333. }
  334. break
  335. }
  336. optStack.Push(token)
  337. }
  338. }
  339. }
  340. if token.TType == efp.TokenTypeSubexpression && token.TSubType == efp.TokenSubTypeStart { // (
  341. optStack.Push(token)
  342. }
  343. if token.TType == efp.TokenTypeSubexpression && token.TSubType == efp.TokenSubTypeStop { // )
  344. for optStack.Peek().(efp.Token).TSubType != efp.TokenSubTypeStart && optStack.Peek().(efp.Token).TType != efp.TokenTypeSubexpression { // != (
  345. topOpt := optStack.Peek().(efp.Token)
  346. if err := calculate(opdStack, topOpt); err != nil {
  347. return err
  348. }
  349. optStack.Pop()
  350. }
  351. optStack.Pop()
  352. }
  353. // opd
  354. if token.TType == efp.TokenTypeOperand && token.TSubType == efp.TokenSubTypeNumber {
  355. opdStack.Push(token)
  356. }
  357. return nil
  358. }
  359. // parseReference parse reference and extract values by given reference
  360. // characters and default sheet name.
  361. func (f *File) parseReference(sheet, reference string) (result []string, err error) {
  362. reference = strings.Replace(reference, "$", "", -1)
  363. refs, cellRanges, cellRefs := list.New(), list.New(), list.New()
  364. for _, ref := range strings.Split(reference, ":") {
  365. tokens := strings.Split(ref, "!")
  366. cr := cellRef{}
  367. if len(tokens) == 2 { // have a worksheet name
  368. cr.Sheet = tokens[0]
  369. if cr.Col, cr.Row, err = CellNameToCoordinates(tokens[1]); err != nil {
  370. return
  371. }
  372. if refs.Len() > 0 {
  373. e := refs.Back()
  374. cellRefs.PushBack(e.Value.(cellRef))
  375. refs.Remove(e)
  376. }
  377. refs.PushBack(cr)
  378. continue
  379. }
  380. if cr.Col, cr.Row, err = CellNameToCoordinates(tokens[0]); err != nil {
  381. return
  382. }
  383. e := refs.Back()
  384. if e == nil {
  385. cr.Sheet = sheet
  386. refs.PushBack(cr)
  387. continue
  388. }
  389. cellRanges.PushBack(cellRange{
  390. From: e.Value.(cellRef),
  391. To: cr,
  392. })
  393. refs.Remove(e)
  394. }
  395. if refs.Len() > 0 {
  396. e := refs.Back()
  397. cellRefs.PushBack(e.Value.(cellRef))
  398. refs.Remove(e)
  399. }
  400. result, err = f.rangeResolver(cellRefs, cellRanges)
  401. return
  402. }
  403. // rangeResolver extract value as string from given reference and range list.
  404. // This function will not ignore the empty cell. Note that the result of 3D
  405. // range references may be different from Excel in some cases, for example,
  406. // A1:A2:A2:B3 in Excel will include B1, but we wont.
  407. func (f *File) rangeResolver(cellRefs, cellRanges *list.List) (result []string, err error) {
  408. filter := map[string]string{}
  409. // extract value from ranges
  410. for temp := cellRanges.Front(); temp != nil; temp = temp.Next() {
  411. cr := temp.Value.(cellRange)
  412. if cr.From.Sheet != cr.To.Sheet {
  413. err = errors.New(formulaErrorVALUE)
  414. }
  415. rng := []int{cr.From.Col, cr.From.Row, cr.To.Col, cr.To.Row}
  416. sortCoordinates(rng)
  417. for col := rng[0]; col <= rng[2]; col++ {
  418. for row := rng[1]; row <= rng[3]; row++ {
  419. var cell string
  420. if cell, err = CoordinatesToCellName(col, row); err != nil {
  421. return
  422. }
  423. if filter[cell], err = f.GetCellValue(cr.From.Sheet, cell); err != nil {
  424. return
  425. }
  426. }
  427. }
  428. }
  429. // extract value from references
  430. for temp := cellRefs.Front(); temp != nil; temp = temp.Next() {
  431. cr := temp.Value.(cellRef)
  432. var cell string
  433. if cell, err = CoordinatesToCellName(cr.Col, cr.Row); err != nil {
  434. return
  435. }
  436. if filter[cell], err = f.GetCellValue(cr.Sheet, cell); err != nil {
  437. return
  438. }
  439. }
  440. for _, val := range filter {
  441. result = append(result, val)
  442. }
  443. return
  444. }
  445. // callFuncByName calls the no error or only error return function with
  446. // reflect by given receiver, name and parameters.
  447. func callFuncByName(receiver interface{}, name string, params []reflect.Value) (result string, err error) {
  448. function := reflect.ValueOf(receiver).MethodByName(name)
  449. if function.IsValid() {
  450. rt := function.Call(params)
  451. if len(rt) == 0 {
  452. return
  453. }
  454. if !rt[1].IsNil() {
  455. err = rt[1].Interface().(error)
  456. return
  457. }
  458. result = rt[0].Interface().(string)
  459. return
  460. }
  461. err = fmt.Errorf("not support %s function", name)
  462. return
  463. }
  464. // Math and Trigonometric functions
  465. // ABS function returns the absolute value of any supplied number. The syntax
  466. // of the function is:
  467. //
  468. // ABS(number)
  469. //
  470. func (fn *formulaFuncs) ABS(argsList *list.List) (result string, err error) {
  471. if argsList.Len() != 1 {
  472. err = errors.New("ABS requires 1 numeric arguments")
  473. return
  474. }
  475. var val float64
  476. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  477. if err != nil {
  478. return
  479. }
  480. result = fmt.Sprintf("%g", math.Abs(val))
  481. return
  482. }
  483. // ACOS function calculates the arccosine (i.e. the inverse cosine) of a given
  484. // number, and returns an angle, in radians, between 0 and π. The syntax of
  485. // the function is:
  486. //
  487. // ACOS(number)
  488. //
  489. func (fn *formulaFuncs) ACOS(argsList *list.List) (result string, err error) {
  490. if argsList.Len() != 1 {
  491. err = errors.New("ACOS requires 1 numeric arguments")
  492. return
  493. }
  494. var val float64
  495. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  496. if err != nil {
  497. return
  498. }
  499. result = fmt.Sprintf("%g", math.Acos(val))
  500. return
  501. }
  502. // ACOSH function calculates the inverse hyperbolic cosine of a supplied number.
  503. // of the function is:
  504. //
  505. // ACOSH(number)
  506. //
  507. func (fn *formulaFuncs) ACOSH(argsList *list.List) (result string, err error) {
  508. if argsList.Len() != 1 {
  509. err = errors.New("ACOSH requires 1 numeric arguments")
  510. return
  511. }
  512. var val float64
  513. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  514. if err != nil {
  515. return
  516. }
  517. result = fmt.Sprintf("%g", math.Acosh(val))
  518. return
  519. }
  520. // ACOT function calculates the arccotangent (i.e. the inverse cotangent) of a
  521. // given number, and returns an angle, in radians, between 0 and π. The syntax
  522. // of the function is:
  523. //
  524. // ACOT(number)
  525. //
  526. func (fn *formulaFuncs) ACOT(argsList *list.List) (result string, err error) {
  527. if argsList.Len() != 1 {
  528. err = errors.New("ACOT requires 1 numeric arguments")
  529. return
  530. }
  531. var val float64
  532. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  533. if err != nil {
  534. return
  535. }
  536. result = fmt.Sprintf("%g", math.Pi/2-math.Atan(val))
  537. return
  538. }
  539. // ACOTH function calculates the hyperbolic arccotangent (coth) of a supplied
  540. // value. The syntax of the function is:
  541. //
  542. // ACOTH(number)
  543. //
  544. func (fn *formulaFuncs) ACOTH(argsList *list.List) (result string, err error) {
  545. if argsList.Len() != 1 {
  546. err = errors.New("ACOTH requires 1 numeric arguments")
  547. return
  548. }
  549. var val float64
  550. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  551. if err != nil {
  552. return
  553. }
  554. result = fmt.Sprintf("%g", math.Atanh(1/val))
  555. return
  556. }
  557. // ARABIC function converts a Roman numeral into an Arabic numeral. The syntax
  558. // of the function is:
  559. //
  560. // ARABIC(text)
  561. //
  562. func (fn *formulaFuncs) ARABIC(argsList *list.List) (result string, err error) {
  563. if argsList.Len() != 1 {
  564. err = errors.New("ARABIC requires 1 numeric arguments")
  565. return
  566. }
  567. val, last, prefix := 0.0, 0.0, 1.0
  568. for _, char := range argsList.Front().Value.(efp.Token).TValue {
  569. digit := 0.0
  570. switch char {
  571. case '-':
  572. prefix = -1
  573. continue
  574. case 'I':
  575. digit = 1
  576. case 'V':
  577. digit = 5
  578. case 'X':
  579. digit = 10
  580. case 'L':
  581. digit = 50
  582. case 'C':
  583. digit = 100
  584. case 'D':
  585. digit = 500
  586. case 'M':
  587. digit = 1000
  588. }
  589. val += digit
  590. switch {
  591. case last == digit && (last == 5 || last == 50 || last == 500):
  592. result = formulaErrorVALUE
  593. return
  594. case 2*last == digit:
  595. result = formulaErrorVALUE
  596. return
  597. }
  598. if last < digit {
  599. val -= 2 * last
  600. }
  601. last = digit
  602. }
  603. result = fmt.Sprintf("%g", prefix*val)
  604. return
  605. }
  606. // ASIN function calculates the arcsine (i.e. the inverse sine) of a given
  607. // number, and returns an angle, in radians, between -π/2 and π/2. The syntax
  608. // of the function is:
  609. //
  610. // ASIN(number)
  611. //
  612. func (fn *formulaFuncs) ASIN(argsList *list.List) (result string, err error) {
  613. if argsList.Len() != 1 {
  614. err = errors.New("ASIN requires 1 numeric arguments")
  615. return
  616. }
  617. var val float64
  618. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  619. if err != nil {
  620. return
  621. }
  622. result = fmt.Sprintf("%g", math.Asin(val))
  623. return
  624. }
  625. // ASINH function calculates the inverse hyperbolic sine of a supplied number.
  626. // The syntax of the function is:
  627. //
  628. // ASINH(number)
  629. //
  630. func (fn *formulaFuncs) ASINH(argsList *list.List) (result string, err error) {
  631. if argsList.Len() != 1 {
  632. err = errors.New("ASINH requires 1 numeric arguments")
  633. return
  634. }
  635. var val float64
  636. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  637. if err != nil {
  638. return
  639. }
  640. result = fmt.Sprintf("%g", math.Asinh(val))
  641. return
  642. }
  643. // ATAN function calculates the arctangent (i.e. the inverse tangent) of a
  644. // given number, and returns an angle, in radians, between -π/2 and +π/2. The
  645. // syntax of the function is:
  646. //
  647. // ATAN(number)
  648. //
  649. func (fn *formulaFuncs) ATAN(argsList *list.List) (result string, err error) {
  650. if argsList.Len() != 1 {
  651. err = errors.New("ATAN requires 1 numeric arguments")
  652. return
  653. }
  654. var val float64
  655. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  656. if err != nil {
  657. return
  658. }
  659. result = fmt.Sprintf("%g", math.Atan(val))
  660. return
  661. }
  662. // ATANH function calculates the inverse hyperbolic tangent of a supplied
  663. // number. The syntax of the function is:
  664. //
  665. // ATANH(number)
  666. //
  667. func (fn *formulaFuncs) ATANH(argsList *list.List) (result string, err error) {
  668. if argsList.Len() != 1 {
  669. err = errors.New("ATANH requires 1 numeric arguments")
  670. return
  671. }
  672. var val float64
  673. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  674. if err != nil {
  675. return
  676. }
  677. result = fmt.Sprintf("%g", math.Atanh(val))
  678. return
  679. }
  680. // ATAN2 function calculates the arctangent (i.e. the inverse tangent) of a
  681. // given set of x and y coordinates, and returns an angle, in radians, between
  682. // -π/2 and +π/2. The syntax of the function is:
  683. //
  684. // ATAN2(x_num,y_num)
  685. //
  686. func (fn *formulaFuncs) ATAN2(argsList *list.List) (result string, err error) {
  687. if argsList.Len() != 2 {
  688. err = errors.New("ATAN2 requires 2 numeric arguments")
  689. return
  690. }
  691. var x, y float64
  692. x, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64)
  693. if err != nil {
  694. return
  695. }
  696. y, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  697. if err != nil {
  698. return
  699. }
  700. result = fmt.Sprintf("%g", math.Atan2(x, y))
  701. return
  702. }
  703. // gcd returns the greatest common divisor of two supplied integers.
  704. func gcd(x, y float64) float64 {
  705. x, y = math.Trunc(x), math.Trunc(y)
  706. if x == 0 {
  707. return y
  708. }
  709. if y == 0 {
  710. return x
  711. }
  712. for x != y {
  713. if x > y {
  714. x = x - y
  715. } else {
  716. y = y - x
  717. }
  718. }
  719. return x
  720. }
  721. // BASE function converts a number into a supplied base (radix), and returns a
  722. // text representation of the calculated value. The syntax of the function is:
  723. //
  724. // BASE(number,radix,[min_length])
  725. //
  726. func (fn *formulaFuncs) BASE(argsList *list.List) (result string, err error) {
  727. if argsList.Len() < 2 {
  728. err = errors.New("BASE requires at least 2 arguments")
  729. return
  730. }
  731. if argsList.Len() > 3 {
  732. err = errors.New("BASE allows at most 3 arguments")
  733. return
  734. }
  735. var number float64
  736. var radix, minLength int
  737. number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  738. if err != nil {
  739. return
  740. }
  741. radix, err = strconv.Atoi(argsList.Front().Next().Value.(efp.Token).TValue)
  742. if err != nil {
  743. return
  744. }
  745. if radix < 2 || radix > 36 {
  746. err = errors.New("radix must be an integer ≥ 2 and ≤ 36")
  747. return
  748. }
  749. if argsList.Len() > 2 {
  750. minLength, err = strconv.Atoi(argsList.Back().Value.(efp.Token).TValue)
  751. if err != nil {
  752. return
  753. }
  754. }
  755. result = strconv.FormatInt(int64(number), radix)
  756. if len(result) < minLength {
  757. result = strings.Repeat("0", minLength-len(result)) + result
  758. }
  759. result = strings.ToUpper(result)
  760. return
  761. }
  762. // GCD function returns the greatest common divisor of two or more supplied
  763. // integers. The syntax of the function is:
  764. //
  765. // GCD(number1,[number2],...)
  766. //
  767. func (fn *formulaFuncs) GCD(argsList *list.List) (result string, err error) {
  768. if argsList.Len() == 0 {
  769. err = errors.New("GCD requires at least 1 argument")
  770. return
  771. }
  772. var (
  773. val float64
  774. nums = []float64{}
  775. )
  776. for arg := argsList.Front(); arg != nil; arg = arg.Next() {
  777. token := arg.Value.(efp.Token)
  778. if token.TValue == "" {
  779. continue
  780. }
  781. val, err = strconv.ParseFloat(token.TValue, 64)
  782. if err != nil {
  783. return
  784. }
  785. nums = append(nums, val)
  786. }
  787. if nums[0] < 0 {
  788. err = errors.New("GCD only accepts positive arguments")
  789. return
  790. }
  791. if len(nums) == 1 {
  792. result = fmt.Sprintf("%g", nums[0])
  793. return
  794. }
  795. cd := nums[0]
  796. for i := 1; i < len(nums); i++ {
  797. if nums[i] < 0 {
  798. err = errors.New("GCD only accepts positive arguments")
  799. return
  800. }
  801. cd = gcd(cd, nums[i])
  802. }
  803. result = fmt.Sprintf("%g", cd)
  804. return
  805. }
  806. // lcm returns the least common multiple of two supplied integers.
  807. func lcm(a, b float64) float64 {
  808. a = math.Trunc(a)
  809. b = math.Trunc(b)
  810. if a == 0 && b == 0 {
  811. return 0
  812. }
  813. return a * b / gcd(a, b)
  814. }
  815. // LCM function returns the least common multiple of two or more supplied
  816. // integers. The syntax of the function is:
  817. //
  818. // LCM(number1,[number2],...)
  819. //
  820. func (fn *formulaFuncs) LCM(argsList *list.List) (result string, err error) {
  821. if argsList.Len() == 0 {
  822. err = errors.New("LCM requires at least 1 argument")
  823. return
  824. }
  825. var (
  826. val float64
  827. nums = []float64{}
  828. )
  829. for arg := argsList.Front(); arg != nil; arg = arg.Next() {
  830. token := arg.Value.(efp.Token)
  831. if token.TValue == "" {
  832. continue
  833. }
  834. val, err = strconv.ParseFloat(token.TValue, 64)
  835. if err != nil {
  836. return
  837. }
  838. nums = append(nums, val)
  839. }
  840. if nums[0] < 0 {
  841. err = errors.New("LCM only accepts positive arguments")
  842. return
  843. }
  844. if len(nums) == 1 {
  845. result = fmt.Sprintf("%g", nums[0])
  846. return
  847. }
  848. cm := nums[0]
  849. for i := 1; i < len(nums); i++ {
  850. if nums[i] < 0 {
  851. err = errors.New("LCM only accepts positive arguments")
  852. return
  853. }
  854. cm = lcm(cm, nums[i])
  855. }
  856. result = fmt.Sprintf("%g", cm)
  857. return
  858. }
  859. // POWER function calculates a given number, raised to a supplied power.
  860. // The syntax of the function is:
  861. //
  862. // POWER(number,power)
  863. //
  864. func (fn *formulaFuncs) POWER(argsList *list.List) (result string, err error) {
  865. if argsList.Len() != 2 {
  866. err = errors.New("POWER requires 2 numeric arguments")
  867. return
  868. }
  869. var x, y float64
  870. x, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  871. if err != nil {
  872. return
  873. }
  874. y, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64)
  875. if err != nil {
  876. return
  877. }
  878. if x == 0 && y == 0 {
  879. err = errors.New(formulaErrorNUM)
  880. return
  881. }
  882. if x == 0 && y < 0 {
  883. err = errors.New(formulaErrorDIV)
  884. return
  885. }
  886. result = fmt.Sprintf("%g", math.Pow(x, y))
  887. return
  888. }
  889. // PRODUCT function returns the product (multiplication) of a supplied set of
  890. // numerical values. The syntax of the function is:
  891. //
  892. // PRODUCT(number1,[number2],...)
  893. //
  894. func (fn *formulaFuncs) PRODUCT(argsList *list.List) (result string, err error) {
  895. var (
  896. val float64
  897. product float64 = 1
  898. )
  899. for arg := argsList.Front(); arg != nil; arg = arg.Next() {
  900. token := arg.Value.(efp.Token)
  901. if token.TValue == "" {
  902. continue
  903. }
  904. val, err = strconv.ParseFloat(token.TValue, 64)
  905. if err != nil {
  906. return
  907. }
  908. product = product * val
  909. }
  910. result = fmt.Sprintf("%g", product)
  911. return
  912. }
  913. // SIGN function returns the arithmetic sign (+1, -1 or 0) of a supplied
  914. // number. I.e. if the number is positive, the Sign function returns +1, if
  915. // the number is negative, the function returns -1 and if the number is 0
  916. // (zero), the function returns 0. The syntax of the function is:
  917. //
  918. // SIGN(number)
  919. //
  920. func (fn *formulaFuncs) SIGN(argsList *list.List) (result string, err error) {
  921. if argsList.Len() != 1 {
  922. err = errors.New("SIGN requires 1 numeric arguments")
  923. return
  924. }
  925. var val float64
  926. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  927. if err != nil {
  928. return
  929. }
  930. if val < 0 {
  931. result = "-1"
  932. return
  933. }
  934. if val > 0 {
  935. result = "1"
  936. return
  937. }
  938. result = "0"
  939. return
  940. }
  941. // SQRT function calculates the positive square root of a supplied number. The
  942. // syntax of the function is:
  943. //
  944. // SQRT(number)
  945. //
  946. func (fn *formulaFuncs) SQRT(argsList *list.List) (result string, err error) {
  947. if argsList.Len() != 1 {
  948. err = errors.New("SQRT requires 1 numeric arguments")
  949. return
  950. }
  951. var val float64
  952. val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  953. if err != nil {
  954. return
  955. }
  956. if val < 0 {
  957. err = errors.New(formulaErrorNUM)
  958. return
  959. }
  960. result = fmt.Sprintf("%g", math.Sqrt(val))
  961. return
  962. }
  963. // SUM function adds together a supplied set of numbers and returns the sum of
  964. // these values. The syntax of the function is:
  965. //
  966. // SUM(number1,[number2],...)
  967. //
  968. func (fn *formulaFuncs) SUM(argsList *list.List) (result string, err error) {
  969. var val float64
  970. var sum float64
  971. for arg := argsList.Front(); arg != nil; arg = arg.Next() {
  972. token := arg.Value.(efp.Token)
  973. if token.TValue == "" {
  974. continue
  975. }
  976. val, err = strconv.ParseFloat(token.TValue, 64)
  977. if err != nil {
  978. return
  979. }
  980. sum += val
  981. }
  982. result = fmt.Sprintf("%g", sum)
  983. return
  984. }
  985. // QUOTIENT function returns the integer portion of a division between two
  986. // supplied numbers. The syntax of the function is:
  987. //
  988. // QUOTIENT(numerator,denominator)
  989. //
  990. func (fn *formulaFuncs) QUOTIENT(argsList *list.List) (result string, err error) {
  991. if argsList.Len() != 2 {
  992. err = errors.New("QUOTIENT requires 2 numeric arguments")
  993. return
  994. }
  995. var x, y float64
  996. x, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
  997. if err != nil {
  998. return
  999. }
  1000. y, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64)
  1001. if err != nil {
  1002. return
  1003. }
  1004. if y == 0 {
  1005. err = errors.New(formulaErrorDIV)
  1006. return
  1007. }
  1008. result = fmt.Sprintf("%g", math.Trunc(x/y))
  1009. return
  1010. }