1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include "analysis.hxx"
30 #include <cppuhelper/factory.hxx>
31 #include <osl/diagnose.h>
32 #include <rtl/ustrbuf.hxx>
33 #include <rtl/math.hxx>
36 #include <tools/resmgr.hxx>
37 #include <tools/rcid.h>
38 #include "analysis.hrc"
41 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
42 #define MY_SERVICE "com.sun.star.sheet.addin.Analysis"
43 #define MY_IMPLNAME "com.sun.star.sheet.addin.AnalysisImpl"
45 using namespace ::rtl
;
46 using namespace ::com::sun::star
;
48 //------------------------------------------------------------------
50 // entry points for service registration / instantiation
52 //------------------------------------------------------------------
57 void SAL_CALL
component_getImplementationEnvironment( const sal_Char
** ppEnvTypeName
, uno_Environment
** /*ppEnv*/ )
59 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
62 void* SAL_CALL
component_getFactory( const sal_Char
* pImplName
, void* pServiceManager
, void* /*pRegistryKey*/ )
66 if( pServiceManager
&& STRING::createFromAscii( pImplName
) == AnalysisAddIn::getImplementationName_Static() )
68 REF( lang::XSingleServiceFactory
) xFactory( cppu::createOneInstanceFactory(
69 reinterpret_cast< lang::XMultiServiceFactory
* >( pServiceManager
),
70 AnalysisAddIn::getImplementationName_Static(),
71 AnalysisAddIn_CreateInstance
,
72 AnalysisAddIn::getSupportedServiceNames_Static() ) );
77 pRet
= xFactory
.get();
90 //------------------------------------------------------------------------
92 // "normal" service implementation
94 //------------------------------------------------------------------------
97 ResMgr
& AnalysisAddIn::GetResMgr( void ) THROWDEF_RTE
101 InitData(); // try to get resource manager
111 STRING
AnalysisAddIn::GetDisplFuncStr( sal_uInt16 nFuncNum
) THROWDEF_RTE
113 return String( AnalysisRscStrLoader( RID_ANALYSIS_FUNCTION_NAMES
, nFuncNum
, GetResMgr() ).GetString() );
117 class AnalysisResourcePublisher
: public Resource
120 AnalysisResourcePublisher( const AnalysisResId
& rId
) : Resource( rId
) {}
121 sal_Bool
IsAvailableRes( const ResId
& rId
) const { return Resource::IsAvailableRes( rId
); }
122 void FreeResource() { Resource::FreeResource(); }
126 class AnalysisFuncRes
: public Resource
129 AnalysisFuncRes( ResId
& rRes
, ResMgr
& rResMgr
, sal_uInt16 nInd
, STRING
& rRet
);
133 AnalysisFuncRes::AnalysisFuncRes( ResId
& rRes
, ResMgr
& rResMgr
, sal_uInt16 nInd
, STRING
& rRet
) : Resource( rRes
)
135 rRet
= String( AnalysisResId( nInd
, rResMgr
) );
141 STRING
AnalysisAddIn::GetFuncDescrStr( sal_uInt16 nResId
, sal_uInt16 nStrIndex
) THROWDEF_RTE
144 AnalysisResourcePublisher
aResPubl( AnalysisResId( RID_ANALYSIS_FUNCTION_DESCRIPTIONS
, GetResMgr() ) );
145 AnalysisResId
aRes( nResId
, GetResMgr() );
146 aRes
.SetRT( RSC_RESOURCE
);
147 if( aResPubl
.IsAvailableRes( aRes
) )
149 AnalysisFuncRes
aSubRes( aRes
, GetResMgr(), nStrIndex
, aRet
);
152 aResPubl
.FreeResource();
158 void AnalysisAddIn::InitData( void )
163 OString
aModName( "analysis" );
164 pResMgr
= ResMgr::CreateResMgr( ( const sal_Char
* ) aModName
,
171 pFD
= new FuncDataList( *pResMgr
);
183 AnalysisAddIn::AnalysisAddIn( const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
) :
186 pFactDoubles( NULL
),
189 aAnyConv( xServiceFact
)
194 AnalysisAddIn::~AnalysisAddIn()
200 delete[] pFactDoubles
;
205 // if( pResMgr ) no delete, because _all_ resource managers are deleted _before_ this dtor is called
209 delete[] pDefLocales
;
213 sal_Int32
AnalysisAddIn::getDateMode(
214 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
215 const uno::Any
& rAny
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
217 sal_Int32 nMode
= aAnyConv
.getInt32( xPropSet
, rAny
, 0 );
218 if( (nMode
< 0) || (nMode
> 4) )
219 throw lang::IllegalArgumentException();
225 //-----------------------------------------------------------------------------
228 #define MAXFACTDOUBLE 300
230 double AnalysisAddIn::FactDouble( sal_Int32 nNum
) THROWDEF_RTE_IAE
232 if( nNum
< 0 || nNum
> MAXFACTDOUBLE
)
237 pFactDoubles
= new double[ MAXFACTDOUBLE
+ 1 ];
239 pFactDoubles
[ 0 ] = 1.0; // by default
244 pFactDoubles
[ 1 ] = fOdd
;
245 pFactDoubles
[ 2 ] = fEven
;
247 sal_Bool bOdd
= sal_True
;
249 for( sal_uInt16 nCnt
= 3 ; nCnt
<= MAXFACTDOUBLE
; nCnt
++ )
254 pFactDoubles
[ nCnt
] = fOdd
;
259 pFactDoubles
[ nCnt
] = fEven
;
267 return pFactDoubles
[ nNum
];
271 STRING
AnalysisAddIn::getImplementationName_Static()
273 return STRFROMASCII( MY_IMPLNAME
);
277 SEQ( STRING
) AnalysisAddIn::getSupportedServiceNames_Static()
279 SEQ( STRING
) aRet(2);
280 STRING
* pArray
= aRet
.getArray();
281 pArray
[0] = STRFROMASCII( ADDIN_SERVICE
);
282 pArray
[1] = STRFROMASCII( MY_SERVICE
);
287 REF( uno::XInterface
) SAL_CALL
AnalysisAddIn_CreateInstance(
288 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
)
290 static uno::Reference
< uno::XInterface
> xInst
= (cppu::OWeakObject
*) new AnalysisAddIn( xServiceFact
);
297 STRING SAL_CALL
AnalysisAddIn::getServiceName() THROWDEF_RTE
299 // name of specific AddIn service
300 return STRFROMASCII( MY_SERVICE
);
306 STRING SAL_CALL
AnalysisAddIn::getImplementationName() THROWDEF_RTE
308 return getImplementationName_Static();
312 sal_Bool SAL_CALL
AnalysisAddIn::supportsService( const STRING
& aName
) THROWDEF_RTE
314 return aName
.compareToAscii( ADDIN_SERVICE
) == 0 || aName
.compareToAscii( MY_SERVICE
) == 0;
318 SEQ( STRING
) SAL_CALL
AnalysisAddIn::getSupportedServiceNames() THROWDEF_RTE
320 return getSupportedServiceNames_Static();
326 void SAL_CALL
AnalysisAddIn::setLocale( const lang::Locale
& eLocale
) THROWDEF_RTE
330 InitData(); // change of locale invalidates resources!
333 lang::Locale SAL_CALL
AnalysisAddIn::getLocale() THROWDEF_RTE
341 STRING SAL_CALL
AnalysisAddIn::getProgrammaticFuntionName( const STRING
& ) THROWDEF_RTE
344 // (but should be implemented for other uses of the AddIn service)
350 STRING SAL_CALL
AnalysisAddIn::getDisplayFunctionName( const STRING
& aProgrammaticName
) THROWDEF_RTE
354 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
357 aRet
= GetDisplFuncStr( p
->GetUINameID() );
359 aRet
+= STRFROMANSI( "_ADD" );
363 aRet
= STRFROMANSI( "UNKNOWNFUNC_" );
364 aRet
+= aProgrammaticName
;
371 STRING SAL_CALL
AnalysisAddIn::getFunctionDescription( const STRING
& aProgrammaticName
) THROWDEF_RTE
375 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
377 aRet
= GetFuncDescrStr( p
->GetDescrID(), 1 );
383 STRING SAL_CALL
AnalysisAddIn::getDisplayArgumentName( const STRING
& aName
, sal_Int32 nArg
) THROWDEF_RTE
387 const FuncData
* p
= pFD
->Get( aName
);
388 if( p
&& nArg
<= 0xFFFF )
390 sal_uInt16 nStr
= p
->GetStrIndex( sal_uInt16( nArg
) );
391 if( nStr
/*&& nStr < 4*/ )
392 aRet
= GetFuncDescrStr( p
->GetDescrID(), nStr
);
394 aRet
= STRFROMANSI( "internal" );
401 STRING SAL_CALL
AnalysisAddIn::getArgumentDescription( const STRING
& aName
, sal_Int32 nArg
) THROWDEF_RTE
405 const FuncData
* p
= pFD
->Get( aName
);
406 if( p
&& nArg
<= 0xFFFF )
408 sal_uInt16 nStr
= p
->GetStrIndex( sal_uInt16( nArg
) );
409 if( nStr
/*&& nStr < 4*/ )
410 aRet
= GetFuncDescrStr( p
->GetDescrID(), nStr
+ 1 );
412 aRet
= STRFROMANSI( "for internal use only" );
419 static const char* pDefCatName
= "Add-In";
422 STRING SAL_CALL
AnalysisAddIn::getProgrammaticCategoryName( const STRING
& aName
) THROWDEF_RTE
424 // return non-translated strings
425 // return STRFROMASCII( "Add-In" );
426 const FuncData
* p
= pFD
->Get( aName
);
430 const sal_Char
* pStr
;
432 switch( p
->GetCategory() )
434 case FDCat_DateTime
: pStr
= "Date&Time"; break;
435 case FDCat_Finance
: pStr
= "Financial"; break;
436 case FDCat_Inf
: pStr
= "Information"; break;
437 case FDCat_Math
: pStr
= "Mathematical"; break;
438 case FDCat_Tech
: pStr
= "Technical"; break;
440 pStr
= pDefCatName
; break;
443 aRet
= STRFROMASCII( pStr
);
446 aRet
= STRFROMASCII( pDefCatName
);
452 STRING SAL_CALL
AnalysisAddIn::getDisplayCategoryName( const STRING
& aProgrammaticFunctionName
) THROWDEF_RTE
454 // return translated strings, not used for predefined categories
455 // return STRFROMASCII( "Add-In" );
456 const FuncData
* p
= pFD
->Get( aProgrammaticFunctionName
);
460 const sal_Char
* pStr
;
462 switch( p
->GetCategory() )
464 case FDCat_DateTime
: pStr
= "Date&Time"; break;
465 case FDCat_Finance
: pStr
= "Financial"; break;
466 case FDCat_Inf
: pStr
= "Information"; break;
467 case FDCat_Math
: pStr
= "Mathematical"; break;
468 case FDCat_Tech
: pStr
= "Technical"; break;
470 pStr
= pDefCatName
; break;
473 aRet
= STRFROMASCII( pStr
);
476 aRet
= STRFROMASCII( pDefCatName
);
482 static const sal_Char
* pLang
[] = { "de", "en" };
483 static const sal_Char
* pCoun
[] = { "DE", "US" };
484 static const sal_uInt32 nNumOfLoc
= sizeof( pLang
) / sizeof( sal_Char
* );
487 void AnalysisAddIn::InitDefLocales( void )
489 pDefLocales
= new CSS::lang::Locale
[ nNumOfLoc
];
491 for( sal_uInt32 n
= 0 ; n
< nNumOfLoc
; n
++ )
493 pDefLocales
[ n
].Language
= STRING::createFromAscii( pLang
[ n
] );
494 pDefLocales
[ n
].Country
= STRING::createFromAscii( pCoun
[ n
] );
499 inline const CSS::lang::Locale
& AnalysisAddIn::GetLocale( sal_uInt32 nInd
)
504 if( nInd
< sizeof( pLang
) )
505 return pDefLocales
[ nInd
];
511 SEQofLocName SAL_CALL
AnalysisAddIn::getCompatibilityNames( const STRING
& aProgrammaticName
) THROWDEF_RTE
513 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
516 return SEQofLocName( 0 );
518 const StringList
& r
= p
->GetCompNameList();
519 sal_uInt32 nCount
= r
.Count();
521 SEQofLocName
aRet( nCount
);
523 CSS::sheet::LocalizedName
* pArray
= aRet
.getArray();
525 for( sal_uInt32 n
= 0 ; n
< nCount
; n
++ )
527 pArray
[ n
] = CSS::sheet::LocalizedName( GetLocale( n
), *r
.Get( n
) );
536 /*double SAL_CALL AnalysisAddIn::get_Test( constREFXPS&,
537 sal_Int32 nMode, double f1, double f2, double f3 ) THROWDEF_RTE
539 return _Test( nMode, f1, f2, f3 );
547 sal_Int32 SAL_CALL
AnalysisAddIn::getWorkday( constREFXPS
& xOptions
,
548 sal_Int32 nDate
, sal_Int32 nDays
, const ANY
& aHDay
) THROWDEF_RTE_IAE
553 sal_Int32 nNullDate
= GetNullDate( xOptions
);
555 SortedIndividualInt32List aSrtLst
;
557 aSrtLst
.InsertHolidayList( aAnyConv
, xOptions
, aHDay
, nNullDate
, sal_False
);
559 sal_Int32 nActDate
= nDate
+ nNullDate
;
563 if( GetDayOfWeek( nActDate
) == 5 )
564 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
571 if( GetDayOfWeek( nActDate
) < 5 )
573 if( !aSrtLst
.Find( nActDate
) )
577 nActDate
++; // jump over weekend
582 if( GetDayOfWeek( nActDate
) == 6 )
583 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
590 if( GetDayOfWeek( nActDate
) < 5 )
592 if( !aSrtLst
.Find( nActDate
) )
596 nActDate
--; // jump over weekend
600 return nActDate
- nNullDate
;
608 double SAL_CALL
AnalysisAddIn::getYearfrac( constREFXPS
& xOpt
,
609 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const ANY
& rMode
) THROWDEF_RTE_IAE
611 double fRet
= GetYearFrac( xOpt
, nStartDate
, nEndDate
, getDateMode( xOpt
, rMode
) );
612 RETURN_FINITE( fRet
);
616 sal_Int32 SAL_CALL
AnalysisAddIn::getEdate( constREFXPS
& xOpt
, sal_Int32 nStartDate
, sal_Int32 nMonths
) THROWDEF_RTE_IAE
618 sal_Int32 nNullDate
= GetNullDate( xOpt
);
619 ScaDate
aDate( nNullDate
, nStartDate
, 5 );
620 aDate
.addMonths( nMonths
);
621 return aDate
.getDate( nNullDate
);
625 sal_Int32 SAL_CALL
AnalysisAddIn::getWeeknum( constREFXPS
& xOpt
, sal_Int32 nDate
, sal_Int32 nMode
) THROWDEF_RTE_IAE
627 nDate
+= GetNullDate( xOpt
);
629 sal_uInt16 nDay
, nMonth
, nYear
;
630 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
632 sal_Int32 nFirstInYear
= DateToDays( 1, 1, nYear
);
633 sal_uInt16 nFirstDayInYear
= GetDayOfWeek( nFirstInYear
);
635 return ( nDate
- nFirstInYear
+ ( ( nMode
== 1 )? ( nFirstDayInYear
+ 1 ) % 7 : nFirstDayInYear
) ) / 7 + 1;
639 sal_Int32 SAL_CALL
AnalysisAddIn::getEomonth( constREFXPS
& xOpt
, sal_Int32 nDate
, sal_Int32 nMonths
) THROWDEF_RTE_IAE
641 sal_Int32 nNullDate
= GetNullDate( xOpt
);
643 sal_uInt16 nDay
, nMonth
, nYear
;
644 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
646 sal_Int32 nNewMonth
= nMonth
+ nMonths
;
650 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
+ ( nNewMonth
/ 12 ) );
653 else if( nNewMonth
< 1 )
655 nNewMonth
= -nNewMonth
;
656 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
- ( nNewMonth
/ 12 ) );
659 nNewMonth
= 12 - nNewMonth
;
662 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth
), nYear
), sal_uInt16( nNewMonth
), nYear
) - nNullDate
;
666 sal_Int32 SAL_CALL
AnalysisAddIn::getNetworkdays( constREFXPS
& xOpt
,
667 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const ANY
& aHDay
) THROWDEF_RTE_IAE
669 sal_Int32 nNullDate
= GetNullDate( xOpt
);
671 SortedIndividualInt32List aSrtLst
;
673 aSrtLst
.InsertHolidayList( aAnyConv
, xOpt
, aHDay
, nNullDate
, sal_False
);
675 sal_Int32 nActDate
= nStartDate
+ nNullDate
;
676 sal_Int32 nStopDate
= nEndDate
+ nNullDate
;
679 if( nActDate
<= nStopDate
)
681 while( nActDate
<= nStopDate
)
683 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
691 while( nActDate
>= nStopDate
)
693 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
704 sal_Int32 SAL_CALL
AnalysisAddIn::getIseven( sal_Int32 nVal
) THROWDEF_RTE_IAE
706 return ( nVal
& 0x00000001 )? 0 : 1;
710 sal_Int32 SAL_CALL
AnalysisAddIn::getIsodd( sal_Int32 nVal
) THROWDEF_RTE_IAE
712 return ( nVal
& 0x00000001 )? 1 : 0;
716 AnalysisAddIn::getMultinomial( constREFXPS
& xOpt
, const SEQSEQ( sal_Int32
)& aVLst
,
717 const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
719 ScaDoubleListGE0 aValList
;
721 aValList
.Append( aVLst
);
722 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
724 if( aValList
.Count() == 0 )
730 for( const double *p
= aValList
.First(); p
; p
= aValList
.Next() )
732 double fInt
= (*p
>= 0.0) ? rtl::math::approxFloor( *p
) : rtl::math::approxCeil( *p
);
733 if ( fInt
< 0.0 || fInt
> 170.0 )
735 sal_Int32 n
= static_cast< sal_Int32
>( fInt
);
746 double fRet
= Fak( nZ
) / fN
;
747 RETURN_FINITE( fRet
);
751 double SAL_CALL
AnalysisAddIn::getSeriessum( double fX
, double fN
, double fM
, const SEQSEQ( double )& aCoeffList
) THROWDEF_RTE_IAE
755 // #i32269# 0^0 is undefined, Excel returns #NUM! error
756 if( fX
== 0.0 && fN
== 0 )
762 sal_Int32 nE1
= aCoeffList
.getLength();
766 for( n1
= 0 ; n1
< nE1
; n1
++ )
768 const SEQ( double )& rList
= aCoeffList
[ n1
];
769 nE2
= rList
.getLength();
770 const double* pList
= rList
.getConstArray();
772 for( n2
= 0 ; n2
< nE2
; n2
++ )
774 fRet
+= pList
[ n2
] * pow( fX
, fN
);
781 RETURN_FINITE( fRet
);
785 double SAL_CALL
AnalysisAddIn::getQuotient( double fNum
, double fDenom
) THROWDEF_RTE_IAE
788 if( (fNum
< 0) != (fDenom
< 0) )
789 fRet
= ::rtl::math::approxCeil( fNum
/ fDenom
);
791 fRet
= ::rtl::math::approxFloor( fNum
/ fDenom
);
792 RETURN_FINITE( fRet
);
796 double SAL_CALL
AnalysisAddIn::getMround( double fNum
, double fMult
) THROWDEF_RTE_IAE
801 double fRet
= fMult
* ::rtl::math::round( fNum
/ fMult
);
802 RETURN_FINITE( fRet
);
806 double SAL_CALL
AnalysisAddIn::getSqrtpi( double fNum
) THROWDEF_RTE_IAE
808 double fRet
= sqrt( fNum
* PI
);
809 RETURN_FINITE( fRet
);
813 double SAL_CALL
AnalysisAddIn::getRandbetween( double fMin
, double fMax
) THROWDEF_RTE_IAE
815 fMin
= ::rtl::math::round( fMin
, 0, rtl_math_RoundingMode_Up
);
816 fMax
= ::rtl::math::round( fMax
, 0, rtl_math_RoundingMode_Up
);
821 double fRet
= fMax
- fMin
+ 1.0;
823 fRet
/= (RAND_MAX
+ 1.0);
825 fRet
= floor( fRet
); // simple floor is sufficient here
826 RETURN_FINITE( fRet
);
830 double SAL_CALL
AnalysisAddIn::getGcd( constREFXPS
& xOpt
, const SEQSEQ( double )& aVLst
, const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
832 ScaDoubleListGT0 aValList
;
834 aValList
.Append( aVLst
);
835 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
837 if( aValList
.Count() == 0 )
840 const double* p
= aValList
.First();
855 double SAL_CALL
AnalysisAddIn::getLcm( constREFXPS
& xOpt
, const SEQSEQ( double )& aVLst
, const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
857 ScaDoubleListGE0 aValList
;
859 aValList
.Append( aVLst
);
860 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
862 if( aValList
.Count() == 0 )
865 const double* p
= aValList
.First();
879 f
= fTmp
* f
/ GetGcd( fTmp
, f
);
887 double SAL_CALL
AnalysisAddIn::getBesseli( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE_NCE
889 double fRet
= sca::analysis::BesselI( fNum
, nOrder
);
890 RETURN_FINITE( fRet
);
894 double SAL_CALL
AnalysisAddIn::getBesselj( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE_NCE
896 double fRet
= sca::analysis::BesselJ( fNum
, nOrder
);
897 RETURN_FINITE( fRet
);
901 double SAL_CALL
AnalysisAddIn::getBesselk( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE_NCE
903 if( nOrder
< 0 || fNum
<= 0.0 )
906 double fRet
= sca::analysis::BesselK( fNum
, nOrder
);
907 RETURN_FINITE( fRet
);
911 double SAL_CALL
AnalysisAddIn::getBessely( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE_NCE
913 if( nOrder
< 0 || fNum
<= 0.0 )
916 // return yn( nOrder, fNum );
917 double fRet
= sca::analysis::BesselY( fNum
, nOrder
);
918 RETURN_FINITE( fRet
);
922 const double SCA_MAX2
= 511.0; // min. val for binary numbers (9 bits + sign)
923 const double SCA_MIN2
= -SCA_MAX2
-1.0; // min. val for binary numbers (9 bits + sign)
924 const double SCA_MAX8
= 536870911.0; // max. val for octal numbers (29 bits + sign)
925 const double SCA_MIN8
= -SCA_MAX8
-1.0; // min. val for octal numbers (29 bits + sign)
926 const double SCA_MAX16
= 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
927 const double SCA_MIN16
= -SCA_MAX16
-1.0; // min. val for hexadecimal numbers (39 bits + sign)
928 const sal_Int32 SCA_MAXPLACES
= 10; // max. number of places
931 STRING SAL_CALL
AnalysisAddIn::getBin2Oct( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
933 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
934 sal_Int32 nPlaces
= 0;
935 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
936 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
940 double SAL_CALL
AnalysisAddIn::getBin2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
942 double fRet
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
943 RETURN_FINITE( fRet
);
947 STRING SAL_CALL
AnalysisAddIn::getBin2Hex( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
949 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
950 sal_Int32 nPlaces
= 0;
951 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
952 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
956 STRING SAL_CALL
AnalysisAddIn::getOct2Bin( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
958 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
959 sal_Int32 nPlaces
= 0;
960 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
961 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
965 double SAL_CALL
AnalysisAddIn::getOct2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
967 double fRet
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
968 RETURN_FINITE( fRet
);
972 STRING SAL_CALL
AnalysisAddIn::getOct2Hex( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
974 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
975 sal_Int32 nPlaces
= 0;
976 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
977 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
981 STRING SAL_CALL
AnalysisAddIn::getDec2Bin( constREFXPS
& xOpt
, sal_Int32 nNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
983 sal_Int32 nPlaces
= 0;
984 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
985 return ConvertFromDec( nNum
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
989 STRING SAL_CALL
AnalysisAddIn::getDec2Oct( constREFXPS
& xOpt
, sal_Int32 nNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
991 sal_Int32 nPlaces
= 0;
992 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
993 return ConvertFromDec( nNum
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
997 STRING SAL_CALL
AnalysisAddIn::getDec2Hex( constREFXPS
& xOpt
, double fNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
999 sal_Int32 nPlaces
= 0;
1000 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1001 return ConvertFromDec( fNum
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1005 STRING SAL_CALL
AnalysisAddIn::getHex2Bin( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
1007 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
1008 sal_Int32 nPlaces
= 0;
1009 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1010 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1014 double SAL_CALL
AnalysisAddIn::getHex2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
1016 double fRet
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
1017 RETURN_FINITE( fRet
);
1021 STRING SAL_CALL
AnalysisAddIn::getHex2Oct( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
1023 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
1024 sal_Int32 nPlaces
= 0;
1025 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
1026 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1030 sal_Int32 SAL_CALL
AnalysisAddIn::getDelta( constREFXPS
& xOpt
, double fNum1
, const ANY
& rNum2
) THROWDEF_RTE_IAE
1032 return fNum1
== aAnyConv
.getDouble( xOpt
, rNum2
, 0.0 );
1036 double SAL_CALL
AnalysisAddIn::getErf( constREFXPS
& xOpt
, double fLL
, const ANY
& rUL
) THROWDEF_RTE_IAE
1039 sal_Bool bContainsValue
= aAnyConv
.getDouble( fUL
, xOpt
, rUL
);
1041 fRet
= bContainsValue
? (Erf( fUL
) - Erf( fLL
)) : Erf( fLL
);
1042 RETURN_FINITE( fRet
);
1046 double SAL_CALL
AnalysisAddIn::getErfc( double f
) THROWDEF_RTE_IAE
1048 double fRet
= Erfc( f
);
1049 RETURN_FINITE( fRet
);
1053 sal_Int32 SAL_CALL
AnalysisAddIn::getGestep( constREFXPS
& xOpt
, double fNum
, const ANY
& rStep
) THROWDEF_RTE_IAE
1055 return fNum
>= aAnyConv
.getDouble( xOpt
, rStep
, 0.0 );
1059 double SAL_CALL
AnalysisAddIn::getFactdouble( sal_Int32 nNum
) THROWDEF_RTE_IAE
1061 double fRet
= FactDouble( nNum
);
1062 RETURN_FINITE( fRet
);
1066 double SAL_CALL
AnalysisAddIn::getImabs( const STRING
& aNum
) THROWDEF_RTE_IAE
1068 double fRet
= Complex( aNum
).Abs();
1069 RETURN_FINITE( fRet
);
1073 double SAL_CALL
AnalysisAddIn::getImaginary( const STRING
& aNum
) THROWDEF_RTE_IAE
1075 double fRet
= Complex( aNum
).Imag();
1076 RETURN_FINITE( fRet
);
1080 STRING SAL_CALL
AnalysisAddIn::getImpower( const STRING
& aNum
, double f
) THROWDEF_RTE_IAE
1086 return z
.GetString();
1090 double SAL_CALL
AnalysisAddIn::getImargument( const STRING
& aNum
) THROWDEF_RTE_IAE
1092 double fRet
= Complex( aNum
).Arg();
1093 RETURN_FINITE( fRet
);
1097 STRING SAL_CALL
AnalysisAddIn::getImcos( const STRING
& aNum
) THROWDEF_RTE_IAE
1103 return z
.GetString();
1107 STRING SAL_CALL
AnalysisAddIn::getImdiv( const STRING
& aDivid
, const STRING
& aDivis
) THROWDEF_RTE_IAE
1109 Complex
z( aDivid
);
1111 z
.Div( Complex( aDivis
) );
1113 return z
.GetString();
1117 STRING SAL_CALL
AnalysisAddIn::getImexp( const STRING
& aNum
) THROWDEF_RTE_IAE
1123 return z
.GetString();
1127 STRING SAL_CALL
AnalysisAddIn::getImconjugate( const STRING
& aNum
) THROWDEF_RTE_IAE
1133 return z
.GetString();
1137 STRING SAL_CALL
AnalysisAddIn::getImln( const STRING
& aNum
) THROWDEF_RTE_IAE
1143 return z
.GetString();
1147 STRING SAL_CALL
AnalysisAddIn::getImlog10( const STRING
& aNum
) THROWDEF_RTE_IAE
1153 return z
.GetString();
1157 STRING SAL_CALL
AnalysisAddIn::getImlog2( const STRING
& aNum
) THROWDEF_RTE_IAE
1163 return z
.GetString();
1167 STRING SAL_CALL
AnalysisAddIn::getImproduct( constREFXPS
&, const SEQSEQ( STRING
)& aNum1
, const SEQ( uno::Any
)& aNL
) THROWDEF_RTE_IAE
1171 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
1172 z_list
.Append( aNL
, AH_IgnoreEmpty
);
1174 const Complex
* p
= z_list
.First();
1177 return Complex( 0 ).GetString();
1181 for( p
= z_list
.Next() ; p
; p
= z_list
.Next() )
1184 return z
.GetString();
1188 double SAL_CALL
AnalysisAddIn::getImreal( const STRING
& aNum
) THROWDEF_RTE_IAE
1190 double fRet
= Complex( aNum
).Real();
1191 RETURN_FINITE( fRet
);
1195 STRING SAL_CALL
AnalysisAddIn::getImsin( const STRING
& aNum
) THROWDEF_RTE_IAE
1201 return z
.GetString();
1205 STRING SAL_CALL
AnalysisAddIn::getImsub( const STRING
& aNum1
, const STRING
& aNum2
) THROWDEF_RTE_IAE
1209 z
.Sub( Complex( aNum2
) );
1211 return z
.GetString();
1215 STRING SAL_CALL
AnalysisAddIn::getImsum( constREFXPS
&, const SEQSEQ( STRING
)& aNum1
, const SEQ( CSS::uno::Any
)& aFollowingPars
) THROWDEF_RTE_IAE
1219 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
1220 z_list
.Append( aFollowingPars
, AH_IgnoreEmpty
);
1222 const Complex
* p
= z_list
.First();
1225 return Complex( 0 ).GetString();
1229 for( p
= z_list
.Next() ; p
; p
= z_list
.Next() )
1232 return z
.GetString();
1236 STRING SAL_CALL
AnalysisAddIn::getImsqrt( const STRING
& aNum
) THROWDEF_RTE_IAE
1243 return z
.GetString();
1247 STRING SAL_CALL
AnalysisAddIn::getComplex( double fR
, double fI
, const ANY
& rSuff
) THROWDEF_RTE_IAE
1251 switch( rSuff
.getValueTypeClass() )
1253 case uno::TypeClass_VOID
:
1256 case uno::TypeClass_STRING
:
1258 const STRING
* pSuff
= ( const STRING
* ) rSuff
.getValue();
1259 bi
= pSuff
->compareToAscii( "i" ) == 0 || pSuff
->getLength() == 0;
1260 if( !bi
&& pSuff
->compareToAscii( "j" ) != 0 )
1268 return Complex( fR
, fI
, bi
? 'i' : 'j' ).GetString();
1272 double SAL_CALL
AnalysisAddIn::getConvert( double f
, const STRING
& aFU
, const STRING
& aTU
) THROWDEF_RTE_IAE
1275 pCDL
= new ConvertDataList();
1277 double fRet
= pCDL
->Convert( f
, aFU
, aTU
);
1278 RETURN_FINITE( fRet
);