1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SC_SOURCE_CORE_INC_INTERPRE_HXX
21 #define INCLUDED_SC_SOURCE_CORE_INC_INTERPRE_HXX
24 #include <rtl/math.hxx>
25 #include <rtl/ustring.hxx>
26 #include <formula/errorcodes.hxx>
27 #include <formula/tokenarray.hxx>
31 #include "externalrefmgr.hxx"
32 #include "calcconfig.hxx"
35 #include "parclass.hxx"
43 class SvNumberFormatter
;
46 struct ScDBQueryParamBase
;
49 struct ScSingleRefData
;
50 struct ScComplexRefData
;
52 namespace formula
{ class FormulaToken
; }
54 struct ScRefCellValue
;
60 struct CompareOptions
;
66 class SharedStringPool
;
70 #define MAXSTACK (4096 / sizeof(formula::FormulaToken*))
75 DECL_FIXEDMEMPOOL_NEWDEL( ScTokenStack
)
76 formula::FormulaToken
* pPointer
[ MAXSTACK
];
81 ifSUMSQ
, // Sums of squares
84 ifCOUNT
, // Count Values
85 ifCOUNT2
, // Count Values (not empty)
92 ifSUMIF
, // Conditional sum
93 ifAVERAGEIF
// Conditional average
98 ifSUMIFS
, // Multi-Conditional sum
99 ifAVERAGEIFS
, // Multi-Conditional average
100 ifCOUNTIFS
// Multi-Conditional count
103 struct FormulaTokenRef_less
105 bool operator () ( const formula::FormulaConstTokenRef
& r1
, const formula::FormulaConstTokenRef
& r2
) const
106 { return r1
.get() < r2
.get(); }
108 typedef ::std::map
< const formula::FormulaConstTokenRef
, formula::FormulaTokenRef
, FormulaTokenRef_less
> ScTokenMatrixMap
;
112 // distibution function objects need the GetxxxDist methods
113 friend class ScGammaDistFunction
;
114 friend class ScBetaDistFunction
;
115 friend class ScTDistFunction
;
116 friend class ScFDistFunction
;
117 friend class ScChiDistFunction
;
118 friend class ScChiSqDistFunction
;
121 DECL_FIXEDMEMPOOL_NEWDEL( ScInterpreter
)
123 static SC_DLLPUBLIC
void SetGlobalConfig(const ScCalcConfig
& rConfig
);
124 static SC_DLLPUBLIC
const ScCalcConfig
& GetGlobalConfig();
126 static void GlobalExit(); // called by ScGlobal::Clear()
128 /// Could string be a regular expression?
129 /// If pDoc!=NULL the document options are taken into account and if
130 /// RegularExpressions are disabled the function returns false regardless
131 /// of the string content.
132 static bool MayBeRegExp( const OUString
& rStr
, const ScDocument
* pDoc
);
134 /// Fail safe division, returning an errDivisionByZero coded into a double
135 /// if denominator is 0.0
136 static inline double div( const double& fNumerator
, const double& fDenominator
);
138 ScMatrixRef
GetNewMat(SCSIZE nC
, SCSIZE nR
, bool bEmpty
= false);
146 VolatileType
GetVolatileType() const { return meVolatileType
;}
149 static ScCalcConfig maGlobalConfig
;
151 static ScTokenStack
* pGlobalStack
;
152 static bool bGlobalStackInUse
;
154 ScCalcConfig maCalcConfig
;
155 formula::FormulaTokenIterator aCode
;
159 svl::SharedStringPool
& mrStrPool
;
160 formula::FormulaTokenRef xResult
;
161 ScJumpMatrix
* pJumpMatrix
; // currently active array condition, if any
162 ScTokenMatrixMap
* pTokenMatrixMap
; // map FormulaToken* to formula::FormulaTokenRef if in array condition
163 ScFormulaCell
* pMyFormulaCell
; // the cell of this formula expression
164 SvNumberFormatter
* pFormatter
;
166 const formula::FormulaToken
*
167 pCur
; // current token
168 ScTokenStack
* pStackObj
; // contains the stacks
169 formula::FormulaToken
** pStack
; // the current stack
170 sal_uInt16 nGlobalError
; // global (local to this formula expression) error
171 sal_uInt16 sp
; // stack pointer
172 sal_uInt16 maxsp
; // the maximal used stack pointer
173 sal_uLong nFuncFmtIndex
; // NumberFormatIndex of a function
174 sal_uLong nCurFmtIndex
; // current NumberFormatIndex
175 sal_uLong nRetFmtIndex
; // NumberFormatIndex of an expression, if any
176 short nFuncFmtType
; // NumberFormatType of a function
177 short nCurFmtType
; // current NumberFormatType
178 short nRetFmtType
; // NumberFormatType of an expression
179 sal_uInt16 mnStringNoValueError
; // the error set in ConvertStringToValue() if no value
180 sal_uInt16 mnSubTotalFlags
; // flags for subtotal and aggregate functions
181 sal_uInt8 cPar
; // current count of parameters
182 bool bCalcAsShown
; // precision as shown
183 bool bMatrixFormula
; // formula cell is a matrix formula
185 VolatileType meVolatileType
;
187 /// Merge global and document specific settings.
188 void MergeCalcConfig();
190 // nMust <= nAct <= nMax ? ok : PushError
191 inline bool MustHaveParamCount( short nAct
, short nMust
);
192 inline bool MustHaveParamCount( short nAct
, short nMust
, short nMax
);
193 inline bool MustHaveParamCountMin( short nAct
, short nMin
);
194 void PushParameterExpected();
195 void PushIllegalParameter();
196 void PushIllegalArgument();
200 // Functions for accessing a document
202 void ReplaceCell( ScAddress
& ); // for TableOp
203 void ReplaceCell( SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
); // for TableOp
204 bool IsTableOpInRange( const ScRange
& );
205 sal_uLong
GetCellNumberFormat( const ScAddress
& rPos
, ScRefCellValue
& rCell
);
206 double ConvertStringToValue( const OUString
& );
208 /** For matrix back calls into the current interpreter.
209 Uses rError instead of nGlobalError and rCurFmtType instead of nCurFmtType. */
210 double ConvertStringToValue( const OUString
&, sal_uInt16
& rError
, short& rCurFmtType
);
212 double GetCellValue( const ScAddress
&, ScRefCellValue
& rCell
);
213 double GetCellValueOrZero( const ScAddress
&, ScRefCellValue
& rCell
);
214 double GetValueCellValue( const ScAddress
&, double fOrig
);
215 void GetCellString( svl::SharedString
& rStr
, ScRefCellValue
& rCell
);
216 static sal_uInt16
GetCellErrCode( const ScRefCellValue
& rCell
);
218 bool CreateDoubleArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
219 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, sal_uInt8
* pCellArr
);
220 bool CreateStringArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
221 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, sal_uInt8
* pCellArr
);
222 bool CreateCellArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
223 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, sal_uInt8
* pCellArr
);
227 /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
228 passed is not formula::FormulaErrorToken.
229 Increments RefCount of the original token if not substituted. */
230 void Push( formula::FormulaToken
& r
);
232 /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
233 Used to push RPN tokens or from within Push() or tokens that are already
234 explicit formula::FormulaErrorToken. Increments RefCount. */
235 void PushWithoutError( formula::FormulaToken
& r
);
237 /** Clones the token to be pushed or substitutes with formula::FormulaErrorToken if
238 nGlobalError is set and the token passed is not formula::FormulaErrorToken. */
239 void PushTempToken( const formula::FormulaToken
& );
241 /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
242 passed is not formula::FormulaErrorToken.
243 Increments RefCount of the original token if not substituted.
244 ATTENTION! The token had to be allocated with `new' and must not be used
245 after this call if no RefCount was set because possibly it gets immediately
246 deleted in case of an errStackOverflow or if substituted with formula::FormulaErrorToken! */
247 void PushTempToken( formula::FormulaToken
* );
249 /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
250 Used to push tokens from within PushTempToken() or tokens that are already
251 explicit formula::FormulaErrorToken. Increments RefCount.
252 ATTENTION! The token had to be allocated with `new' and must not be used
253 after this call if no RefCount was set because possibly it gets immediately
254 decremented again and thus deleted in case of an errStackOverflow! */
255 void PushTempTokenWithoutError( formula::FormulaToken
* );
257 /** If nGlobalError is set push formula::FormulaErrorToken.
258 If nGlobalError is not set do nothing.
259 Used in PushTempToken() and alike to simplify handling.
260 @return: <TRUE/> if nGlobalError. */
261 inline bool IfErrorPushError()
265 PushTempTokenWithoutError( new formula::FormulaErrorToken( nGlobalError
));
271 /** Obtain cell result / content from address and push as temp token.
272 bDisplayEmptyAsString is passed to ScEmptyCell in case of an empty cell
273 result. Also obtain number format and type if _both_, type and index
274 pointer, are not NULL. */
275 void PushCellResultToken( bool bDisplayEmptyAsString
, const ScAddress
& rAddress
,
276 short * pRetTypeExpr
, sal_uLong
* pRetIndexExpr
);
278 formula::FormulaTokenRef
PopToken();
282 svl::SharedString
PopString();
283 void ValidateRef( const ScSingleRefData
& rRef
);
284 void ValidateRef( const ScComplexRefData
& rRef
);
285 void ValidateRef( const ScRefList
& rRefList
);
286 void SingleRefToVars( const ScSingleRefData
& rRef
, SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
);
287 void PopSingleRef( ScAddress
& );
288 void PopSingleRef(SCCOL
& rCol
, SCROW
&rRow
, SCTAB
& rTab
);
289 void DoubleRefToRange( const ScComplexRefData
&, ScRange
&, bool bDontCheckForTableOp
= false );
290 /** If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of
292 Else if StackVar svRefList return values of the ScComplexRefData where
293 rRefInList is pointing to. rRefInList is incremented. If rRefInList was the
294 last element in list pop ScRefListToken and set rRefInList to 0, else
295 rParam is incremented (!) to allow usage as in
296 while(nParamCount--) PopDoubleRef(aRange,nParamCount,nRefInList);
298 void PopDoubleRef( ScRange
& rRange
, short & rParam
, size_t & rRefInList
);
299 void PopDoubleRef( ScRange
&, bool bDontCheckForTableOp
= false );
300 void DoubleRefToVars( const formula::FormulaToken
* p
,
301 SCCOL
& rCol1
, SCROW
&rRow1
, SCTAB
& rTab1
,
302 SCCOL
& rCol2
, SCROW
&rRow2
, SCTAB
& rTab2
,
303 bool bDontCheckForTableOp
= false );
304 ScDBRangeBase
* PopDBDoubleRef();
305 void PopDoubleRef(SCCOL
& rCol1
, SCROW
&rRow1
, SCTAB
& rTab1
,
306 SCCOL
& rCol2
, SCROW
&rRow2
, SCTAB
& rTab2
,
307 bool bDontCheckForTableOp
= false );
308 void PopExternalSingleRef(sal_uInt16
& rFileId
, OUString
& rTabName
, ScSingleRefData
& rRef
);
309 void PopExternalSingleRef(ScExternalRefCache::TokenRef
& rToken
, ScExternalRefCache::CellFormat
* pFmt
= NULL
);
310 void PopExternalSingleRef(sal_uInt16
& rFileId
, OUString
& rTabName
, ScSingleRefData
& rRef
,
311 ScExternalRefCache::TokenRef
& rToken
, ScExternalRefCache::CellFormat
* pFmt
= NULL
);
312 void PopExternalDoubleRef(sal_uInt16
& rFileId
, OUString
& rTabName
, ScComplexRefData
& rRef
);
313 void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef
& rArray
);
314 void PopExternalDoubleRef(ScMatrixRef
& rMat
);
315 void GetExternalDoubleRef(sal_uInt16 nFileId
, const OUString
& rTabName
, const ScComplexRefData
& aData
, ScExternalRefCache::TokenArrayRef
& rArray
);
316 bool PopDoubleRefOrSingleRef( ScAddress
& rAdr
);
317 void PopDoubleRefPushMatrix();
318 // If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix.
319 // Else convert area reference parameters marked as ForceArray to array.
320 // Returns true if JumpMatrix created.
321 bool ConvertMatrixParameters();
322 inline void MatrixDoubleRefToMatrix(); // if MatrixFormula: PopDoubleRefPushMatrix
323 // If MatrixFormula or ForceArray: ConvertMatrixParameters()
324 inline bool MatrixParameterConversion();
325 ScMatrixRef
PopMatrix();
326 sc::RangeMatrix
PopRangeMatrix();
327 void QueryMatrixType(ScMatrixRef
& xMat
, short& rRetTypeExpr
, sal_uLong
& rRetIndexExpr
);
329 void PushDouble(double nVal
);
330 void PushInt( int nVal
);
331 void PushStringBuffer( const sal_Unicode
* pString
);
332 void PushString( const OUString
& rStr
);
333 void PushString( const svl::SharedString
& rString
);
334 void PushSingleRef(SCCOL nCol
, SCROW nRow
, SCTAB nTab
);
335 void PushDoubleRef(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
336 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
);
337 void PushExternalSingleRef(sal_uInt16 nFileId
, const OUString
& rTabName
,
338 SCCOL nCol
, SCROW nRow
, SCTAB nTab
);
339 void PushExternalDoubleRef(sal_uInt16 nFileId
, const OUString
& rTabName
,
340 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
341 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
);
342 void PushSingleRef( const ScRefAddress
& rRef
);
343 void PushDoubleRef( const ScRefAddress
& rRef1
, const ScRefAddress
& rRef2
);
344 void PushMatrix( const sc::RangeMatrix
& rMat
);
345 void PushMatrix(const ScMatrixRef
& pMat
);
346 void PushError( sal_uInt16 nError
);
347 /// Raw stack type without default replacements.
348 formula::StackVar
GetRawStackType();
349 /// Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formula::svDouble.
350 formula::StackVar
GetStackType();
351 // peek StackType of Parameter, Parameter 1 == TOS, 2 == TOS-1, ...
352 formula::StackVar
GetStackType( sal_uInt8 nParam
);
353 sal_uInt8
GetByte() { return cPar
; }
354 // generates a position-dependent SingleRef out of a DoubleRef
355 bool DoubleRefToPosSingleRef( const ScRange
& rRange
, ScAddress
& rAdr
);
356 double GetDoubleFromMatrix(const ScMatrixRef
& pMat
);
358 double GetDoubleWithDefault(double nDefault
);
360 bool GetBool() { return GetDouble() != 0.0; }
361 svl::SharedString
GetString();
362 svl::SharedString
GetStringFromMatrix(const ScMatrixRef
& pMat
);
363 // pop matrix and obtain one element, upper left or according to jump matrix
364 ScMatValType
GetDoubleOrStringFromMatrix( double& rDouble
, svl::SharedString
& rString
);
365 ScMatrixRef
CreateMatrixFromDoubleRef( const formula::FormulaToken
* pToken
,
366 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
367 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
);
368 inline ScTokenMatrixMap
& GetTokenMatrixMap();
369 static ScTokenMatrixMap
* CreateTokenMatrixMap();
370 ScMatrixRef
GetMatrix();
371 sc::RangeMatrix
GetRangeMatrix();
373 void ScTableOp(); // repeated operations
375 // common helper functions
377 void SetMaxIterationCount(sal_uInt16 n
);
378 inline void CurFmtToFuncFmt()
379 { nFuncFmtType
= nCurFmtType
; nFuncFmtIndex
= nCurFmtIndex
; }
381 /** Check if a double is suitable as string position or length argument.
383 If fVal is Inf or NaN it is changed to -1, if it is less than 0 it is
384 sanitized to 0, if it is greater than some implementation defined max
385 string length it is sanitized to that max.
387 @return TRUE if double value fVal is suitable as string argument and was
389 FALSE if not and fVal was adapted.
391 static inline bool CheckStringPositionArgument( double & fVal
);
393 /** Obtain a double suitable as string position or length argument.
394 Returns -1 if the number is Inf or NaN or less than 0 or greater than some
395 implementation defined max string length. */
396 inline double GetStringPositionArgument();
398 // Check for String overflow of rResult+rAdd and set error and erase rResult
399 // if so. Return true if ok, false if overflow
400 inline bool CheckStringResultLen( OUString
& rResult
, const OUString
& rAdd
);
401 // Set error according to rVal, and set rVal to 0.0 if there was an error.
402 inline void TreatDoubleError( double& rVal
);
403 // Lookup using ScLookupCache, @returns true if found and result address
404 bool LookupQueryWithCache( ScAddress
& o_rResultPos
,
405 const ScQueryParam
& rParam
) const;
408 void ScIfError( bool bNAonly
);
411 // Be sure to only call this if pStack[sp-nStackLevel] really contains a
412 // ScJumpMatrixToken, no further checks are applied!
413 // Returns true if last jump was executed and result matrix pushed.
414 bool JumpMatrix( short nStackLevel
);
416 double Compare( ScQueryOp eOp
);
418 NULL means case sensitivity document option is to be used!
420 sc::RangeMatrix
CompareMat( ScQueryOp eOp
, sc::CompareOptions
* pOptions
= NULL
);
421 ScMatrixRef
QueryMat( const ScMatrixRef
& pMat
, sc::CompareOptions
& rOptions
);
427 void ScGreaterEqual();
433 void ScPercentSign();
461 void ScCosecantHyp();
470 void ScIsNonString();
474 void ScCellExternal();
496 void ScNumberValue();
503 void ScMin( bool bTextAsZero
= false );
504 void ScMax( bool bTextAsZero
= false );
505 double IterateParameters( ScIterFunc
, bool bTextAsZero
= false );
509 void ScAverage( bool bTextAsZero
= false );
512 void GetStVarParams( double& rVal
, double& rValCount
, bool bTextAsZero
= false );
513 void ScVar( bool bTextAsZero
= false );
514 void ScVarP( bool bTextAsZero
= false );
515 void ScStDev( bool bTextAsZero
= false );
516 void ScStDevP( bool bTextAsZero
= false );
524 double IterateParametersIf( ScIterFuncIf
);
528 double IterateParametersIfs( ScIterFuncIfs
);
532 void ScCountEmptyCells();
538 // If upon call rMissingField==true then the database field parameter may be
539 // missing (Xcl DCOUNT() syntax), or may be faked as missing by having the
540 // value 0.0 or being exactly the entire database range reference (old SO
541 // compatibility). If this was the case then rMissingField is set to true upon
542 // return. If rMissingField==false upon call all "missing cases" are considered
544 ScDBQueryParamBase
* GetDBParams( bool& rMissingField
);
546 void DBIterator( ScIterFunc
);
555 void GetDBStVarParams( double& rVal
, double& rValCount
);
561 void ScAddressFunc();
582 bool SetSbxVariable( SbxVariable
* pVar
, const ScAddress
& );
583 bool SetSbxVariable( SbxVariable
* pVar
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
);
584 sal_uInt16
GetErrorType();
586 void ScErrorType_ODF();
588 void ScColRowNameAuto();
589 void ScGetPivotData();
600 /** Obtain the date serial number for a given date.
602 If false, nYear < 100 takes the two-digit year setting into account,
603 and rollover of invalid calendar dates takes place, e.g. 1999-02-31 =>
605 If true, the date passed must be a valid Gregorian calendar date. No
606 two-digit expanding or rollover is done.
608 @param bCheckGregorian
609 If true, date must be Gregorian, i.e. >= 1582-10-15.
610 If false, don't care, any valid date >= 0-1-1 will do.
612 double GetDateSerial( sal_Int16 nYear
, sal_Int16 nMonth
, sal_Int16 nDay
, bool bStrict
, bool bCheckGregorian
);
619 void ScGetDayOfWeek();
620 void ScGetWeekOfYear();
621 void ScEasterSunday();
622 sal_uInt16
GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount
, const sal_uInt32 nNullDate
,
623 ::std::vector
<double>& rSortArray
, bool bWeekendMask
[ 7 ] );
624 sal_uInt16
GetWeekendAndHolidayMasks_MS( const sal_uInt8 nParamCount
, const sal_uInt32 nNullDate
,
625 ::std::vector
<double>& rSortArray
, bool bWeekendMask
[ 7 ] );
626 static inline sal_Int16
GetDayOfWeek( sal_Int32 n
);
627 void ScNetWorkdays( bool bOOXML_Version
);
637 void ScCeil( bool bODFF
);
639 void ScCeil_Precise();
640 void ScFloor( bool bODFF
);
642 void ScFloor_Precise();
643 void RoundNumber( rtl_math_RoundingMode eMode
);
647 void ScGetDateValue();
648 void ScGetTimeValue();
653 void ScGetDiffDate();
654 void ScGetDiffDate360();
669 void ScEuroConvert();
671 // financial functions
677 static double ScGetBw(double fZins
, double fZzr
, double fRmz
,
678 double fZw
, double fF
);
681 static double ScGetGDA(double fWert
, double fRest
, double fDauer
,
682 double fPeriode
, double fFactor
);
685 static double ScInterVDB(double fWert
,double fRest
,double fDauer
,double fDauer1
,
686 double fPeriode
,double fFactor
);
690 static double ScGetRmz(double fZins
, double fZzr
, double fBw
,
691 double fZw
, double fF
);
694 static double ScGetZw(double fZins
, double fZzr
, double fRmz
,
695 double fBw
, double fF
);
698 static bool RateIteration(double fNper
, double fPayment
, double fPv
,
699 double fFv
, double fPayType
, double& fGuess
);
701 double ScGetCompoundInterest(double fZins
, double fZr
, double fZzr
, double fBw
,
702 double fZw
, double fF
, double& fRmz
);
711 static double ScGetGCD(double fx
, double fy
);
717 static void MEMat(const ScMatrixRef
& mM
, SCSIZE n
);
724 ScMatrixRef
MatConcat(const ScMatrixRef
& pMat1
, const ScMatrixRef
& pMat2
);
730 bool CalculateSkew(double& fSum
,double& fCount
,double& vSum
,std::vector
<double>& values
);
731 void CalculateSkewOrSkewp( bool bSkewp
);
732 void CalculateSlopeIntercept(bool bSlope
);
733 void CalculateSmallLarge(bool bSmall
);
734 void CalculatePearsonCovar( bool _bPearson
, bool _bStexy
, bool _bSample
); //fdo#70000 argument _bSample is ignored if _bPearson == true
735 bool CalculateTest( bool _bTemplin
736 ,const SCSIZE nC1
, const SCSIZE nC2
,const SCSIZE nR1
,const SCSIZE nR2
737 ,const ScMatrixRef
& pMat1
,const ScMatrixRef
& pMat2
738 ,double& fT
,double& fF
);
739 void CalculateLookup(bool bHLookup
);
740 bool FillEntry(ScQueryEntry
& rEntry
);
741 void CalculateAddSub(bool _bSub
);
742 void CalculateTrendGrowth(bool _bGrowth
);
743 void CalculateRGPRKP(bool _bRKP
);
744 void CalculateSumX2MY2SumX2DY2(bool _bSumX2DY2
);
745 void CalculateMatrixValue(const ScMatrix
* pMat
,SCSIZE nC
,SCSIZE nR
);
746 bool CheckMatrix(bool _bLOG
,sal_uInt8
& nCase
,SCSIZE
& nCX
,SCSIZE
& nCY
,SCSIZE
& nRX
,SCSIZE
& nRY
,SCSIZE
& M
,SCSIZE
& N
,ScMatrixRef
& pMatX
,ScMatrixRef
& pMatY
);
753 static double taylor(const double* pPolynom
, sal_uInt16 nMax
, double x
);
754 static double gauss(double x
);
757 static SC_DLLPUBLIC
double phi(double x
);
758 static SC_DLLPUBLIC
double integralPhi(double x
);
759 static SC_DLLPUBLIC
double gaussinv(double x
);
762 double GetBetaDist(double x
, double alpha
, double beta
); //cumulative distribution function
763 double GetBetaDistPDF(double fX
, double fA
, double fB
); //probability density function)
764 double GetChiDist(double fChi
, double fDF
); // for LEGACY.CHIDIST, returns right tail
765 double GetChiSqDistCDF(double fX
, double fDF
); // for CHISQDIST, returns left tail
766 static double GetChiSqDistPDF(double fX
, double fDF
); // probability density function
767 double GetFDist(double x
, double fF1
, double fF2
);
768 double GetTDist( double T
, double fDF
, int nType
);
769 double Fakultaet(double x
);
770 static double BinomKoeff(double n
, double k
);
771 double GetGamma(double x
);
772 static double GetLogGamma(double x
);
773 double GetBeta(double fAlpha
, double fBeta
);
774 static double GetLogBeta(double fAlpha
, double fBeta
);
775 double GetBinomDistPMF(double x
, double n
, double p
); //probability mass function
776 double GetHypGeomDist( double x
, double n
, double M
, double N
);
781 void ScStdNormDist();
782 void ScStdNormDist_MS();
786 void ScNormDist( int nMinParamCount
);
787 void ScGammaDist( int nMinParamCount
);
791 void ScPoissonDist();
795 void ScPermutationA();
797 void ScHypGeomDist();
798 void ScHypGeomDist_MS();
799 void ScLogNormDist( int nMinParamCount
);
803 void ScTDist_T( int nTails
);
806 void ScChiDist(); // for LEGACY.CHIDIST, returns right tail
807 void ScChiSqDist(); // returns left tail or density
808 void ScChiSqDist_MS();
809 void ScChiSqInv(); //invers to CHISQDIST
812 void ScBetaDist_MS();
815 void ScTInv( int nType
);
819 void ScNegBinomDist();
820 void ScNegBinomDist_MS();
828 double GetMedian( ::std::vector
<double> & rArray
);
829 double GetPercentile( ::std::vector
<double> & rArray
, double fPercentile
);
830 double GetPercentileExclusive( ::std::vector
<double> & rArray
, double fPercentile
);
831 void GetNumberSequenceArray( sal_uInt8 nParamCount
, ::std::vector
<double>& rArray
, bool bConvertTextInArray
);
832 void GetSortArray( sal_uInt8 nParamCount
, ::std::vector
<double>& rSortArray
, ::std::vector
<long>* pIndexOrder
, bool bConvertTextInArray
, bool bAllowEmptyArray
);
833 static void QuickSort(::std::vector
<double>& rSortArray
, ::std::vector
<long>* pIndexOrder
= NULL
);
835 void ScModalValue_Multi();
843 void ScRank( bool bAverage
);
844 void ScPercentile( bool bInclusive
);
845 void ScPercentrank( bool bInclusive
);
846 static double GetPercentrank( ::std::vector
<double> & rArray
, double fVal
, bool bInclusive
);
850 void ScQuartile( bool bInclusive
);
854 void ScConfidenceT();
856 void ScProbability();
858 void ScCovarianceP();
859 void ScCovarianceS();
878 static const double fMaxGammaArgument
;
880 double GetGammaContFraction(double fA
,double fX
);
881 double GetGammaSeries(double fA
,double fX
);
882 double GetLowRegIGamma(double fA
,double fX
); // lower regularized incomplete gamma function, GAMMAQ
883 double GetUpRegIGamma(double fA
,double fX
); // upper regularized incomplete gamma function, GAMMAP
884 // probability density function; fLambda is "scale" parameter
885 double GetGammaDistPDF(double fX
, double fAlpha
, double fLambda
);
886 // cumulative distribution function; fLambda is "scale" parameter
887 double GetGammaDist(double fX
, double fAlpha
, double fLambda
);
888 double GetTInv( double fAlpha
, double fSize
, int nType
);
891 ScInterpreter( ScFormulaCell
* pCell
, ScDocument
* pDoc
,
892 const ScAddress
&, ScTokenArray
& );
895 formula::StackVar
Interpret();
897 void SetError(sal_uInt16 nError
)
898 { if (nError
&& !nGlobalError
) nGlobalError
= nError
; }
900 sal_uInt16
GetError() const { return nGlobalError
; }
901 formula::StackVar
GetResultType() const { return xResult
->GetType(); }
902 svl::SharedString
GetStringResult() const;
903 double GetNumResult() const { return xResult
->GetDouble(); }
904 formula::FormulaTokenRef
GetResultToken() const { return xResult
; }
905 short GetRetFormatType() const { return nRetFmtType
; }
906 sal_uLong
GetRetFormatIndex() const { return nRetFmtIndex
; }
909 inline void ScInterpreter::MatrixDoubleRefToMatrix()
911 if ( (bMatrixFormula
|| pCur
->HasForceArray()) && GetStackType() == formula::svDoubleRef
)
913 GetTokenMatrixMap(); // make sure it exists, create if not.
914 PopDoubleRefPushMatrix();
918 inline bool ScInterpreter::MatrixParameterConversion()
920 if ( (bMatrixFormula
|| pCur
->HasForceArray() || ScParameterClassification::HasForceArray( pCur
->GetOpCode())) &&
921 !pJumpMatrix
&& sp
> 0 )
922 return ConvertMatrixParameters();
926 inline ScTokenMatrixMap
& ScInterpreter::GetTokenMatrixMap()
928 if (!pTokenMatrixMap
)
929 pTokenMatrixMap
= CreateTokenMatrixMap();
930 return *pTokenMatrixMap
;
933 inline bool ScInterpreter::MustHaveParamCount( short nAct
, short nMust
)
938 PushParameterExpected();
940 PushIllegalParameter();
944 inline bool ScInterpreter::MustHaveParamCount( short nAct
, short nMust
, short nMax
)
946 if ( nMust
<= nAct
&& nAct
<= nMax
)
949 PushParameterExpected();
951 PushIllegalParameter();
955 inline bool ScInterpreter::MustHaveParamCountMin( short nAct
, short nMin
)
959 PushParameterExpected();
963 inline bool ScInterpreter::CheckStringPositionArgument( double & fVal
)
965 if (!rtl::math::isFinite( fVal
))
975 else if (fVal
> SAL_MAX_UINT16
)
977 fVal
= static_cast<double>(SAL_MAX_UINT16
);
983 inline double ScInterpreter::GetStringPositionArgument()
985 double fVal
= rtl::math::approxFloor( GetDouble());
986 if (!CheckStringPositionArgument( fVal
))
993 inline bool ScInterpreter::CheckStringResultLen( OUString
& rResult
, const OUString
& rAdd
)
995 if ( rResult
.getLength() + rAdd
.getLength() > SAL_MAX_UINT16
)
997 SetError( errStringOverflow
);
1004 inline void ScInterpreter::TreatDoubleError( double& rVal
)
1006 if ( !::rtl::math::isFinite( rVal
) )
1008 sal_uInt16 nErr
= GetDoubleErrorValue( rVal
);
1012 SetError( errNoValue
);
1017 inline double ScInterpreter::div( const double& fNumerator
, const double& fDenominator
)
1019 return sc::div(fNumerator
, fDenominator
);
1022 inline sal_Int16
ScInterpreter::GetDayOfWeek( sal_Int32 n
)
1023 { // monday = 0, ..., sunday = 6
1024 return static_cast< sal_Int16
>( ( n
- 1 ) % 7 );
1029 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */