1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "analysis.hxx"
31 #include <cppuhelper/factory.hxx>
32 #include <osl/diagnose.h>
33 #include <rtl/ustrbuf.hxx>
34 #include <rtl/math.hxx>
35 #include <sal/macros.h>
38 #include <tools/resmgr.hxx>
39 #include <tools/rcid.h>
40 #include "analysis.hrc"
43 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
44 #define MY_SERVICE "com.sun.star.sheet.addin.Analysis"
45 #define MY_IMPLNAME "com.sun.star.sheet.addin.AnalysisImpl"
47 using namespace ::rtl
;
48 using namespace ::com::sun::star
;
51 extern "C" SAL_DLLPUBLIC_EXPORT
void* SAL_CALL
analysis_component_getFactory(
52 const sal_Char
* pImplName
, void* pServiceManager
, void* /*pRegistryKey*/ )
56 if( pServiceManager
&& STRING::createFromAscii( pImplName
) == AnalysisAddIn::getImplementationName_Static() )
58 REF( lang::XSingleServiceFactory
) xFactory( cppu::createOneInstanceFactory(
59 reinterpret_cast< lang::XMultiServiceFactory
* >( pServiceManager
),
60 AnalysisAddIn::getImplementationName_Static(),
61 AnalysisAddIn_CreateInstance
,
62 AnalysisAddIn::getSupportedServiceNames_Static() ) );
67 pRet
= xFactory
.get();
75 //------------------------------------------------------------------------
77 // "normal" service implementation
79 //------------------------------------------------------------------------
82 ResMgr
& AnalysisAddIn::GetResMgr( void ) THROWDEF_RTE
86 InitData(); // try to get resource manager
96 STRING
AnalysisAddIn::GetDisplFuncStr( sal_uInt16 nFuncNum
) THROWDEF_RTE
98 return String( AnalysisRscStrLoader( RID_ANALYSIS_FUNCTION_NAMES
, nFuncNum
, GetResMgr() ).GetString() );
102 class AnalysisResourcePublisher
: public Resource
105 AnalysisResourcePublisher( const AnalysisResId
& rId
) : Resource( rId
) {}
106 sal_Bool
IsAvailableRes( const ResId
& rId
) const { return Resource::IsAvailableRes( rId
); }
107 void FreeResource() { Resource::FreeResource(); }
111 class AnalysisFuncRes
: public Resource
114 AnalysisFuncRes( ResId
& rRes
, ResMgr
& rResMgr
, sal_uInt16 nInd
, STRING
& rRet
);
118 AnalysisFuncRes::AnalysisFuncRes( ResId
& rRes
, ResMgr
& rResMgr
, sal_uInt16 nInd
, STRING
& rRet
) : Resource( rRes
)
120 rRet
= String( AnalysisResId( nInd
, rResMgr
) );
126 STRING
AnalysisAddIn::GetFuncDescrStr( sal_uInt16 nResId
, sal_uInt16 nStrIndex
) THROWDEF_RTE
129 AnalysisResourcePublisher
aResPubl( AnalysisResId( RID_ANALYSIS_FUNCTION_DESCRIPTIONS
, GetResMgr() ) );
130 AnalysisResId
aRes( nResId
, GetResMgr() );
131 aRes
.SetRT( RSC_RESOURCE
);
132 if( aResPubl
.IsAvailableRes( aRes
) )
134 AnalysisFuncRes
aSubRes( aRes
, GetResMgr(), nStrIndex
, aRet
);
137 aResPubl
.FreeResource();
143 void AnalysisAddIn::InitData( void )
148 OString
aModName( "analysis" );
149 pResMgr
= ResMgr::CreateResMgr( aModName
.getStr(), aFuncLoc
);
155 pFD
= new FuncDataList( *pResMgr
);
167 AnalysisAddIn::AnalysisAddIn( const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
) :
170 pFactDoubles( NULL
),
173 aAnyConv( xServiceFact
)
178 AnalysisAddIn::~AnalysisAddIn()
184 delete[] pFactDoubles
;
190 delete[] pDefLocales
;
194 sal_Int32
AnalysisAddIn::getDateMode(
195 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
196 const uno::Any
& rAny
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
198 sal_Int32 nMode
= aAnyConv
.getInt32( xPropSet
, rAny
, 0 );
199 if( (nMode
< 0) || (nMode
> 4) )
200 throw lang::IllegalArgumentException();
206 //-----------------------------------------------------------------------------
209 #define MAXFACTDOUBLE 300
211 double AnalysisAddIn::FactDouble( sal_Int32 nNum
) THROWDEF_RTE_IAE
213 if( nNum
< 0 || nNum
> MAXFACTDOUBLE
)
218 pFactDoubles
= new double[ MAXFACTDOUBLE
+ 1 ];
220 pFactDoubles
[ 0 ] = 1.0; // by default
225 pFactDoubles
[ 1 ] = fOdd
;
226 pFactDoubles
[ 2 ] = fEven
;
228 sal_Bool bOdd
= sal_True
;
230 for( sal_uInt16 nCnt
= 3 ; nCnt
<= MAXFACTDOUBLE
; nCnt
++ )
235 pFactDoubles
[ nCnt
] = fOdd
;
240 pFactDoubles
[ nCnt
] = fEven
;
248 return pFactDoubles
[ nNum
];
252 STRING
AnalysisAddIn::getImplementationName_Static()
254 return STRFROMASCII( MY_IMPLNAME
);
258 SEQ( STRING
) AnalysisAddIn::getSupportedServiceNames_Static()
260 SEQ( STRING
) aRet(2);
261 STRING
* pArray
= aRet
.getArray();
262 pArray
[0] = STRFROMASCII( ADDIN_SERVICE
);
263 pArray
[1] = STRFROMASCII( MY_SERVICE
);
268 REF( uno::XInterface
) SAL_CALL
AnalysisAddIn_CreateInstance(
269 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
)
271 static uno::Reference
< uno::XInterface
> xInst
= (cppu::OWeakObject
*) new AnalysisAddIn( xServiceFact
);
278 STRING SAL_CALL
AnalysisAddIn::getServiceName() THROWDEF_RTE
280 // name of specific AddIn service
281 return STRFROMASCII( MY_SERVICE
);
287 STRING SAL_CALL
AnalysisAddIn::getImplementationName() THROWDEF_RTE
289 return getImplementationName_Static();
293 sal_Bool SAL_CALL
AnalysisAddIn::supportsService( const STRING
& aName
) THROWDEF_RTE
295 return aName
.compareToAscii( ADDIN_SERVICE
) == 0 || aName
.compareToAscii( MY_SERVICE
) == 0;
299 SEQ( STRING
) SAL_CALL
AnalysisAddIn::getSupportedServiceNames() THROWDEF_RTE
301 return getSupportedServiceNames_Static();
307 void SAL_CALL
AnalysisAddIn::setLocale( const lang::Locale
& eLocale
) THROWDEF_RTE
311 InitData(); // change of locale invalidates resources!
314 lang::Locale SAL_CALL
AnalysisAddIn::getLocale() THROWDEF_RTE
322 STRING SAL_CALL
AnalysisAddIn::getProgrammaticFuntionName( const STRING
& ) THROWDEF_RTE
325 // (but should be implemented for other uses of the AddIn service)
331 STRING SAL_CALL
AnalysisAddIn::getDisplayFunctionName( const STRING
& aProgrammaticName
) THROWDEF_RTE
335 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
338 aRet
= GetDisplFuncStr( p
->GetUINameID() );
340 aRet
+= STRFROMANSI( "_ADD" );
344 aRet
= STRFROMANSI( "UNKNOWNFUNC_" );
345 aRet
+= aProgrammaticName
;
352 STRING SAL_CALL
AnalysisAddIn::getFunctionDescription( const STRING
& aProgrammaticName
) THROWDEF_RTE
356 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
358 aRet
= GetFuncDescrStr( p
->GetDescrID(), 1 );
364 STRING SAL_CALL
AnalysisAddIn::getDisplayArgumentName( const STRING
& aName
, sal_Int32 nArg
) THROWDEF_RTE
368 const FuncData
* p
= pFD
->Get( aName
);
369 if( p
&& nArg
<= 0xFFFF )
371 sal_uInt16 nStr
= p
->GetStrIndex( sal_uInt16( nArg
) );
373 aRet
= GetFuncDescrStr( p
->GetDescrID(), nStr
);
375 aRet
= STRFROMANSI( "internal" );
382 STRING SAL_CALL
AnalysisAddIn::getArgumentDescription( const STRING
& aName
, sal_Int32 nArg
) THROWDEF_RTE
386 const FuncData
* p
= pFD
->Get( aName
);
387 if( p
&& nArg
<= 0xFFFF )
389 sal_uInt16 nStr
= p
->GetStrIndex( sal_uInt16( nArg
) );
391 aRet
= GetFuncDescrStr( p
->GetDescrID(), nStr
+ 1 );
393 aRet
= STRFROMANSI( "for internal use only" );
400 static const char* pDefCatName
= "Add-In";
403 STRING SAL_CALL
AnalysisAddIn::getProgrammaticCategoryName( const STRING
& aName
) THROWDEF_RTE
405 // return non-translated strings
406 // return STRFROMASCII( "Add-In" );
407 const FuncData
* p
= pFD
->Get( aName
);
411 const sal_Char
* pStr
;
413 switch( p
->GetCategory() )
415 case FDCat_DateTime
: pStr
= "Date&Time"; break;
416 case FDCat_Finance
: pStr
= "Financial"; break;
417 case FDCat_Inf
: pStr
= "Information"; break;
418 case FDCat_Math
: pStr
= "Mathematical"; break;
419 case FDCat_Tech
: pStr
= "Technical"; break;
421 pStr
= pDefCatName
; break;
424 aRet
= STRFROMASCII( pStr
);
427 aRet
= STRFROMASCII( pDefCatName
);
433 STRING SAL_CALL
AnalysisAddIn::getDisplayCategoryName( const STRING
& aProgrammaticFunctionName
) THROWDEF_RTE
435 // return translated strings, not used for predefined categories
436 // return STRFROMASCII( "Add-In" );
437 const FuncData
* p
= pFD
->Get( aProgrammaticFunctionName
);
441 const sal_Char
* pStr
;
443 switch( p
->GetCategory() )
445 case FDCat_DateTime
: pStr
= "Date&Time"; break;
446 case FDCat_Finance
: pStr
= "Financial"; break;
447 case FDCat_Inf
: pStr
= "Information"; break;
448 case FDCat_Math
: pStr
= "Mathematical"; break;
449 case FDCat_Tech
: pStr
= "Technical"; break;
451 pStr
= pDefCatName
; break;
454 aRet
= STRFROMASCII( pStr
);
457 aRet
= STRFROMASCII( pDefCatName
);
463 static const sal_Char
* pLang
[] = { "de", "en" };
464 static const sal_Char
* pCoun
[] = { "DE", "US" };
465 static const sal_uInt32 nNumOfLoc
= SAL_N_ELEMENTS(pLang
);
468 void AnalysisAddIn::InitDefLocales( void )
470 pDefLocales
= new ::com::sun::star::lang::Locale
[ nNumOfLoc
];
472 for( sal_uInt32 n
= 0 ; n
< nNumOfLoc
; n
++ )
474 pDefLocales
[ n
].Language
= STRING::createFromAscii( pLang
[ n
] );
475 pDefLocales
[ n
].Country
= STRING::createFromAscii( pCoun
[ n
] );
480 inline const ::com::sun::star::lang::Locale
& AnalysisAddIn::GetLocale( sal_uInt32 nInd
)
485 if( nInd
< sizeof( pLang
) )
486 return pDefLocales
[ nInd
];
492 SEQofLocName SAL_CALL
AnalysisAddIn::getCompatibilityNames( const STRING
& aProgrammaticName
) THROWDEF_RTE
494 const FuncData
* p
= pFD
->Get( aProgrammaticName
);
497 return SEQofLocName( 0 );
499 const StringList
& r
= p
->GetCompNameList();
500 sal_uInt32 nCount
= r
.Count();
502 SEQofLocName
aRet( nCount
);
504 ::com::sun::star::sheet::LocalizedName
* pArray
= aRet
.getArray();
506 for( sal_uInt32 n
= 0 ; n
< nCount
; n
++ )
508 pArray
[ n
] = ::com::sun::star::sheet::LocalizedName( GetLocale( n
), *r
.Get( n
) );
521 sal_Int32 SAL_CALL
AnalysisAddIn::getWorkday( constREFXPS
& xOptions
,
522 sal_Int32 nDate
, sal_Int32 nDays
, const ANY
& aHDay
) THROWDEF_RTE_IAE
527 sal_Int32 nNullDate
= GetNullDate( xOptions
);
529 SortedIndividualInt32List aSrtLst
;
531 aSrtLst
.InsertHolidayList( aAnyConv
, xOptions
, aHDay
, nNullDate
, sal_False
);
533 sal_Int32 nActDate
= nDate
+ nNullDate
;
537 if( GetDayOfWeek( nActDate
) == 5 )
538 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
545 if( GetDayOfWeek( nActDate
) < 5 )
547 if( !aSrtLst
.Find( nActDate
) )
551 nActDate
++; // jump over weekend
556 if( GetDayOfWeek( nActDate
) == 6 )
557 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
564 if( GetDayOfWeek( nActDate
) < 5 )
566 if( !aSrtLst
.Find( nActDate
) )
570 nActDate
--; // jump over weekend
574 return nActDate
- nNullDate
;
582 double SAL_CALL
AnalysisAddIn::getYearfrac( constREFXPS
& xOpt
,
583 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const ANY
& rMode
) THROWDEF_RTE_IAE
585 double fRet
= GetYearFrac( xOpt
, nStartDate
, nEndDate
, getDateMode( xOpt
, rMode
) );
586 RETURN_FINITE( fRet
);
590 sal_Int32 SAL_CALL
AnalysisAddIn::getEdate( constREFXPS
& xOpt
, sal_Int32 nStartDate
, sal_Int32 nMonths
) THROWDEF_RTE_IAE
592 sal_Int32 nNullDate
= GetNullDate( xOpt
);
593 ScaDate
aDate( nNullDate
, nStartDate
, 5 );
594 aDate
.addMonths( nMonths
);
595 return aDate
.getDate( nNullDate
);
599 sal_Int32 SAL_CALL
AnalysisAddIn::getWeeknum( constREFXPS
& xOpt
, sal_Int32 nDate
, sal_Int32 nMode
) THROWDEF_RTE_IAE
601 nDate
+= GetNullDate( xOpt
);
603 sal_uInt16 nDay
, nMonth
, nYear
;
604 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
606 sal_Int32 nFirstInYear
= DateToDays( 1, 1, nYear
);
607 sal_uInt16 nFirstDayInYear
= GetDayOfWeek( nFirstInYear
);
609 return ( nDate
- nFirstInYear
+ ( ( nMode
== 1 )? ( nFirstDayInYear
+ 1 ) % 7 : nFirstDayInYear
) ) / 7 + 1;
613 sal_Int32 SAL_CALL
AnalysisAddIn::getEomonth( constREFXPS
& xOpt
, sal_Int32 nDate
, sal_Int32 nMonths
) THROWDEF_RTE_IAE
615 sal_Int32 nNullDate
= GetNullDate( xOpt
);
617 sal_uInt16 nDay
, nMonth
, nYear
;
618 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
620 sal_Int32 nNewMonth
= nMonth
+ nMonths
;
624 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
+ ( nNewMonth
/ 12 ) );
627 else if( nNewMonth
< 1 )
629 nNewMonth
= -nNewMonth
;
630 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
- ( nNewMonth
/ 12 ) );
633 nNewMonth
= 12 - nNewMonth
;
636 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth
), nYear
), sal_uInt16( nNewMonth
), nYear
) - nNullDate
;
640 sal_Int32 SAL_CALL
AnalysisAddIn::getNetworkdays( constREFXPS
& xOpt
,
641 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const ANY
& aHDay
) THROWDEF_RTE_IAE
643 sal_Int32 nNullDate
= GetNullDate( xOpt
);
645 SortedIndividualInt32List aSrtLst
;
647 aSrtLst
.InsertHolidayList( aAnyConv
, xOpt
, aHDay
, nNullDate
, sal_False
);
649 sal_Int32 nActDate
= nStartDate
+ nNullDate
;
650 sal_Int32 nStopDate
= nEndDate
+ nNullDate
;
653 if( nActDate
<= nStopDate
)
655 while( nActDate
<= nStopDate
)
657 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
665 while( nActDate
>= nStopDate
)
667 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
678 sal_Int32 SAL_CALL
AnalysisAddIn::getIseven( sal_Int32 nVal
) THROWDEF_RTE_IAE
680 return ( nVal
& 0x00000001 )? 0 : 1;
684 sal_Int32 SAL_CALL
AnalysisAddIn::getIsodd( sal_Int32 nVal
) THROWDEF_RTE_IAE
686 return ( nVal
& 0x00000001 )? 1 : 0;
690 AnalysisAddIn::getMultinomial( constREFXPS
& xOpt
, const SEQSEQ( sal_Int32
)& aVLst
,
691 const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
693 ScaDoubleListGE0 aValList
;
695 aValList
.Append( aVLst
);
696 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
698 if( aValList
.Count() == 0 )
704 for( const double *p
= aValList
.First(); p
; p
= aValList
.Next() )
706 double fInt
= (*p
>= 0.0) ? rtl::math::approxFloor( *p
) : rtl::math::approxCeil( *p
);
707 if ( fInt
< 0.0 || fInt
> 170.0 )
709 sal_Int32 n
= static_cast< sal_Int32
>( fInt
);
720 double fRet
= Fak( nZ
) / fN
;
721 RETURN_FINITE( fRet
);
725 double SAL_CALL
AnalysisAddIn::getSeriessum( double fX
, double fN
, double fM
, const SEQSEQ( double )& aCoeffList
) THROWDEF_RTE_IAE
729 // #i32269# 0^0 is undefined, Excel returns #NUM! error
730 if( fX
== 0.0 && fN
== 0 )
736 sal_Int32 nE1
= aCoeffList
.getLength();
739 for( n1
= 0 ; n1
< nE1
; n1
++ )
741 const SEQ( double )& rList
= aCoeffList
[ n1
];
742 nE2
= rList
.getLength();
743 const double* pList
= rList
.getConstArray();
745 for( n2
= 0 ; n2
< nE2
; n2
++ )
747 fRet
+= pList
[ n2
] * pow( fX
, fN
);
754 RETURN_FINITE( fRet
);
758 double SAL_CALL
AnalysisAddIn::getQuotient( double fNum
, double fDenom
) THROWDEF_RTE_IAE
761 if( (fNum
< 0) != (fDenom
< 0) )
762 fRet
= ::rtl::math::approxCeil( fNum
/ fDenom
);
764 fRet
= ::rtl::math::approxFloor( fNum
/ fDenom
);
765 RETURN_FINITE( fRet
);
769 double SAL_CALL
AnalysisAddIn::getMround( double fNum
, double fMult
) THROWDEF_RTE_IAE
774 double fRet
= fMult
* ::rtl::math::round( fNum
/ fMult
);
775 RETURN_FINITE( fRet
);
779 double SAL_CALL
AnalysisAddIn::getSqrtpi( double fNum
) THROWDEF_RTE_IAE
781 double fRet
= sqrt( fNum
* PI
);
782 RETURN_FINITE( fRet
);
786 double SAL_CALL
AnalysisAddIn::getRandbetween( double fMin
, double fMax
) THROWDEF_RTE_IAE
788 fMin
= ::rtl::math::round( fMin
, 0, rtl_math_RoundingMode_Up
);
789 fMax
= ::rtl::math::round( fMax
, 0, rtl_math_RoundingMode_Up
);
794 double fRet
= fMax
- fMin
+ 1.0;
796 fRet
/= (RAND_MAX
+ 1.0);
798 fRet
= floor( fRet
); // simple floor is sufficient here
799 RETURN_FINITE( fRet
);
803 double SAL_CALL
AnalysisAddIn::getGcd( constREFXPS
& xOpt
, const SEQSEQ( double )& aVLst
, const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
805 ScaDoubleListGT0 aValList
;
807 aValList
.Append( aVLst
);
808 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
810 if( aValList
.Count() == 0 )
813 const double* p
= aValList
.First();
828 double SAL_CALL
AnalysisAddIn::getLcm( constREFXPS
& xOpt
, const SEQSEQ( double )& aVLst
, const SEQ( uno::Any
)& aOptVLst
) THROWDEF_RTE_IAE
830 ScaDoubleListGE0 aValList
;
832 aValList
.Append( aVLst
);
833 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
835 if( aValList
.Count() == 0 )
838 const double* p
= aValList
.First();
852 f
= fTmp
* f
/ GetGcd( fTmp
, f
);
860 double SAL_CALL
AnalysisAddIn::getBesseli( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE_NCE
862 double fRet
= sca::analysis::BesselI( fNum
, nOrder
);
863 RETURN_FINITE( fRet
);
867 double SAL_CALL
AnalysisAddIn::getBesselj( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE_NCE
869 double fRet
= sca::analysis::BesselJ( fNum
, nOrder
);
870 RETURN_FINITE( fRet
);
874 double SAL_CALL
AnalysisAddIn::getBesselk( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE_NCE
876 if( nOrder
< 0 || fNum
<= 0.0 )
879 double fRet
= sca::analysis::BesselK( fNum
, nOrder
);
880 RETURN_FINITE( fRet
);
884 double SAL_CALL
AnalysisAddIn::getBessely( double fNum
, sal_Int32 nOrder
) THROWDEF_RTE_IAE_NCE
886 if( nOrder
< 0 || fNum
<= 0.0 )
889 double fRet
= sca::analysis::BesselY( fNum
, nOrder
);
890 RETURN_FINITE( fRet
);
894 const double SCA_MAX2
= 511.0; // min. val for binary numbers (9 bits + sign)
895 const double SCA_MIN2
= -SCA_MAX2
-1.0; // min. val for binary numbers (9 bits + sign)
896 const double SCA_MAX8
= 536870911.0; // max. val for octal numbers (29 bits + sign)
897 const double SCA_MIN8
= -SCA_MAX8
-1.0; // min. val for octal numbers (29 bits + sign)
898 const double SCA_MAX16
= 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
899 const double SCA_MIN16
= -SCA_MAX16
-1.0; // min. val for hexadecimal numbers (39 bits + sign)
900 const sal_Int32 SCA_MAXPLACES
= 10; // max. number of places
903 STRING SAL_CALL
AnalysisAddIn::getBin2Oct( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
905 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
906 sal_Int32 nPlaces
= 0;
907 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
908 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
912 double SAL_CALL
AnalysisAddIn::getBin2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
914 double fRet
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
915 RETURN_FINITE( fRet
);
919 STRING SAL_CALL
AnalysisAddIn::getBin2Hex( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
921 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
922 sal_Int32 nPlaces
= 0;
923 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
924 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
928 STRING SAL_CALL
AnalysisAddIn::getOct2Bin( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
930 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
931 sal_Int32 nPlaces
= 0;
932 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
933 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
937 double SAL_CALL
AnalysisAddIn::getOct2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
939 double fRet
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
940 RETURN_FINITE( fRet
);
944 STRING SAL_CALL
AnalysisAddIn::getOct2Hex( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
946 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
947 sal_Int32 nPlaces
= 0;
948 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
949 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
953 STRING SAL_CALL
AnalysisAddIn::getDec2Bin( constREFXPS
& xOpt
, sal_Int32 nNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
955 sal_Int32 nPlaces
= 0;
956 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
957 return ConvertFromDec( nNum
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
961 STRING SAL_CALL
AnalysisAddIn::getDec2Oct( constREFXPS
& xOpt
, sal_Int32 nNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
963 sal_Int32 nPlaces
= 0;
964 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
965 return ConvertFromDec( nNum
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
969 STRING SAL_CALL
AnalysisAddIn::getDec2Hex( constREFXPS
& xOpt
, double fNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
971 sal_Int32 nPlaces
= 0;
972 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
973 return ConvertFromDec( fNum
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
977 STRING SAL_CALL
AnalysisAddIn::getHex2Bin( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
979 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
980 sal_Int32 nPlaces
= 0;
981 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
982 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
986 double SAL_CALL
AnalysisAddIn::getHex2Dec( const STRING
& aNum
) THROWDEF_RTE_IAE
988 double fRet
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
989 RETURN_FINITE( fRet
);
993 STRING SAL_CALL
AnalysisAddIn::getHex2Oct( constREFXPS
& xOpt
, const STRING
& aNum
, const ANY
& rPlaces
) THROWDEF_RTE_IAE
995 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
996 sal_Int32 nPlaces
= 0;
997 sal_Bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
998 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
1002 sal_Int32 SAL_CALL
AnalysisAddIn::getDelta( constREFXPS
& xOpt
, double fNum1
, const ANY
& rNum2
) THROWDEF_RTE_IAE
1004 return fNum1
== aAnyConv
.getDouble( xOpt
, rNum2
, 0.0 );
1008 double SAL_CALL
AnalysisAddIn::getErf( constREFXPS
& xOpt
, double fLL
, const ANY
& rUL
) THROWDEF_RTE_IAE
1011 sal_Bool bContainsValue
= aAnyConv
.getDouble( fUL
, xOpt
, rUL
);
1013 fRet
= bContainsValue
? (Erf( fUL
) - Erf( fLL
)) : Erf( fLL
);
1014 RETURN_FINITE( fRet
);
1018 double SAL_CALL
AnalysisAddIn::getErfc( double f
) THROWDEF_RTE_IAE
1020 double fRet
= Erfc( f
);
1021 RETURN_FINITE( fRet
);
1025 sal_Int32 SAL_CALL
AnalysisAddIn::getGestep( constREFXPS
& xOpt
, double fNum
, const ANY
& rStep
) THROWDEF_RTE_IAE
1027 return fNum
>= aAnyConv
.getDouble( xOpt
, rStep
, 0.0 );
1031 double SAL_CALL
AnalysisAddIn::getFactdouble( sal_Int32 nNum
) THROWDEF_RTE_IAE
1033 double fRet
= FactDouble( nNum
);
1034 RETURN_FINITE( fRet
);
1038 double SAL_CALL
AnalysisAddIn::getImabs( const STRING
& aNum
) THROWDEF_RTE_IAE
1040 double fRet
= Complex( aNum
).Abs();
1041 RETURN_FINITE( fRet
);
1045 double SAL_CALL
AnalysisAddIn::getImaginary( const STRING
& aNum
) THROWDEF_RTE_IAE
1047 double fRet
= Complex( aNum
).Imag();
1048 RETURN_FINITE( fRet
);
1052 STRING SAL_CALL
AnalysisAddIn::getImpower( const STRING
& aNum
, double f
) THROWDEF_RTE_IAE
1058 return z
.GetString();
1062 double SAL_CALL
AnalysisAddIn::getImargument( const STRING
& aNum
) THROWDEF_RTE_IAE
1064 double fRet
= Complex( aNum
).Arg();
1065 RETURN_FINITE( fRet
);
1069 STRING SAL_CALL
AnalysisAddIn::getImcos( const STRING
& aNum
) THROWDEF_RTE_IAE
1075 return z
.GetString();
1079 STRING SAL_CALL
AnalysisAddIn::getImdiv( const STRING
& aDivid
, const STRING
& aDivis
) THROWDEF_RTE_IAE
1081 Complex
z( aDivid
);
1083 z
.Div( Complex( aDivis
) );
1085 return z
.GetString();
1089 STRING SAL_CALL
AnalysisAddIn::getImexp( const STRING
& aNum
) THROWDEF_RTE_IAE
1095 return z
.GetString();
1099 STRING SAL_CALL
AnalysisAddIn::getImconjugate( const STRING
& aNum
) THROWDEF_RTE_IAE
1105 return z
.GetString();
1109 STRING SAL_CALL
AnalysisAddIn::getImln( const STRING
& aNum
) THROWDEF_RTE_IAE
1115 return z
.GetString();
1119 STRING SAL_CALL
AnalysisAddIn::getImlog10( const STRING
& aNum
) THROWDEF_RTE_IAE
1125 return z
.GetString();
1129 STRING SAL_CALL
AnalysisAddIn::getImlog2( const STRING
& aNum
) THROWDEF_RTE_IAE
1135 return z
.GetString();
1139 STRING SAL_CALL
AnalysisAddIn::getImproduct( constREFXPS
&, const SEQSEQ( STRING
)& aNum1
, const SEQ( uno::Any
)& aNL
) THROWDEF_RTE_IAE
1143 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
1144 z_list
.Append( aNL
, AH_IgnoreEmpty
);
1146 const Complex
* p
= z_list
.First();
1149 return Complex( 0 ).GetString();
1153 for( p
= z_list
.Next() ; p
; p
= z_list
.Next() )
1156 return z
.GetString();
1160 double SAL_CALL
AnalysisAddIn::getImreal( const STRING
& aNum
) THROWDEF_RTE_IAE
1162 double fRet
= Complex( aNum
).Real();
1163 RETURN_FINITE( fRet
);
1167 STRING SAL_CALL
AnalysisAddIn::getImsin( const STRING
& aNum
) THROWDEF_RTE_IAE
1173 return z
.GetString();
1177 STRING SAL_CALL
AnalysisAddIn::getImsub( const STRING
& aNum1
, const STRING
& aNum2
) THROWDEF_RTE_IAE
1181 z
.Sub( Complex( aNum2
) );
1183 return z
.GetString();
1187 STRING SAL_CALL
AnalysisAddIn::getImsum( constREFXPS
&, const SEQSEQ( STRING
)& aNum1
, const SEQ( ::com::sun::star::uno::Any
)& aFollowingPars
) THROWDEF_RTE_IAE
1191 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
1192 z_list
.Append( aFollowingPars
, AH_IgnoreEmpty
);
1194 const Complex
* p
= z_list
.First();
1197 return Complex( 0 ).GetString();
1201 for( p
= z_list
.Next() ; p
; p
= z_list
.Next() )
1204 return z
.GetString();
1208 STRING SAL_CALL
AnalysisAddIn::getImsqrt( const STRING
& aNum
) THROWDEF_RTE_IAE
1214 return z
.GetString();
1218 STRING SAL_CALL
AnalysisAddIn::getImtan( const STRING
& aNum
) THROWDEF_RTE_IAE
1224 return z
.GetString();
1228 STRING SAL_CALL
AnalysisAddIn::getImsec( const STRING
& aNum
) THROWDEF_RTE_IAE
1234 return z
.GetString();
1238 STRING SAL_CALL
AnalysisAddIn::getImcsc( const STRING
& aNum
) THROWDEF_RTE_IAE
1244 return z
.GetString();
1248 STRING SAL_CALL
AnalysisAddIn::getImcot( const STRING
& aNum
) THROWDEF_RTE_IAE
1254 return z
.GetString();
1258 STRING SAL_CALL
AnalysisAddIn::getImsinh( const STRING
& aNum
) THROWDEF_RTE_IAE
1264 return z
.GetString();
1268 STRING SAL_CALL
AnalysisAddIn::getImcosh( const STRING
& aNum
) THROWDEF_RTE_IAE
1274 return z
.GetString();
1278 STRING SAL_CALL
AnalysisAddIn::getImsech( const STRING
& aNum
) THROWDEF_RTE_IAE
1284 return z
.GetString();
1288 STRING SAL_CALL
AnalysisAddIn::getImcsch( const STRING
& aNum
) THROWDEF_RTE_IAE
1294 return z
.GetString();
1298 STRING SAL_CALL
AnalysisAddIn::getComplex( double fR
, double fI
, const ANY
& rSuff
) THROWDEF_RTE_IAE
1302 switch( rSuff
.getValueTypeClass() )
1304 case uno::TypeClass_VOID
:
1307 case uno::TypeClass_STRING
:
1309 const STRING
* pSuff
= ( const STRING
* ) rSuff
.getValue();
1310 bi
= pSuff
->compareToAscii( "i" ) == 0 || pSuff
->isEmpty();
1311 if( !bi
&& pSuff
->compareToAscii( "j" ) != 0 )
1319 return Complex( fR
, fI
, bi
? 'i' : 'j' ).GetString();
1323 double SAL_CALL
AnalysisAddIn::getConvert( double f
, const STRING
& aFU
, const STRING
& aTU
) THROWDEF_RTE_IAE
1326 pCDL
= new ConvertDataList();
1328 double fRet
= pCDL
->Convert( f
, aFU
, aTU
);
1329 RETURN_FINITE( fRet
);
1333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */