forked from p30928647/excelize
ref #65, new formula functions: F.INV and GAUSS
This commit is contained in:
parent
74b1a998d6
commit
aee7bdd3a0
59
calc.go
59
calc.go
|
@ -417,6 +417,7 @@ type formulaFuncs struct {
|
||||||
// FALSE
|
// FALSE
|
||||||
// FIND
|
// FIND
|
||||||
// FINDB
|
// FINDB
|
||||||
|
// F.INV
|
||||||
// F.INV.RT
|
// F.INV.RT
|
||||||
// FINV
|
// FINV
|
||||||
// FISHER
|
// FISHER
|
||||||
|
@ -430,6 +431,7 @@ type formulaFuncs struct {
|
||||||
// FVSCHEDULE
|
// FVSCHEDULE
|
||||||
// GAMMA
|
// GAMMA
|
||||||
// GAMMALN
|
// GAMMALN
|
||||||
|
// GAUSS
|
||||||
// GCD
|
// GCD
|
||||||
// GEOMEAN
|
// GEOMEAN
|
||||||
// GESTEP
|
// GESTEP
|
||||||
|
@ -6064,6 +6066,28 @@ func (fn *formulaFuncs) GAMMALN(argsList *list.List) formulaArg {
|
||||||
return newErrorFormulaArg(formulaErrorVALUE, "GAMMALN requires 1 numeric argument")
|
return newErrorFormulaArg(formulaErrorVALUE, "GAMMALN requires 1 numeric argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GAUSS function returns the probability that a member of a standard normal
|
||||||
|
// population will fall between the mean and a specified number of standard
|
||||||
|
// deviations from the mean. The syntax of the function is:
|
||||||
|
//
|
||||||
|
// GAUSS(z)
|
||||||
|
//
|
||||||
|
func (fn *formulaFuncs) GAUSS(argsList *list.List) formulaArg {
|
||||||
|
if argsList.Len() != 1 {
|
||||||
|
return newErrorFormulaArg(formulaErrorVALUE, "GAUSS requires 1 numeric argument")
|
||||||
|
}
|
||||||
|
args := list.New().Init()
|
||||||
|
args.PushBack(argsList.Front().Value.(formulaArg))
|
||||||
|
args.PushBack(formulaArg{Type: ArgNumber, Number: 0})
|
||||||
|
args.PushBack(formulaArg{Type: ArgNumber, Number: 1})
|
||||||
|
args.PushBack(newBoolFormulaArg(true))
|
||||||
|
normdist := fn.NORMDIST(args)
|
||||||
|
if normdist.Type != ArgNumber {
|
||||||
|
return normdist
|
||||||
|
}
|
||||||
|
return newNumberFormulaArg(normdist.Number - 0.5)
|
||||||
|
}
|
||||||
|
|
||||||
// GEOMEAN function calculates the geometric mean of a supplied set of values.
|
// GEOMEAN function calculates the geometric mean of a supplied set of values.
|
||||||
// The syntax of the function is:
|
// The syntax of the function is:
|
||||||
//
|
//
|
||||||
|
@ -6208,8 +6232,9 @@ func (fn *formulaFuncs) EXPONDIST(argsList *list.List) formulaArg {
|
||||||
return newNumberFormulaArg(lambda.Number * math.Exp(-lambda.Number*x.Number))
|
return newNumberFormulaArg(lambda.Number * math.Exp(-lambda.Number*x.Number))
|
||||||
}
|
}
|
||||||
|
|
||||||
// finv is an implementation of the formula functions F.INV.RT and FINV.
|
// prepareFinvArgs checking and prepare arguments for the formula function
|
||||||
func (fn *formulaFuncs) finv(name string, argsList *list.List) formulaArg {
|
// F.INV, F.INV.RT and FINV.
|
||||||
|
func (fn *formulaFuncs) prepareFinvArgs(name string, argsList *list.List) formulaArg {
|
||||||
if argsList.Len() != 3 {
|
if argsList.Len() != 3 {
|
||||||
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 arguments", name))
|
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 arguments", name))
|
||||||
}
|
}
|
||||||
|
@ -6232,7 +6257,21 @@ func (fn *formulaFuncs) finv(name string, argsList *list.List) formulaArg {
|
||||||
if d2.Number < 1 || d2.Number >= math.Pow10(10) {
|
if d2.Number < 1 || d2.Number >= math.Pow10(10) {
|
||||||
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
|
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
|
||||||
}
|
}
|
||||||
return newNumberFormulaArg((1/calcBetainv(1.0-(1.0-probability.Number), d2.Number/2, d1.Number/2, 0, 1) - 1.0) * (d2.Number / d1.Number))
|
return newListFormulaArg([]formulaArg{probability, d1, d2})
|
||||||
|
}
|
||||||
|
|
||||||
|
// FdotINV function calculates the inverse of the Cumulative F Distribution
|
||||||
|
// for a supplied probability. The syntax of the F.Inv function is:
|
||||||
|
//
|
||||||
|
// F.INV(probability,deg_freedom1,deg_freedom2)
|
||||||
|
//
|
||||||
|
func (fn *formulaFuncs) FdotINV(argsList *list.List) formulaArg {
|
||||||
|
args := fn.prepareFinvArgs("F.INV", argsList)
|
||||||
|
if args.Type != ArgList {
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
probability, d1, d2 := args.List[0], args.List[1], args.List[2]
|
||||||
|
return newNumberFormulaArg((1/calcBetainv(1-probability.Number, d2.Number/2, d1.Number/2, 0, 1) - 1) * (d2.Number / d1.Number))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FdotINVdotRT function calculates the inverse of the (right-tailed) F
|
// FdotINVdotRT function calculates the inverse of the (right-tailed) F
|
||||||
|
@ -6242,7 +6281,12 @@ func (fn *formulaFuncs) finv(name string, argsList *list.List) formulaArg {
|
||||||
// F.INV.RT(probability,deg_freedom1,deg_freedom2)
|
// F.INV.RT(probability,deg_freedom1,deg_freedom2)
|
||||||
//
|
//
|
||||||
func (fn *formulaFuncs) FdotINVdotRT(argsList *list.List) formulaArg {
|
func (fn *formulaFuncs) FdotINVdotRT(argsList *list.List) formulaArg {
|
||||||
return fn.finv("F.INV.RT", argsList)
|
args := fn.prepareFinvArgs("F.INV.RT", argsList)
|
||||||
|
if args.Type != ArgList {
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
probability, d1, d2 := args.List[0], args.List[1], args.List[2]
|
||||||
|
return newNumberFormulaArg((1/calcBetainv(1-(1-probability.Number), d2.Number/2, d1.Number/2, 0, 1) - 1) * (d2.Number / d1.Number))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FINV function calculates the inverse of the (right-tailed) F Probability
|
// FINV function calculates the inverse of the (right-tailed) F Probability
|
||||||
|
@ -6251,7 +6295,12 @@ func (fn *formulaFuncs) FdotINVdotRT(argsList *list.List) formulaArg {
|
||||||
// FINV(probability,deg_freedom1,deg_freedom2)
|
// FINV(probability,deg_freedom1,deg_freedom2)
|
||||||
//
|
//
|
||||||
func (fn *formulaFuncs) FINV(argsList *list.List) formulaArg {
|
func (fn *formulaFuncs) FINV(argsList *list.List) formulaArg {
|
||||||
return fn.finv("FINV", argsList)
|
args := fn.prepareFinvArgs("FINV", argsList)
|
||||||
|
if args.Type != ArgList {
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
probability, d1, d2 := args.List[0], args.List[1], args.List[2]
|
||||||
|
return newNumberFormulaArg((1/calcBetainv(1-(1-probability.Number), d2.Number/2, d1.Number/2, 0, 1) - 1) * (d2.Number / d1.Number))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NORMdotDIST function calculates the Normal Probability Density Function or
|
// NORMdotDIST function calculates the Normal Probability Density Function or
|
||||||
|
|
18
calc_test.go
18
calc_test.go
|
@ -838,6 +838,11 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
// GAMMALN
|
// GAMMALN
|
||||||
"=GAMMALN(4.5)": "2.45373657084244",
|
"=GAMMALN(4.5)": "2.45373657084244",
|
||||||
"=GAMMALN(INT(1))": "0",
|
"=GAMMALN(INT(1))": "0",
|
||||||
|
// GAUSS
|
||||||
|
"=GAUSS(-5)": "-0.499999713348428",
|
||||||
|
"=GAUSS(0)": "0",
|
||||||
|
"=GAUSS(0.1)": "0.039827837277029",
|
||||||
|
"=GAUSS(2.5)": "0.493790334674224",
|
||||||
// GEOMEAN
|
// GEOMEAN
|
||||||
"=GEOMEAN(2.5,3,0.5,1,3)": "1.6226711115996",
|
"=GEOMEAN(2.5,3,0.5,1,3)": "1.6226711115996",
|
||||||
// HARMEAN
|
// HARMEAN
|
||||||
|
@ -855,6 +860,8 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
"=EXPONDIST(0.5,1,TRUE)": "0.393469340287367",
|
"=EXPONDIST(0.5,1,TRUE)": "0.393469340287367",
|
||||||
"=EXPONDIST(0.5,1,FALSE)": "0.606530659712633",
|
"=EXPONDIST(0.5,1,FALSE)": "0.606530659712633",
|
||||||
"=EXPONDIST(2,1,TRUE)": "0.864664716763387",
|
"=EXPONDIST(2,1,TRUE)": "0.864664716763387",
|
||||||
|
// F.INV
|
||||||
|
"=F.INV(0.9,2,5)": "3.77971607877395",
|
||||||
// FINV
|
// FINV
|
||||||
"=FINV(0.2,1,2)": "3.55555555555555",
|
"=FINV(0.2,1,2)": "3.55555555555555",
|
||||||
"=FINV(0.6,1,2)": "0.380952380952381",
|
"=FINV(0.6,1,2)": "0.380952380952381",
|
||||||
|
@ -2380,6 +2387,9 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
"=GAMMALN(F1)": "GAMMALN requires 1 numeric argument",
|
"=GAMMALN(F1)": "GAMMALN requires 1 numeric argument",
|
||||||
"=GAMMALN(0)": "#N/A",
|
"=GAMMALN(0)": "#N/A",
|
||||||
"=GAMMALN(INT(0))": "#N/A",
|
"=GAMMALN(INT(0))": "#N/A",
|
||||||
|
// GAUSS
|
||||||
|
"=GAUSS()": "GAUSS requires 1 numeric argument",
|
||||||
|
"=GAUSS(\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||||
// GEOMEAN
|
// GEOMEAN
|
||||||
"=GEOMEAN()": "GEOMEAN requires at least 1 numeric argument",
|
"=GEOMEAN()": "GEOMEAN requires at least 1 numeric argument",
|
||||||
"=GEOMEAN(0)": "#NUM!",
|
"=GEOMEAN(0)": "#NUM!",
|
||||||
|
@ -2405,6 +2415,14 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
"=EXPONDIST(0,1,\"\")": "strconv.ParseBool: parsing \"\": invalid syntax",
|
"=EXPONDIST(0,1,\"\")": "strconv.ParseBool: parsing \"\": invalid syntax",
|
||||||
"=EXPONDIST(-1,1,TRUE)": "#NUM!",
|
"=EXPONDIST(-1,1,TRUE)": "#NUM!",
|
||||||
"=EXPONDIST(1,0,TRUE)": "#NUM!",
|
"=EXPONDIST(1,0,TRUE)": "#NUM!",
|
||||||
|
// F.INV
|
||||||
|
"=F.INV()": "F.INV requires 3 arguments",
|
||||||
|
"=F.INV(\"\",1,2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||||
|
"=F.INV(0.2,\"\",2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||||
|
"=F.INV(0.2,1,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||||
|
"=F.INV(0,1,2)": "#NUM!",
|
||||||
|
"=F.INV(0.2,0.5,2)": "#NUM!",
|
||||||
|
"=F.INV(0.2,1,0.5)": "#NUM!",
|
||||||
// FINV
|
// FINV
|
||||||
"=FINV()": "FINV requires 3 arguments",
|
"=FINV()": "FINV requires 3 arguments",
|
||||||
"=FINV(\"\",1,2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
"=FINV(\"\",1,2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||||
|
|
Loading…
Reference in New Issue