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
|
||||
// FIND
|
||||
// FINDB
|
||||
// F.INV
|
||||
// F.INV.RT
|
||||
// FINV
|
||||
// FISHER
|
||||
|
@ -430,6 +431,7 @@ type formulaFuncs struct {
|
|||
// FVSCHEDULE
|
||||
// GAMMA
|
||||
// GAMMALN
|
||||
// GAUSS
|
||||
// GCD
|
||||
// GEOMEAN
|
||||
// GESTEP
|
||||
|
@ -6064,6 +6066,28 @@ func (fn *formulaFuncs) GAMMALN(argsList *list.List) formulaArg {
|
|||
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.
|
||||
// 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))
|
||||
}
|
||||
|
||||
// finv is an implementation of the formula functions F.INV.RT and FINV.
|
||||
func (fn *formulaFuncs) finv(name string, argsList *list.List) formulaArg {
|
||||
// prepareFinvArgs checking and prepare arguments for the formula function
|
||||
// F.INV, F.INV.RT and FINV.
|
||||
func (fn *formulaFuncs) prepareFinvArgs(name string, argsList *list.List) formulaArg {
|
||||
if argsList.Len() != 3 {
|
||||
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) {
|
||||
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
|
||||
|
@ -6242,7 +6281,12 @@ func (fn *formulaFuncs) finv(name string, argsList *list.List) formulaArg {
|
|||
// F.INV.RT(probability,deg_freedom1,deg_freedom2)
|
||||
//
|
||||
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
|
||||
|
@ -6251,7 +6295,12 @@ func (fn *formulaFuncs) FdotINVdotRT(argsList *list.List) formulaArg {
|
|||
// FINV(probability,deg_freedom1,deg_freedom2)
|
||||
//
|
||||
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
|
||||
|
|
18
calc_test.go
18
calc_test.go
|
@ -838,6 +838,11 @@ func TestCalcCellValue(t *testing.T) {
|
|||
// GAMMALN
|
||||
"=GAMMALN(4.5)": "2.45373657084244",
|
||||
"=GAMMALN(INT(1))": "0",
|
||||
// GAUSS
|
||||
"=GAUSS(-5)": "-0.499999713348428",
|
||||
"=GAUSS(0)": "0",
|
||||
"=GAUSS(0.1)": "0.039827837277029",
|
||||
"=GAUSS(2.5)": "0.493790334674224",
|
||||
// GEOMEAN
|
||||
"=GEOMEAN(2.5,3,0.5,1,3)": "1.6226711115996",
|
||||
// HARMEAN
|
||||
|
@ -855,6 +860,8 @@ func TestCalcCellValue(t *testing.T) {
|
|||
"=EXPONDIST(0.5,1,TRUE)": "0.393469340287367",
|
||||
"=EXPONDIST(0.5,1,FALSE)": "0.606530659712633",
|
||||
"=EXPONDIST(2,1,TRUE)": "0.864664716763387",
|
||||
// F.INV
|
||||
"=F.INV(0.9,2,5)": "3.77971607877395",
|
||||
// FINV
|
||||
"=FINV(0.2,1,2)": "3.55555555555555",
|
||||
"=FINV(0.6,1,2)": "0.380952380952381",
|
||||
|
@ -2380,6 +2387,9 @@ func TestCalcCellValue(t *testing.T) {
|
|||
"=GAMMALN(F1)": "GAMMALN requires 1 numeric argument",
|
||||
"=GAMMALN(0)": "#N/A",
|
||||
"=GAMMALN(INT(0))": "#N/A",
|
||||
// GAUSS
|
||||
"=GAUSS()": "GAUSS requires 1 numeric argument",
|
||||
"=GAUSS(\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
// GEOMEAN
|
||||
"=GEOMEAN()": "GEOMEAN requires at least 1 numeric argument",
|
||||
"=GEOMEAN(0)": "#NUM!",
|
||||
|
@ -2405,6 +2415,14 @@ func TestCalcCellValue(t *testing.T) {
|
|||
"=EXPONDIST(0,1,\"\")": "strconv.ParseBool: parsing \"\": invalid syntax",
|
||||
"=EXPONDIST(-1,1,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 requires 3 arguments",
|
||||
"=FINV(\"\",1,2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
|
|
Loading…
Reference in New Issue