1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: analysis.cxx,v $
10 * $Revision: 1.46.20.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "analysis.hxx"
33 #include <cppuhelper/factory.hxx>
34 #include <osl/diagnose.h>
35 #include <rtl/ustrbuf.hxx>
36 #include <rtl/math.hxx>
39 #include <tools/resmgr.hxx>
40 #include <tools/rcid.h>
41 #include "analysis.hrc"
44 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
45 #define MY_SERVICE "com.sun.star.sheet.addin.Analysis"
46 #define MY_IMPLNAME "com.sun.star.sheet.addin.AnalysisImpl"
48 using namespace ::rtl
;
49 using namespace ::com::sun::star
;
51 //------------------------------------------------------------------
53 // entry points for service registration / instantiation
55 //------------------------------------------------------------------
60 void SAL_CALL
component_getImplementationEnvironment( const sal_Char
** ppEnvTypeName
, uno_Environment
** /*ppEnv*/ )
62 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
66 sal_Bool SAL_CALL
component_writeInfo( void* /*pServiceManager*/, registry::XRegistryKey
* pRegistryKey
)
72 STRING aImpl
= STRFROMASCII( "/" );
73 aImpl
+= AnalysisAddIn::getImplementationName_Static();
74 aImpl
+= STRFROMASCII( "/UNO/SERVICES" );
76 REF( registry::XRegistryKey
) xNewKey(
77 reinterpret_cast< registry::XRegistryKey
* >( pRegistryKey
)->createKey( aImpl
) );
79 SEQ( STRING
) aSequ
= AnalysisAddIn::getSupportedServiceNames_Static();
80 const STRING
* pArray
= aSequ
.getConstArray();
82 for( sal_Int32 i
= 0 ; i
< aSequ
.getLength() ; i
++ )
83 xNewKey
->createKey( pArray
[ i
] );
87 catch( registry::InvalidRegistryException
& )
89 OSL_ENSURE( sal_False
, "### InvalidRegistryException!" );
96 void* SAL_CALL
component_getFactory( const sal_Char
* pImplName
, void* pServiceManager
, void* /*pRegistryKey*/ )
100 if( pServiceManager
&& STRING::createFromAscii( pImplName
) == AnalysisAddIn::getImplementationName_Static() )
102 REF( lang::XSingleServiceFactory
) xFactory( cppu::createOneInstanceFactory(
103 reinterpret_cast< lang::XMultiServiceFactory
* >( pServiceManager
),
104 AnalysisAddIn::getImplementationName_Static(),
105 AnalysisAddIn_CreateInstance
,
106 AnalysisAddIn::getSupportedServiceNames_Static() ) );
111 pRet
= xFactory
.get();
124 //------------------------------------------------------------------------
126 // "normal" service implementation
128 //------------------------------------------------------------------------
131 ResMgr
& AnalysisAddIn::GetResMgr( void ) THROWDEF_RTE
135 InitData(); // try to get resource manager
145 STRING
AnalysisAddIn::GetDisplFuncStr( sal_uInt16 nFuncNum
) THROWDEF_RTE
147 return String( AnalysisRscStrLoader( RID_ANALYSIS_FUNCTION_NAMES
, nFuncNum
, GetResMgr() ).GetString() );
151 class AnalysisResourcePublisher
: public Resource
154 AnalysisResourcePublisher( const AnalysisResId
& rId
) : Resource( rId
) {}
155 BOOL
IsAvailableRes( const ResId
& rId
) const { return Resource::IsAvailableRes( rId
); }
156 void FreeResource() { Resource::FreeResource(); }
160 class AnalysisFuncRes
: public Resource
163 AnalysisFuncRes( ResId
& rRes
, ResMgr
& rResMgr
, sal_uInt16 nInd
, STRING
& rRet
);
167 AnalysisFuncRes::AnalysisFuncRes( ResId
& rRes
, ResMgr
& rResMgr
, sal_uInt16 nInd
, STRING
& rRet
) : Resource( rRes
)
169 rRet
= String( AnalysisResId( nInd
, rResMgr
) );
175 STRING
AnalysisAddIn::GetFuncDescrStr( sal_uInt16 nResId
, sal_uInt16 nStrIndex
) THROWDEF_RTE
178 AnalysisResourcePublisher
aResPubl( AnalysisResId( RID_ANALYSIS_FUNCTION_DESCRIPTIONS
, GetResMgr() ) );
179 AnalysisResId
aRes( nResId
, GetResMgr() );
180 aRes
.SetRT( RSC_RESOURCE
);
181 if( aResPubl
.IsAvailableRes( aRes
) )
183 AnalysisFuncRes
aSubRes( aRes
, GetResMgr(), nStrIndex
, aRet
);
186 aResPubl
.FreeResource();
192 void AnalysisAddIn::InitData( void )
197 OString
aModName( "analysis" );
198 pResMgr
= ResMgr::CreateResMgr( ( const sal_Char
* ) aModName
,
205 pFD
= new FuncDataList( *pResMgr
);
217 AnalysisAddIn::AnalysisAddIn( const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
) :
220 pFactDoubles( NULL
),
223 aAnyConv( xServiceFact
)
228 AnalysisAddIn::~AnalysisAddIn()
234 delete[] pFactDoubles
;
239 // if( pResMgr ) no delete, because _all_ resource managers are deleted _before_ this dtor is called
243 delete[] pDefLocales
;
247 sal_Int32
AnalysisAddIn::getDateMode(
248 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
249 const uno::Any
& rAny
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
251 sal_Int32 nMode
= aAnyConv
.getInt32( xPropSet
, rAny
, 0 );
252 if( (nMode
< 0) || (nMode
> 4) )
253 throw lang::IllegalArgumentException();
259 //-----------------------------------------------------------------------------
262 #define MAXFACTDOUBLE 300
264 double AnalysisAddIn::FactDouble( sal_Int32 nNum
) THROWDEF_RTE_IAE
266 if( nNum
< 0 || nNum
> MAXFACTDOUBLE
)
271 pFactDoubles
= new double[ MAXFACTDOUBLE
+ 1 ];
273 pFactDoubles
[ 0 ] = 1.0; // by default
278 pFactDoubles
[ 1 ] = fOdd
;
279 pFactDoubles
[ 2 ] = fEven
;
281 sal_Bool bOdd
= sal_True
;
283 for( sal_uInt16 nCnt
= 3 ; nCnt
<= MAXFACTDOUBLE
; nCnt
++ )
288 pFactDoubles
[ nCnt
] = fOdd
;
293 pFactDoubles
[ nCnt
] = fEven
;
301 return pFactDoubles
[ nNum
];
305 STRING
AnalysisAddIn::getImplementationName_Static()
307 return STRFROMASCII( MY_IMPLNAME
);
311 SEQ( STRING
) AnalysisAddIn::getSupportedServiceNames_Static()
313 SEQ( STRING
) aRet(2);
314 STRING
* pArray
= aRet
.getArray();
315 pArray
[0] = STRFROMASCII( ADDIN_SERVICE
);
316 pArray
[1] = STRFROMASCII( MY_SERVICE
);
321 REF( uno::XInterface
) SAL_CALL
AnalysisAddIn_CreateInstance(
322 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
)
324 static uno::Reference
< uno::XInterface
> xInst
= (cppu::OWeakObject
*) new AnalysisAddIn( xServiceFact
);
331 STRING SAL_CALL
AnalysisAddIn::getServiceName() THROWDEF_RTE
333 // name of specific AddIn service
334 return STRFROMASCII( MY_SERVICE
);
340 STRING SAL_CALL
AnalysisAddIn::getImplementationName() THROWDEF_RTE
342 return getImplementationName_Static();
346 sal_Bool SAL_CALL
AnalysisAddIn::supportsService( const STRING
& aName
) THROWDEF_RTE
348 return aName
.compareToAscii( ADDIN_SERVICE
) == 0 || aName
.compareToAscii( MY_SERVICE
) == 0;
352 SEQ( STRING
) SAL_CALL
AnalysisAddIn::getSupportedServiceNames() THROWDEF_RTE
354 return getSupportedServiceNames_Static();
360 void SAL_CALL
AnalysisAddIn::setLocale( const lang::Locale
& eLocale
) THROWDEF_RTE
364 InitData(); // change of locale invalidates resources!
367 lang::Locale SAL_CALL
AnalysisAddIn::getLocale() THROWDEF_RTE
375 STRING SAL_CALL
AnalysisAddIn::getProgrammaticFuntionName( const STRING
& ) THROWDEF_RTE
378 // (but should be implemented for other uses of the AddIn service)
384 STRING SAL_CALL
AnalysisAddIn::getDisplayFunctionName( const STRING
& aProgrammaticName
) THROWDEF_RTE
388 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
391 aRet
= GetDisplFuncStr( p
->GetUINameID() );
393 aRet
+= STRFROMANSI( "_ADD" );
397 aRet
= STRFROMANSI( "UNKNOWNFUNC_" );
398 aRet
+= aProgrammaticName
;
405 STRING SAL_CALL
AnalysisAddIn::getFunctionDescription( const STRING
& aProgrammaticName
) THROWDEF_RTE
409 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
411 aRet
= GetFuncDescrStr( p
->GetDescrID(), 1 );
417 STRING SAL_CALL
AnalysisAddIn::getDisplayArgumentName( const STRING
& aName
, sal_Int32 nArg
) THROWDEF_RTE
421 const FuncData
* p
= pFD
->Get( aName
);
422 if( p
&& nArg
<= 0xFFFF )
424 sal_uInt16 nStr
= p
->GetStrIndex( sal_uInt16( nArg
) );
425 if( nStr
/*&& nStr < 4*/ )
426 aRet
= GetFuncDescrStr( p
->GetDescrID(), nStr
);
428 aRet
= STRFROMANSI( "internal" );
435 STRING SAL_CALL
AnalysisAddIn::getArgumentDescription( const STRING
& aName
, sal_Int32 nArg
) THROWDEF_RTE
439 const FuncData
* p
= pFD
->Get( aName
);
440 if( p
&& nArg
<= 0xFFFF )
442 sal_uInt16 nStr
= p
->GetStrIndex( sal_uInt16( nArg
) );
443 if( nStr
/*&& nStr < 4*/ )
444 aRet
= GetFuncDescrStr( p
->GetDescrID(), nStr
+ 1 );
446 aRet
= STRFROMANSI( "for internal use only" );
453 static const char* pDefCatName
= "Add-In";
456 STRING SAL_CALL
AnalysisAddIn::getProgrammaticCategoryName( const STRING
& aName
) THROWDEF_RTE
458 // return non-translated strings
459 // return STRFROMASCII( "Add-In" );
460 const FuncData
* p
= pFD
->Get( aName
);
464 const sal_Char
* pStr
;
466 switch( p
->GetCategory() )
468 case FDCat_DateTime
: pStr
= "Date&Time"; break;
469 case FDCat_Finance
: pStr
= "Financial"; break;
470 case FDCat_Inf
: pStr
= "Information"; break;
471 case FDCat_Math
: pStr
= "Mathematical"; break;
472 case FDCat_Tech
: pStr
= "Technical"; break;
474 pStr
= pDefCatName
; break;
477 aRet
= STRFROMASCII( pStr
);
480 aRet
= STRFROMASCII( pDefCatName
);
486 STRING SAL_CALL
AnalysisAddIn::getDisplayCategoryName( const STRING
& aProgrammaticFunctionName
) THROWDEF_RTE
488 // return translated strings, not used for predefined categories
489 // return STRFROMASCII( "Add-In" );
490 const FuncData
* p
= pFD
->Get( aProgrammaticFunctionName
);
494 const sal_Char
* pStr
;
496 switch( p
->GetCategory() )
498 case FDCat_DateTime
: pStr
= "Date&Time"; break;
499 case FDCat_Finance
: pStr
= "Financial"; break;
500 case FDCat_Inf
: pStr
= "Information"; break;
501 case FDCat_Math
: pStr
= "Mathematical"; break;
502 case FDCat_Tech
: pStr
= "Technical"; break;
504 pStr
= pDefCatName
; break;
507 aRet
= STRFROMASCII( pStr
);
510 aRet
= STRFROMASCII( pDefCatName
);
516 static const sal_Char
* pLang
[] = { "de", "en" };
517 static const sal_Char
* pCoun
[] = { "DE", "US" };
518 static const sal_uInt32 nNumOfLoc
= sizeof( pLang
) / sizeof( sal_Char
* );
521 void AnalysisAddIn::InitDefLocales( void )
523 pDefLocales
= new CSS::lang::Locale
[ nNumOfLoc
];
525 for( sal_uInt32 n
= 0 ; n
< nNumOfLoc
; n
++ )
527 pDefLocales
[ n
].Language
= STRING::createFromAscii( pLang
[ n
] );
528 pDefLocales
[ n
].Country
= STRING::createFromAscii( pCoun
[ n
] );
533 inline const CSS::lang::Locale
& AnalysisAddIn::GetLocale( sal_uInt32 nInd
)
538 if( nInd
< sizeof( pLang
) )
539 return pDefLocales
[ nInd
];
545 SEQofLocName SAL_CALL
AnalysisAddIn::getCompatibilityNames( const STRING
& aProgrammaticName
) THROWDEF_RTE
547 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
550 return SEQofLocName( 0 );
552 const StringList
& r
= p
->GetCompNameList();
553 sal_uInt32 nCount
= r
.Count();
555 SEQofLocName
aRet( nCount
);
557 CSS::sheet::LocalizedName
* pArray
= aRet
.getArray();
559 for( sal_uInt32 n
= 0 ; n
< nCount
; n
++ )
561 pArray
[ n
] = CSS::sheet::LocalizedName( GetLocale( n
), *r
.Get( n
) );
570 /*double SAL_CALL AnalysisAddIn::get_Test( constREFXPS&,
571 sal_Int32 nMode, double f1, double f2, double f3 ) THROWDEF_RTE
573 return _Test( nMode, f1, f2, f3 );
581 sal_Int32 SAL_CALL
AnalysisAddIn::getWorkday( constREFXPS
& xOptions
,
582 sal_Int32 nDate
, sal_Int32 nDays
, const ANY
& aHDay
) THROWDEF_RTE_IAE
587 sal_Int32 nNullDate
= GetNullDate( xOptions
);
589 SortedIndividualInt32List aSrtLst
;
591 aSrtLst
.InsertHolidayList( aAnyConv
, xOptions
, aHDay
, nNullDate
, sal_False
);
593 sal_Int32 nActDate
= nDate
+ nNullDate
;
597 if( GetDayOfWeek( nActDate
) == 5 )
598 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
605 if( GetDayOfWeek( nActDate
) < 5 )
607 if( !aSrtLst
.Find( nActDate
) )
611 nActDate
++; // jump over weekend
616 if( GetDayOfWeek( nActDate
) == 6 )
617 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
624 if( GetDayOfWeek( nActDate
) < 5 )
626 if( !aSrtLst
.Find( nActDate
) )
630 nActDate
--; // jump over weekend
634 return nActDate
- nNullDate
;
642 double SAL_CALL
AnalysisAddIn::getYearfrac( constREFXPS
& xOpt
,
643 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const ANY
& rMode
) THROWDEF_RTE_IAE
645 double fRet
= GetYearFrac( xOpt
, nStartDate
, nEndDate
, getDateMode( xOpt
, rMode
) );
646 RETURN_FINITE( fRet
);
650 sal_Int32 SAL_CALL
AnalysisAddIn::getEdate( constREFXPS
& xOpt
, sal_Int32 nStartDate
, sal_Int32 nMonths
) THROWDEF_RTE_IAE
652 sal_Int32 nNullDate
= GetNullDate( xOpt
);
653 ScaDate
aDate( nNullDate
, nStartDate
, 5 );
654 aDate
.addMonths( nMonths
);
655 return aDate
.getDate( nNullDate
);
659 sal_Int32 SAL_CALL
AnalysisAddIn::getWeeknum( constREFXPS
& xOpt
, sal_Int32 nDate
, sal_Int32 nMode
) THROWDEF_RTE_IAE
661 nDate
+= GetNullDate( xOpt
);
663 sal_uInt16 nDay
, nMonth
, nYear
;
664 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
666 sal_Int32 nFirstInYear
= DateToDays( 1, 1, nYear
);
667 sal_uInt16 nFirstDayInYear
= GetDayOfWeek( nFirstInYear
);
669 return ( nDate
- nFirstInYear
+ ( ( nMode
== 1 )? ( nFirstDayInYear
+ 1 ) % 7 : nFirstDayInYear
) ) / 7 + 1;
673 sal_Int32 SAL_CALL
AnalysisAddIn::getEomonth( constREFXPS
& xOpt
, sal_Int32 nDate
, sal_Int32 nMonths
) THROWDEF_RTE_IAE
675 sal_Int32 nNullDate
= GetNullDate( xOpt
);
677 sal_uInt16 nDay
, nMonth
, nYear
;
678 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
680 sal_Int32 nNewMonth
= nMonth
+ nMonths
;
684 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
+ ( nNewMonth
/ 12 ) );
687 else if( nNewMonth
< 1 )
689 nNewMonth
= -nNewMonth
;
690 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
- ( nNewMonth
/ 12 ) );
693 nNewMonth
= 12 - nNewMonth
;
696 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth
), nYear
), sal_uInt16( nNewMonth
), nYear
) - nNullDate
;
700 sal_Int32 SAL_CALL
AnalysisAddIn::getNetworkdays( constREFXPS
& xOpt
,
701 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const ANY
& aHDay
) THROWDEF_RTE_IAE
703 sal_Int32 nNullDate
= GetNullDate( xOpt
);
705 SortedIndividualInt32List aSrtLst
;
707 aSrtLst
.InsertHolidayList( aAnyConv
, xOpt
, aHDay
, nNullDate
, sal_False
);
709 sal_Int32 nActDate
= nStartDate
+ nNullDate
;
710 sal_Int32 nStopDate
= nEndDate
+ nNullDate
;
713 if( nActDate
<= nStopDate
)
715 while( nActDate
<= nStopDate
)
717 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
725 while( nActDate
>= nStopDate
)
727 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
738 sal_Int32 SAL_CALL
AnalysisAddIn::getIseven( sal_Int32 nVal
) THROWDEF_RTE_IAE
740 return ( nVal
& 0x00000001 )? 0 : 1;
744 sal_Int32 SAL_CALL
AnalysisAddIn::getIsodd( sal_Int32 nVal
) THROWDEF_RTE_IAE
746 return ( nVal
& 0x00000001 )? 1 : 0;
750 AnalysisAddIn::getMultinomial( constREFXPS
& xOpt
, const SEQSEQ( sal_Int32
)& aVLst
,
751 const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
753 ScaDoubleListGE0 aValList
;
755 aValList
.Append( aVLst
);
756 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
758 if( aValList
.Count() == 0 )
764 for( const double *p
= aValList
.First(); p
; p
= aValList
.Next() )
766 double fInt
= (*p
>= 0.0) ? rtl::math::approxFloor( *p
) : rtl::math::approxCeil( *p
);
767 if ( fInt
< 0.0 || fInt
> 170.0 )
769 sal_Int32 n
= static_cast< sal_Int32
>( fInt
);
780 double fRet
= Fak( nZ
) / fN
;
781 RETURN_FINITE( fRet
);
785 double SAL_CALL
AnalysisAddIn::getSeriessum( double fX
, double fN
, double fM
, const SEQSEQ( double )& aCoeffList
) THROWDEF_RTE_IAE
789 // #i32269# 0^0 is undefined, Excel returns #NUM! error
790 if( fX
== 0.0 && fN
== 0 )
796 sal_Int32 nE1
= aCoeffList
.getLength();
800 for( n1
= 0 ; n1
< nE1
; n1
++ )
802 const SEQ( double )& rList
= aCoeffList
[ n1
];
803 nE2
= rList
.getLength();
804 const double* pList
= rList
.getConstArray();
806 for( n2
= 0 ; n2
< nE2
; n2
++ )
808 fRet
+= pList
[ n2
] * pow( fX
, fN
);
815 RETURN_FINITE( fRet
);
819 double SAL_CALL
AnalysisAddIn::getQuotient( double fNum
, double fDenom
) THROWDEF_RTE_IAE
822 if( (fNum
< 0) != (fDenom
< 0) )
823 fRet
= ::rtl::math::approxCeil( fNum
/ fDenom
);
825 fRet
= ::rtl::math::approxFloor( fNum
/ fDenom
);
826 RETURN_FINITE( fRet
);
830 double SAL_CALL
AnalysisAddIn::getMround( double fNum
, double fMult
) THROWDEF_RTE_IAE
835 double fRet
= fMult
* ::rtl::math::round( fNum
/ fMult
);
836 RETURN_FINITE( fRet
);
840 double SAL_CALL
AnalysisAddIn::getSqrtpi( double fNum
) THROWDEF_RTE_IAE
842 double fRet
= sqrt( fNum
* PI
);
843 RETURN_FINITE( fRet
);
847 double SAL_CALL
AnalysisAddIn::getRandbetween( double fMin
, double fMax
) THROWDEF_RTE_IAE
849 fMin
= ::rtl::math::round( fMin
, 0, rtl_math_RoundingMode_Up
);
850 fMax
= ::rtl::math::round( fMax
, 0, rtl_math_RoundingMode_Up
);
855 double fRet
= fMax
- fMin
+ 1.0;
857 fRet
/= (RAND_MAX
+ 1.0);
859 fRet
= floor( fRet
); // simple floor is sufficient here
860 RETURN_FINITE( fRet
);
864 double SAL_CALL
AnalysisAddIn::getGcd( constREFXPS
& xOpt
, const SEQSEQ( double )& aVLst
, const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
866 ScaDoubleListGT0 aValList
;
868 aValList
.Append( aVLst
);
869 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
871 if( aValList
.Count() == 0 )
874 const double* p
= aValList
.First();
889 double SAL_CALL
AnalysisAddIn::getLcm( constREFXPS
& xOpt
, const SEQSEQ( double )& aVLst
, const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
891 ScaDoubleListGE0 aValList
;
893 aValList
.Append( aVLst
);
894 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
896 if( aValList
.Count() == 0 )
899 const double* p
= aValList
.First();
913 f
= fTmp
* f
/ GetGcd( fTmp
, f
);
921 double SAL_CALL
AnalysisAddIn::getBesseli( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE
923 double fRet
= sca::analysis::BesselI( fNum
, nOrder
);
924 RETURN_FINITE( fRet
);
928 double SAL_CALL
AnalysisAddIn::getBesselj( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE
930 double fRet
= sca::analysis::BesselJ( fNum
, nOrder
);
931 RETURN_FINITE( fRet
);
935 double SAL_CALL
AnalysisAddIn::getBesselk( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE
937 if( nOrder
< 0 || fNum
<= 0.0 )
940 double fRet
= sca::analysis::BesselK( fNum
, nOrder
);
941 RETURN_FINITE( fRet
);
945 double SAL_CALL
AnalysisAddIn::getBessely( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE
947 if( nOrder
< 0 || fNum
<= 0.0 )
950 // return yn( nOrder, fNum );
951 double fRet
= sca::analysis::BesselY( fNum
, nOrder
);
952 RETURN_FINITE( fRet
);
956 const double SCA_MAX2
= 511.0; // min. val for binary numbers (9 bits + sign)
957 const double SCA_MIN2
= -SCA_MAX2
-1.0; // min. val for binary numbers (9 bits + sign)
958 const double SCA_MAX8
= 536870911.0; // max. val for octal numbers (29 bits + sign)
959 const double SCA_MIN8
= -SCA_MAX8
-1.0; // min. val for octal numbers (29 bits + sign)
960 const double SCA_MAX16
= 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
961 const double SCA_MIN16
= -SCA_MAX16
-1.0; // min. val for hexadecimal numbers (39 bits + sign)
962 const sal_Int32 SCA_MAXPLACES
= 10; // max. number of places
965 STRING SAL_CALL
AnalysisAddIn::getBin2Oct( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
967 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
968 sal_Int32 nPlaces
= 0;
969 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
970 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
974 double SAL_CALL
AnalysisAddIn::getBin2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
976 double fRet
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
977 RETURN_FINITE( fRet
);
981 STRING SAL_CALL
AnalysisAddIn::getBin2Hex( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
983 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
984 sal_Int32 nPlaces
= 0;
985 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
986 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
990 STRING SAL_CALL
AnalysisAddIn::getOct2Bin( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
992 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
993 sal_Int32 nPlaces
= 0;
994 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
995 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
999 double SAL_CALL
AnalysisAddIn::getOct2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
1001 double fRet
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
1002 RETURN_FINITE( fRet
);
1006 STRING SAL_CALL
AnalysisAddIn::getOct2Hex( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
1008 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
1009 sal_Int32 nPlaces
= 0;
1010 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1011 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1015 STRING SAL_CALL
AnalysisAddIn::getDec2Bin( constREFXPS
& xOpt
, sal_Int32 nNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
1017 sal_Int32 nPlaces
= 0;
1018 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1019 return ConvertFromDec( nNum
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1023 STRING SAL_CALL
AnalysisAddIn::getDec2Oct( constREFXPS
& xOpt
, sal_Int32 nNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
1025 sal_Int32 nPlaces
= 0;
1026 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1027 return ConvertFromDec( nNum
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1031 STRING SAL_CALL
AnalysisAddIn::getDec2Hex( constREFXPS
& xOpt
, double fNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
1033 sal_Int32 nPlaces
= 0;
1034 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1035 return ConvertFromDec( fNum
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1039 STRING SAL_CALL
AnalysisAddIn::getHex2Bin( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
1041 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
1042 sal_Int32 nPlaces
= 0;
1043 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1044 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1048 double SAL_CALL
AnalysisAddIn::getHex2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
1050 double fRet
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
1051 RETURN_FINITE( fRet
);
1055 STRING SAL_CALL
AnalysisAddIn::getHex2Oct( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
1057 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
1058 sal_Int32 nPlaces
= 0;
1059 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1060 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1064 sal_Int32 SAL_CALL
AnalysisAddIn::getDelta( constREFXPS
& xOpt
, double fNum1
, const ANY
& rNum2
) THROWDEF_RTE_IAE
1066 return fNum1
== aAnyConv
.getDouble( xOpt
, rNum2
, 0.0 );
1070 double SAL_CALL
AnalysisAddIn::getErf( constREFXPS
& xOpt
, double fLL
, const ANY
& rUL
) THROWDEF_RTE_IAE
1073 sal_Bool bContainsValue
= aAnyConv
.getDouble( fUL
, xOpt
, rUL
);
1075 fRet
= bContainsValue
? (Erf( fUL
) - Erf( fLL
)) : Erf( fLL
);
1076 RETURN_FINITE( fRet
);
1080 double SAL_CALL
AnalysisAddIn::getErfc( double f
) THROWDEF_RTE_IAE
1082 double fRet
= Erfc( f
);
1083 RETURN_FINITE( fRet
);
1087 sal_Int32 SAL_CALL
AnalysisAddIn::getGestep( constREFXPS
& xOpt
, double fNum
, const ANY
& rStep
) THROWDEF_RTE_IAE
1089 return fNum
>= aAnyConv
.getDouble( xOpt
, rStep
, 0.0 );
1093 double SAL_CALL
AnalysisAddIn::getFactdouble( sal_Int32 nNum
) THROWDEF_RTE_IAE
1095 double fRet
= FactDouble( nNum
);
1096 RETURN_FINITE( fRet
);
1100 double SAL_CALL
AnalysisAddIn::getImabs( const STRING
& aNum
) THROWDEF_RTE_IAE
1102 double fRet
= Complex( aNum
).Abs();
1103 RETURN_FINITE( fRet
);
1107 double SAL_CALL
AnalysisAddIn::getImaginary( const STRING
& aNum
) THROWDEF_RTE_IAE
1109 double fRet
= Complex( aNum
).Imag();
1110 RETURN_FINITE( fRet
);
1114 STRING SAL_CALL
AnalysisAddIn::getImpower( const STRING
& aNum
, double f
) THROWDEF_RTE_IAE
1120 return z
.GetString();
1124 double SAL_CALL
AnalysisAddIn::getImargument( const STRING
& aNum
) THROWDEF_RTE_IAE
1126 double fRet
= Complex( aNum
).Arg();
1127 RETURN_FINITE( fRet
);
1131 STRING SAL_CALL
AnalysisAddIn::getImcos( const STRING
& aNum
) THROWDEF_RTE_IAE
1137 return z
.GetString();
1141 STRING SAL_CALL
AnalysisAddIn::getImdiv( const STRING
& aDivid
, const STRING
& aDivis
) THROWDEF_RTE_IAE
1143 Complex
z( aDivid
);
1145 z
.Div( Complex( aDivis
) );
1147 return z
.GetString();
1151 STRING SAL_CALL
AnalysisAddIn::getImexp( const STRING
& aNum
) THROWDEF_RTE_IAE
1157 return z
.GetString();
1161 STRING SAL_CALL
AnalysisAddIn::getImconjugate( const STRING
& aNum
) THROWDEF_RTE_IAE
1167 return z
.GetString();
1171 STRING SAL_CALL
AnalysisAddIn::getImln( const STRING
& aNum
) THROWDEF_RTE_IAE
1177 return z
.GetString();
1181 STRING SAL_CALL
AnalysisAddIn::getImlog10( const STRING
& aNum
) THROWDEF_RTE_IAE
1187 return z
.GetString();
1191 STRING SAL_CALL
AnalysisAddIn::getImlog2( const STRING
& aNum
) THROWDEF_RTE_IAE
1197 return z
.GetString();
1201 STRING SAL_CALL
AnalysisAddIn::getImproduct( constREFXPS
&, const SEQSEQ( STRING
)& aNum1
, const SEQ( uno::Any
)& aNL
) THROWDEF_RTE_IAE
1205 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
1206 z_list
.Append( aNL
, AH_IgnoreEmpty
);
1208 const Complex
* p
= z_list
.First();
1211 return Complex( 0 ).GetString();
1215 for( p
= z_list
.Next() ; p
; p
= z_list
.Next() )
1218 return z
.GetString();
1222 double SAL_CALL
AnalysisAddIn::getImreal( const STRING
& aNum
) THROWDEF_RTE_IAE
1224 double fRet
= Complex( aNum
).Real();
1225 RETURN_FINITE( fRet
);
1229 STRING SAL_CALL
AnalysisAddIn::getImsin( const STRING
& aNum
) THROWDEF_RTE_IAE
1235 return z
.GetString();
1239 STRING SAL_CALL
AnalysisAddIn::getImsub( const STRING
& aNum1
, const STRING
& aNum2
) THROWDEF_RTE_IAE
1243 z
.Sub( Complex( aNum2
) );
1245 return z
.GetString();
1249 STRING SAL_CALL
AnalysisAddIn::getImsum( constREFXPS
&, const SEQSEQ( STRING
)& aNum1
, const SEQ( CSS::uno::Any
)& aFollowingPars
) THROWDEF_RTE_IAE
1253 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
1254 z_list
.Append( aFollowingPars
, AH_IgnoreEmpty
);
1256 const Complex
* p
= z_list
.First();
1259 return Complex( 0 ).GetString();
1263 for( p
= z_list
.Next() ; p
; p
= z_list
.Next() )
1266 return z
.GetString();
1270 STRING SAL_CALL
AnalysisAddIn::getImsqrt( const STRING
& aNum
) THROWDEF_RTE_IAE
1277 return z
.GetString();
1281 STRING SAL_CALL
AnalysisAddIn::getComplex( double fR
, double fI
, const ANY
& rSuff
) THROWDEF_RTE_IAE
1285 switch( rSuff
.getValueTypeClass() )
1287 case uno::TypeClass_VOID
:
1290 case uno::TypeClass_STRING
:
1292 const STRING
* pSuff
= ( const STRING
* ) rSuff
.getValue();
1293 bi
= pSuff
->compareToAscii( "i" ) == 0 || pSuff
->getLength() == 0;
1294 if( !bi
&& pSuff
->compareToAscii( "j" ) != 0 )
1302 return Complex( fR
, fI
, bi
? 'i' : 'j' ).GetString();
1306 double SAL_CALL
AnalysisAddIn::getConvert( double f
, const STRING
& aFU
, const STRING
& aTU
) THROWDEF_RTE_IAE
1309 pCDL
= new ConvertDataList();
1311 double fRet
= pCDL
->Convert( f
, aFU
, aTU
);
1312 RETURN_FINITE( fRet
);