@@ -664,6 +664,8 @@ type formulaFuncs struct {
664664// TEXTJOIN
665665// TIME
666666// TIMEVALUE
667+ // T.INV
668+ // T.INV.2T
667669// TODAY
668670// TRANSPOSE
669671// TRIM
@@ -1265,27 +1267,6 @@ func isOperand(token efp.Token) bool {
12651267 return token .TType == efp .TokenTypeOperand && (token .TSubType == efp .TokenSubTypeNumber || token .TSubType == efp .TokenSubTypeText )
12661268}
12671269
1268- // getDefinedNameRefTo convert defined name to reference range.
1269- func (f * File ) getDefinedNameRefTo (definedNameName string , currentSheet string ) (refTo string ) {
1270- var workbookRefTo , worksheetRefTo string
1271- for _ , definedName := range f .GetDefinedName () {
1272- if definedName .Name == definedNameName {
1273- // worksheet scope takes precedence over scope workbook when both definedNames exist
1274- if definedName .Scope == "Workbook" {
1275- workbookRefTo = definedName .RefersTo
1276- }
1277- if definedName .Scope == currentSheet {
1278- worksheetRefTo = definedName .RefersTo
1279- }
1280- }
1281- }
1282- refTo = workbookRefTo
1283- if worksheetRefTo != "" {
1284- refTo = worksheetRefTo
1285- }
1286- return
1287- }
1288-
12891270// parseToken parse basic arithmetic operator priority and evaluate based on
12901271// operators and operands.
12911272func (f * File ) parseToken (sheet string , token efp.Token , opdStack , optStack * Stack ) error {
@@ -6647,14 +6628,16 @@ func hasChangeOfSign(u, w float64) bool {
66476628// calcInverseIterator directly maps the required parameters for inverse
66486629// distribution functions.
66496630type calcInverseIterator struct {
6650- name string
6651- fp , fDF float64
6631+ name string
6632+ fp , fDF , nT float64
66526633}
66536634
6654- // chiSqDist implements inverse distribution with left tail for the Chi-Square
6655- // distribution.
6656- func (iterator * calcInverseIterator ) chiSqDist (x float64 ) float64 {
6657- return iterator .fp - getChiSqDistCDF (x , iterator .fDF )
6635+ // callBack implements the callback function for the inverse iterator.
6636+ func (iterator * calcInverseIterator ) callBack (x float64 ) float64 {
6637+ if iterator .name == "CHISQ.INV" {
6638+ return iterator .fp - getChiSqDistCDF (x , iterator .fDF )
6639+ }
6640+ return iterator .fp - getTDist (x , iterator .fDF , iterator .nT )
66586641}
66596642
66606643// inverseQuadraticInterpolation inverse quadratic interpolation with
@@ -6682,7 +6665,7 @@ func inverseQuadraticInterpolation(iterator calcInverseIterator, fAx, fAy, fBx,
66826665 bHasToInterpolate = true
66836666 }
66846667 fPx , fQx , fRx , fPy , fQy = fQx , fRx , fSx , fQy , fRy
6685- fRy = iterator .chiSqDist (fSx )
6668+ fRy = iterator .callBack (fSx )
66866669 if hasChangeOfSign (fAy , fRy ) {
66876670 fBx , fBy = fRx , fRy
66886671 } else {
@@ -6697,7 +6680,7 @@ func inverseQuadraticInterpolation(iterator calcInverseIterator, fAx, fAy, fBx,
66976680// calcIterateInverse function calculates the iteration for inverse
66986681// distributions.
66996682func calcIterateInverse (iterator calcInverseIterator , fAx , fBx float64 ) float64 {
6700- fAy , fBy := iterator .chiSqDist (fAx ), iterator .chiSqDist (fBx )
6683+ fAy , fBy := iterator .callBack (fAx ), iterator .callBack (fBx )
67016684 var fTemp float64
67026685 var nCount int
67036686 for nCount = 0 ; nCount < 1000 && ! hasChangeOfSign (fAy , fBy ); nCount ++ {
@@ -6709,13 +6692,13 @@ func calcIterateInverse(iterator calcInverseIterator, fAx, fBx float64) float64
67096692 }
67106693 fBx = fTemp
67116694 fBy = fAy
6712- fAy = iterator .chiSqDist (fAx )
6695+ fAy = iterator .callBack (fAx )
67136696 } else {
67146697 fTemp = fBx
67156698 fBx += 2 * (fBx - fAx )
67166699 fAx = fTemp
67176700 fAy = fBy
6718- fBy = iterator .chiSqDist (fBx )
6701+ fBy = iterator .callBack (fBx )
67196702 }
67206703 }
67216704 if fAy == 0 || fBy == 0 {
@@ -9152,6 +9135,72 @@ func (fn *formulaFuncs) TDIST(argsList *list.List) formulaArg {
91529135 return newNumberFormulaArg (getTDist (x .Number , degrees .Number , tails .Number ))
91539136}
91549137
9138+ // TdotINV function calculates the left-tailed inverse of the Student's T
9139+ // Distribution, which is a continuous probability distribution that is
9140+ // frequently used for testing hypotheses on small sample data sets. The
9141+ // syntax of the function is:
9142+ //
9143+ // T.INV(probability,degrees_freedom)
9144+ //
9145+ func (fn * formulaFuncs ) TdotINV (argsList * list.List ) formulaArg {
9146+ if argsList .Len () != 2 {
9147+ return newErrorFormulaArg (formulaErrorVALUE , "T.INV requires 2 arguments" )
9148+ }
9149+ var probability , degrees formulaArg
9150+ if probability = argsList .Front ().Value .(formulaArg ).ToNumber (); probability .Type != ArgNumber {
9151+ return probability
9152+ }
9153+ if degrees = argsList .Back ().Value .(formulaArg ).ToNumber (); degrees .Type != ArgNumber {
9154+ return degrees
9155+ }
9156+ if probability .Number <= 0 || probability .Number >= 1 || degrees .Number < 1 {
9157+ return newErrorFormulaArg (formulaErrorNUM , formulaErrorNUM )
9158+ }
9159+ if probability .Number < 0.5 {
9160+ return newNumberFormulaArg (- calcIterateInverse (calcInverseIterator {
9161+ name : "T.INV" ,
9162+ fp : 1 - probability .Number ,
9163+ fDF : degrees .Number ,
9164+ nT : 4 ,
9165+ }, degrees .Number / 2 , degrees .Number ))
9166+ }
9167+ return newNumberFormulaArg (calcIterateInverse (calcInverseIterator {
9168+ name : "T.INV" ,
9169+ fp : probability .Number ,
9170+ fDF : degrees .Number ,
9171+ nT : 4 ,
9172+ }, degrees .Number / 2 , degrees .Number ))
9173+ }
9174+
9175+ // TdotINVdot2T function calculates the inverse of the two-tailed Student's T
9176+ // Distribution, which is a continuous probability distribution that is
9177+ // frequently used for testing hypotheses on small sample data sets. The
9178+ // syntax of the function is:
9179+ //
9180+ // T.INV.2T(probability,degrees_freedom)
9181+ //
9182+ func (fn * formulaFuncs ) TdotINVdot2T (argsList * list.List ) formulaArg {
9183+ if argsList .Len () != 2 {
9184+ return newErrorFormulaArg (formulaErrorVALUE , "T.INV.2T requires 2 arguments" )
9185+ }
9186+ var probability , degrees formulaArg
9187+ if probability = argsList .Front ().Value .(formulaArg ).ToNumber (); probability .Type != ArgNumber {
9188+ return probability
9189+ }
9190+ if degrees = argsList .Back ().Value .(formulaArg ).ToNumber (); degrees .Type != ArgNumber {
9191+ return degrees
9192+ }
9193+ if probability .Number <= 0 || probability .Number > 1 || degrees .Number < 1 {
9194+ return newErrorFormulaArg (formulaErrorNUM , formulaErrorNUM )
9195+ }
9196+ return newNumberFormulaArg (calcIterateInverse (calcInverseIterator {
9197+ name : "T.INV.2T" ,
9198+ fp : probability .Number ,
9199+ fDF : degrees .Number ,
9200+ nT : 2 ,
9201+ }, degrees .Number / 2 , degrees .Number ))
9202+ }
9203+
91559204// TRIMMEAN function calculates the trimmed mean (or truncated mean) of a
91569205// supplied set of values. The syntax of the function is:
91579206//
0 commit comments