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 #include "analysis.hxx"
21 #include "analysis.hrc"
23 #include <cppuhelper/factory.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include <comphelper/random.hxx>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <osl/diagnose.h>
28 #include <rtl/ustrbuf.hxx>
29 #include <rtl/math.hxx>
30 #include <sal/macros.h>
32 #include <tools/resmgr.hxx>
33 #include <tools/rcid.h>
37 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
38 #define MY_SERVICE "com.sun.star.sheet.addin.Analysis"
39 #define MY_IMPLNAME "com.sun.star.sheet.addin.AnalysisImpl"
41 using namespace ::com::sun::star
;
42 using namespace sca::analysis
;
45 extern "C" SAL_DLLPUBLIC_EXPORT
void* SAL_CALL
analysis_component_getFactory(
46 const sal_Char
* pImplName
, void* pServiceManager
, void* /*pRegistryKey*/ )
50 if( pServiceManager
&& OUString::createFromAscii( pImplName
) == AnalysisAddIn::getImplementationName_Static() )
52 uno::Reference
< lang::XSingleServiceFactory
> xFactory( cppu::createOneInstanceFactory(
53 static_cast< lang::XMultiServiceFactory
* >( pServiceManager
),
54 AnalysisAddIn::getImplementationName_Static(),
55 AnalysisAddIn_CreateInstance
,
56 AnalysisAddIn::getSupportedServiceNames_Static() ) );
61 pRet
= xFactory
.get();
68 ResMgr
& AnalysisAddIn::GetResMgr() throw( uno::RuntimeException
, std::exception
)
72 InitData(); // try to get resource manager
75 throw uno::RuntimeException();
81 OUString
AnalysisAddIn::GetDisplFuncStr( sal_uInt16 nFuncNum
) throw( uno::RuntimeException
, std::exception
)
83 return AnalysisRscStrLoader( RID_ANALYSIS_FUNCTION_NAMES
, nFuncNum
, GetResMgr() ).GetString();
86 class AnalysisResourcePublisher
: public Resource
89 explicit AnalysisResourcePublisher( const AnalysisResId
& rId
) : Resource( rId
) {}
90 bool IsAvailableRes( const ResId
& rId
) const { return Resource::IsAvailableRes( rId
); }
91 void FreeResource() { Resource::FreeResource(); }
94 class AnalysisFuncRes
: public Resource
97 AnalysisFuncRes( ResId
& rRes
, ResMgr
& rResMgr
, sal_uInt16 nInd
, OUString
& rRet
);
100 AnalysisFuncRes::AnalysisFuncRes( ResId
& rRes
, ResMgr
& rResMgr
, sal_uInt16 nInd
, OUString
& rRet
) : Resource( rRes
)
102 rRet
= AnalysisResId(nInd
, rResMgr
).toString();
107 OUString
AnalysisAddIn::GetFuncDescrStr( sal_uInt16 nResId
, sal_uInt16 nStrIndex
) throw( uno::RuntimeException
, std::exception
)
110 AnalysisResourcePublisher
aResPubl( AnalysisResId( RID_ANALYSIS_FUNCTION_DESCRIPTIONS
, GetResMgr() ) );
111 AnalysisResId
aRes( nResId
, GetResMgr() );
112 aRes
.SetRT( RSC_RESOURCE
);
113 if( aResPubl
.IsAvailableRes( aRes
) )
115 AnalysisFuncRes
aSubRes( aRes
, GetResMgr(), nStrIndex
, aRet
);
118 aResPubl
.FreeResource();
123 void AnalysisAddIn::InitData()
126 pResMgr
= ResMgr::CreateResMgr("analysis", LanguageTag(aFuncLoc
));
132 pFD
= new FuncDataList
;
133 InitFuncDataList( *pFD
, *pResMgr
);
143 pDefLocales
= nullptr;
147 AnalysisAddIn::AnalysisAddIn( const uno::Reference
< uno::XComponentContext
>& xContext
) :
148 pDefLocales( nullptr ),
150 pFactDoubles( nullptr ),
157 AnalysisAddIn::~AnalysisAddIn()
161 delete[] pFactDoubles
;
163 delete[] pDefLocales
;
166 sal_Int32
AnalysisAddIn::getDateMode(
167 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
168 const uno::Any
& rAny
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
170 sal_Int32 nMode
= aAnyConv
.getInt32( xPropSet
, rAny
, 0 );
171 if( (nMode
< 0) || (nMode
> 4) )
172 throw lang::IllegalArgumentException();
176 #define MAXFACTDOUBLE 300
178 double AnalysisAddIn::FactDouble( sal_Int32 nNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
180 if( nNum
< 0 || nNum
> MAXFACTDOUBLE
)
181 throw lang::IllegalArgumentException();
185 pFactDoubles
= new double[ MAXFACTDOUBLE
+ 1 ];
187 pFactDoubles
[ 0 ] = 1.0; // by default
192 pFactDoubles
[ 1 ] = fOdd
;
193 pFactDoubles
[ 2 ] = fEven
;
197 for( sal_uInt16 nCnt
= 3 ; nCnt
<= MAXFACTDOUBLE
; nCnt
++ )
202 pFactDoubles
[ nCnt
] = fOdd
;
207 pFactDoubles
[ nCnt
] = fEven
;
215 return pFactDoubles
[ nNum
];
218 OUString
AnalysisAddIn::getImplementationName_Static()
220 return OUString( MY_IMPLNAME
);
223 uno::Sequence
< OUString
> AnalysisAddIn::getSupportedServiceNames_Static()
225 uno::Sequence
< OUString
> aRet(2);
226 OUString
* pArray
= aRet
.getArray();
227 pArray
[0] = ADDIN_SERVICE
;
228 pArray
[1] = MY_SERVICE
;
232 uno::Reference
< uno::XInterface
> SAL_CALL
AnalysisAddIn_CreateInstance(
233 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
)
235 return static_cast<cppu::OWeakObject
*>(new AnalysisAddIn( comphelper::getComponentContext(xServiceFact
) ));
239 OUString SAL_CALL
AnalysisAddIn::getServiceName() throw( uno::RuntimeException
, std::exception
)
241 // name of specific AddIn service
242 return OUString( MY_SERVICE
);
246 OUString SAL_CALL
AnalysisAddIn::getImplementationName() throw( uno::RuntimeException
, std::exception
)
248 return getImplementationName_Static();
251 sal_Bool SAL_CALL
AnalysisAddIn::supportsService( const OUString
& aName
) throw( uno::RuntimeException
, std::exception
)
253 return cppu::supportsService(this, aName
);
256 uno::Sequence
< OUString
> SAL_CALL
AnalysisAddIn::getSupportedServiceNames() throw( uno::RuntimeException
, std::exception
)
258 return getSupportedServiceNames_Static();
262 void SAL_CALL
AnalysisAddIn::setLocale( const lang::Locale
& eLocale
) throw( uno::RuntimeException
, std::exception
)
266 InitData(); // change of locale invalidates resources!
269 lang::Locale SAL_CALL
AnalysisAddIn::getLocale() throw( uno::RuntimeException
, std::exception
)
275 OUString SAL_CALL
AnalysisAddIn::getProgrammaticFuntionName( const OUString
& ) throw( uno::RuntimeException
, std::exception
)
278 // (but should be implemented for other uses of the AddIn service)
283 OUString SAL_CALL
AnalysisAddIn::getDisplayFunctionName( const OUString
& aProgrammaticName
) throw( uno::RuntimeException
, std::exception
)
287 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
288 if( it
!= pFD
->end() )
290 aRet
= GetDisplFuncStr( it
->GetUINameID() );
293 const OUString
& rSuffix
= it
->GetSuffix();
294 if (!rSuffix
.isEmpty())
302 aRet
= "UNKNOWNFUNC_" + aProgrammaticName
;
308 OUString SAL_CALL
AnalysisAddIn::getFunctionDescription( const OUString
& aProgrammaticName
) throw( uno::RuntimeException
, std::exception
)
312 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
313 if( it
!= pFD
->end() )
314 aRet
= GetFuncDescrStr( it
->GetDescrID(), 1 );
319 OUString SAL_CALL
AnalysisAddIn::getDisplayArgumentName( const OUString
& aName
, sal_Int32 nArg
) throw( uno::RuntimeException
, std::exception
)
323 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
324 if( it
!= pFD
->end() && nArg
<= 0xFFFF )
326 sal_uInt16 nStr
= it
->GetStrIndex( sal_uInt16( nArg
) );
328 aRet
= GetFuncDescrStr( it
->GetDescrID(), nStr
);
336 OUString SAL_CALL
AnalysisAddIn::getArgumentDescription( const OUString
& aName
, sal_Int32 nArg
) throw( uno::RuntimeException
, std::exception
)
340 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
341 if( it
!= pFD
->end() && nArg
<= 0xFFFF )
343 sal_uInt16 nStr
= it
->GetStrIndex( sal_uInt16( nArg
) );
345 aRet
= GetFuncDescrStr( it
->GetDescrID(), nStr
+ 1 );
347 aRet
= "for internal use only";
353 static const char pDefCatName
[] = "Add-In";
355 OUString SAL_CALL
AnalysisAddIn::getProgrammaticCategoryName( const OUString
& aName
) throw( uno::RuntimeException
, std::exception
)
357 // return non-translated strings
358 // return OUString( "Add-In" );
359 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
361 if( it
!= pFD
->end() )
363 switch( it
->GetCategory() )
365 case FDCat_DateTime
: aRet
= "Date&Time"; break;
366 case FDCat_Finance
: aRet
= "Financial"; break;
367 case FDCat_Inf
: aRet
= "Information"; break;
368 case FDCat_Math
: aRet
= "Mathematical"; break;
369 case FDCat_Tech
: aRet
= "Technical"; break;
371 aRet
= pDefCatName
; break;
380 OUString SAL_CALL
AnalysisAddIn::getDisplayCategoryName( const OUString
& aProgrammaticFunctionName
) throw( uno::RuntimeException
, std::exception
)
382 // return translated strings, not used for predefined categories
383 // return OUString( "Add-In" );
384 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticFunctionName
) );
386 if( it
!= pFD
->end() )
388 switch( it
->GetCategory() )
390 case FDCat_DateTime
: aRet
= "Date&Time"; break;
391 case FDCat_Finance
: aRet
= "Financial"; break;
392 case FDCat_Inf
: aRet
= "Information"; break;
393 case FDCat_Math
: aRet
= "Mathematical"; break;
394 case FDCat_Tech
: aRet
= "Technical"; break;
396 aRet
= pDefCatName
; break;
405 static const sal_Char
* pLang
[] = { "de", "en" };
406 static const sal_Char
* pCoun
[] = { "DE", "US" };
407 static const sal_uInt32 nNumOfLoc
= SAL_N_ELEMENTS(pLang
);
409 void AnalysisAddIn::InitDefLocales()
411 pDefLocales
= new lang::Locale
[ nNumOfLoc
];
413 for( sal_uInt32 n
= 0 ; n
< nNumOfLoc
; n
++ )
415 pDefLocales
[ n
].Language
= OUString::createFromAscii( pLang
[ n
] );
416 pDefLocales
[ n
].Country
= OUString::createFromAscii( pCoun
[ n
] );
420 inline const lang::Locale
& AnalysisAddIn::GetLocale( sal_uInt32 nInd
)
425 if( nInd
< sizeof( pLang
) )
426 return pDefLocales
[ nInd
];
431 uno::Sequence
< sheet::LocalizedName
> SAL_CALL
AnalysisAddIn::getCompatibilityNames( const OUString
& aProgrammaticName
) throw( uno::RuntimeException
, std::exception
)
433 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
434 if( it
== pFD
->end() )
435 return uno::Sequence
< sheet::LocalizedName
>( 0 );
437 const std::vector
<OUString
>& r
= it
->GetCompNameList();
438 sal_uInt32 nCount
= r
.size();
440 uno::Sequence
< sheet::LocalizedName
> aRet( nCount
);
442 sheet::LocalizedName
* pArray
= aRet
.getArray();
444 for( sal_uInt32 n
= 0 ; n
< nCount
; n
++ )
446 pArray
[ n
] = sheet::LocalizedName( GetLocale( n
), r
[n
] );
454 sal_Int32 SAL_CALL
AnalysisAddIn::getWorkday( const uno::Reference
< beans::XPropertySet
>& xOptions
,
455 sal_Int32 nDate
, sal_Int32 nDays
, const uno::Any
& aHDay
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
460 sal_Int32 nNullDate
= GetNullDate( xOptions
);
462 SortedIndividualInt32List aSrtLst
;
464 aSrtLst
.InsertHolidayList( aAnyConv
, xOptions
, aHDay
, nNullDate
);
466 sal_Int32 nActDate
= nDate
+ nNullDate
;
470 if( GetDayOfWeek( nActDate
) == 5 )
471 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
478 if( GetDayOfWeek( nActDate
) < 5 )
480 if( !aSrtLst
.Find( nActDate
) )
484 nActDate
++; // jump over weekend
489 if( GetDayOfWeek( nActDate
) == 6 )
490 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
497 if( GetDayOfWeek( nActDate
) < 5 )
499 if( !aSrtLst
.Find( nActDate
) )
503 nActDate
--; // jump over weekend
507 return nActDate
- nNullDate
;
511 double SAL_CALL
AnalysisAddIn::getYearfrac( const uno::Reference
< beans::XPropertySet
>& xOpt
,
512 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& rMode
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
514 double fRet
= GetYearFrac( xOpt
, nStartDate
, nEndDate
, getDateMode( xOpt
, rMode
) );
515 RETURN_FINITE( fRet
);
518 sal_Int32 SAL_CALL
AnalysisAddIn::getEdate( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nStartDate
, sal_Int32 nMonths
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
520 sal_Int32 nNullDate
= GetNullDate( xOpt
);
521 ScaDate
aDate( nNullDate
, nStartDate
, 5 );
522 aDate
.addMonths( nMonths
);
523 return aDate
.getDate( nNullDate
);
526 sal_Int32 SAL_CALL
AnalysisAddIn::getWeeknum( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMode
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
528 nDate
+= GetNullDate( xOpt
);
530 sal_uInt16 nDay
, nMonth
, nYear
;
531 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
533 sal_Int32 nFirstInYear
= DateToDays( 1, 1, nYear
);
534 sal_uInt16 nFirstDayInYear
= GetDayOfWeek( nFirstInYear
);
536 return ( nDate
- nFirstInYear
+ ( ( nMode
== 1 )? ( nFirstDayInYear
+ 1 ) % 7 : nFirstDayInYear
) ) / 7 + 1;
539 sal_Int32 SAL_CALL
AnalysisAddIn::getEomonth( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMonths
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
541 sal_Int32 nNullDate
= GetNullDate( xOpt
);
543 sal_uInt16 nDay
, nMonth
, nYear
;
544 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
546 sal_Int32 nNewMonth
= nMonth
+ nMonths
;
550 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
+ ( nNewMonth
/ 12 ) );
553 else if( nNewMonth
< 1 )
555 nNewMonth
= -nNewMonth
;
556 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
- ( nNewMonth
/ 12 ) );
559 nNewMonth
= 12 - nNewMonth
;
562 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth
), nYear
), sal_uInt16( nNewMonth
), nYear
) - nNullDate
;
565 sal_Int32 SAL_CALL
AnalysisAddIn::getNetworkdays( const uno::Reference
< beans::XPropertySet
>& xOpt
,
566 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& aHDay
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
568 sal_Int32 nNullDate
= GetNullDate( xOpt
);
570 SortedIndividualInt32List aSrtLst
;
572 aSrtLst
.InsertHolidayList( aAnyConv
, xOpt
, aHDay
, nNullDate
);
574 sal_Int32 nActDate
= nStartDate
+ nNullDate
;
575 sal_Int32 nStopDate
= nEndDate
+ nNullDate
;
578 if( nActDate
<= nStopDate
)
580 while( nActDate
<= nStopDate
)
582 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
590 while( nActDate
>= nStopDate
)
592 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
602 sal_Int32 SAL_CALL
AnalysisAddIn::getIseven( sal_Int32 nVal
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
604 return ( nVal
& 0x00000001 )? 0 : 1;
607 sal_Int32 SAL_CALL
AnalysisAddIn::getIsodd( sal_Int32 nVal
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
609 return ( nVal
& 0x00000001 )? 1 : 0;
613 AnalysisAddIn::getMultinomial( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< sal_Int32
> >& aVLst
,
614 const uno::Sequence
< uno::Any
>& aOptVLst
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
616 ScaDoubleListGE0 aValList
;
618 aValList
.Append( aVLst
);
619 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
621 if( aValList
.Count() == 0 )
627 for( sal_uInt32 i
= 0; i
< aValList
.Count(); ++i
)
629 const double d
= aValList
.Get(i
);
630 double n
= (d
>= 0.0) ? rtl::math::approxFloor( d
) : rtl::math::approxCeil( d
);
632 throw lang::IllegalArgumentException();
637 fRet
*= BinomialCoefficient(nZ
, n
);
640 RETURN_FINITE( fRet
);
643 double SAL_CALL
AnalysisAddIn::getSeriessum( double fX
, double fN
, double fM
, const uno::Sequence
< uno::Sequence
< double > >& aCoeffList
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
647 // #i32269# 0^0 is undefined, Excel returns #NUM! error
648 if( fX
== 0.0 && fN
== 0 )
649 throw uno::RuntimeException();
654 sal_Int32 nE1
= aCoeffList
.getLength();
657 for( n1
= 0 ; n1
< nE1
; n1
++ )
659 const uno::Sequence
< double >& rList
= aCoeffList
[ n1
];
660 nE2
= rList
.getLength();
661 const double* pList
= rList
.getConstArray();
663 for( n2
= 0 ; n2
< nE2
; n2
++ )
665 fRet
+= pList
[ n2
] * pow( fX
, fN
);
672 RETURN_FINITE( fRet
);
675 double SAL_CALL
AnalysisAddIn::getQuotient( double fNum
, double fDenom
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
678 if( (fNum
< 0) != (fDenom
< 0) )
679 fRet
= ::rtl::math::approxCeil( fNum
/ fDenom
);
681 fRet
= ::rtl::math::approxFloor( fNum
/ fDenom
);
682 RETURN_FINITE( fRet
);
685 double SAL_CALL
AnalysisAddIn::getMround( double fNum
, double fMult
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
690 double fRet
= fMult
* ::rtl::math::round( fNum
/ fMult
);
691 RETURN_FINITE( fRet
);
694 double SAL_CALL
AnalysisAddIn::getSqrtpi( double fNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
696 double fRet
= sqrt( fNum
* PI
);
697 RETURN_FINITE( fRet
);
700 double SAL_CALL
AnalysisAddIn::getRandbetween( double fMin
, double fMax
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
702 fMin
= ::rtl::math::round( fMin
, 0, rtl_math_RoundingMode_Up
);
703 fMax
= ::rtl::math::round( fMax
, 0, rtl_math_RoundingMode_Up
);
705 throw lang::IllegalArgumentException();
707 double fRet
= floor(comphelper::rng::uniform_real_distribution(fMin
, nextafter(fMax
+1, -DBL_MAX
)));
708 RETURN_FINITE( fRet
);
711 double SAL_CALL
AnalysisAddIn::getGcd( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
713 ScaDoubleListGT0 aValList
;
715 aValList
.Append( aVLst
);
716 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
718 if( aValList
.Count() == 0 )
721 double f
= aValList
.Get(0);
722 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
724 f
= GetGcd( aValList
.Get(i
), f
);
730 double SAL_CALL
AnalysisAddIn::getLcm( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
732 ScaDoubleListGE0 aValList
;
734 aValList
.Append( aVLst
);
735 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
737 if( aValList
.Count() == 0 )
740 double f
= aValList
.Get(0);
745 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
747 double fTmp
= aValList
.Get(i
);
751 f
= fTmp
* f
/ GetGcd( fTmp
, f
);
757 double SAL_CALL
AnalysisAddIn::getBesseli( double fNum
, sal_Int32 nOrder
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, sheet::NoConvergenceException
, std::exception
)
759 double fRet
= sca::analysis::BesselI( fNum
, nOrder
);
760 RETURN_FINITE( fRet
);
763 double SAL_CALL
AnalysisAddIn::getBesselj( double fNum
, sal_Int32 nOrder
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, sheet::NoConvergenceException
, std::exception
)
765 double fRet
= sca::analysis::BesselJ( fNum
, nOrder
);
766 RETURN_FINITE( fRet
);
769 double SAL_CALL
AnalysisAddIn::getBesselk( double fNum
, sal_Int32 nOrder
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, sheet::NoConvergenceException
, std::exception
)
771 if( nOrder
< 0 || fNum
<= 0.0 )
772 throw lang::IllegalArgumentException();
774 double fRet
= sca::analysis::BesselK( fNum
, nOrder
);
775 RETURN_FINITE( fRet
);
778 double SAL_CALL
AnalysisAddIn::getBessely( double fNum
, sal_Int32 nOrder
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, sheet::NoConvergenceException
, std::exception
)
780 if( nOrder
< 0 || fNum
<= 0.0 )
781 throw lang::IllegalArgumentException();
783 double fRet
= sca::analysis::BesselY( fNum
, nOrder
);
784 RETURN_FINITE( fRet
);
787 const double SCA_MAX2
= 511.0; // min. val for binary numbers (9 bits + sign)
788 const double SCA_MIN2
= -SCA_MAX2
-1.0; // min. val for binary numbers (9 bits + sign)
789 const double SCA_MAX8
= 536870911.0; // max. val for octal numbers (29 bits + sign)
790 const double SCA_MIN8
= -SCA_MAX8
-1.0; // min. val for octal numbers (29 bits + sign)
791 const double SCA_MAX16
= 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
792 const double SCA_MIN16
= -SCA_MAX16
-1.0; // min. val for hexadecimal numbers (39 bits + sign)
793 const sal_Int32 SCA_MAXPLACES
= 10; // max. number of places
795 OUString SAL_CALL
AnalysisAddIn::getBin2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
797 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
798 sal_Int32 nPlaces
= 0;
799 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
800 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
803 double SAL_CALL
AnalysisAddIn::getBin2Dec( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
805 double fRet
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
806 RETURN_FINITE( fRet
);
809 OUString SAL_CALL
AnalysisAddIn::getBin2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
811 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
812 sal_Int32 nPlaces
= 0;
813 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
814 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
817 OUString SAL_CALL
AnalysisAddIn::getOct2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
819 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
820 sal_Int32 nPlaces
= 0;
821 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
822 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
825 double SAL_CALL
AnalysisAddIn::getOct2Dec( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
827 double fRet
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
828 RETURN_FINITE( fRet
);
831 OUString SAL_CALL
AnalysisAddIn::getOct2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
833 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
834 sal_Int32 nPlaces
= 0;
835 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
836 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
839 OUString SAL_CALL
AnalysisAddIn::getDec2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
841 sal_Int32 nPlaces
= 0;
842 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
843 return ConvertFromDec( nNum
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
846 OUString SAL_CALL
AnalysisAddIn::getDec2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
848 sal_Int32 nPlaces
= 0;
849 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
850 return ConvertFromDec( nNum
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
853 OUString SAL_CALL
AnalysisAddIn::getDec2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
855 sal_Int32 nPlaces
= 0;
856 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
857 return ConvertFromDec( fNum
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
860 OUString SAL_CALL
AnalysisAddIn::getHex2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
862 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
863 sal_Int32 nPlaces
= 0;
864 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
865 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
868 double SAL_CALL
AnalysisAddIn::getHex2Dec( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
870 double fRet
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
871 RETURN_FINITE( fRet
);
874 OUString SAL_CALL
AnalysisAddIn::getHex2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
876 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
877 sal_Int32 nPlaces
= 0;
878 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
879 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
882 sal_Int32 SAL_CALL
AnalysisAddIn::getDelta( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum1
, const uno::Any
& rNum2
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
884 return sal_Int32(fNum1
== aAnyConv
.getDouble( xOpt
, rNum2
, 0.0 ));
887 double SAL_CALL
AnalysisAddIn::getErf( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fLL
, const uno::Any
& rUL
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
890 bool bContainsValue
= aAnyConv
.getDouble( fUL
, xOpt
, rUL
);
892 fRet
= bContainsValue
? (Erf( fUL
) - Erf( fLL
)) : Erf( fLL
);
893 RETURN_FINITE( fRet
);
896 double SAL_CALL
AnalysisAddIn::getErfc( double f
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
898 double fRet
= Erfc( f
);
899 RETURN_FINITE( fRet
);
902 sal_Int32 SAL_CALL
AnalysisAddIn::getGestep( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rStep
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
904 return sal_Int32(fNum
>= aAnyConv
.getDouble( xOpt
, rStep
, 0.0 ));
907 double SAL_CALL
AnalysisAddIn::getFactdouble( sal_Int32 nNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
909 double fRet
= FactDouble( nNum
);
910 RETURN_FINITE( fRet
);
913 double SAL_CALL
AnalysisAddIn::getImabs( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
915 double fRet
= Complex( aNum
).Abs();
916 RETURN_FINITE( fRet
);
919 double SAL_CALL
AnalysisAddIn::getImaginary( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
921 double fRet
= Complex( aNum
).Imag();
922 RETURN_FINITE( fRet
);
925 OUString SAL_CALL
AnalysisAddIn::getImpower( const OUString
& aNum
, double f
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
931 return z
.GetString();
934 double SAL_CALL
AnalysisAddIn::getImargument( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
936 double fRet
= Complex( aNum
).Arg();
937 RETURN_FINITE( fRet
);
940 OUString SAL_CALL
AnalysisAddIn::getImcos( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
946 return z
.GetString();
949 OUString SAL_CALL
AnalysisAddIn::getImdiv( const OUString
& aDivid
, const OUString
& aDivis
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
953 z
.Div( Complex( aDivis
) );
955 return z
.GetString();
958 OUString SAL_CALL
AnalysisAddIn::getImexp( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
964 return z
.GetString();
967 OUString SAL_CALL
AnalysisAddIn::getImconjugate( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
973 return z
.GetString();
976 OUString SAL_CALL
AnalysisAddIn::getImln( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
982 return z
.GetString();
985 OUString SAL_CALL
AnalysisAddIn::getImlog10( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
991 return z
.GetString();
994 OUString SAL_CALL
AnalysisAddIn::getImlog2( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1000 return z
.GetString();
1003 OUString SAL_CALL
AnalysisAddIn::getImproduct( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aNL
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1007 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
1008 z_list
.Append( aNL
, AH_IgnoreEmpty
);
1010 if( z_list
.empty() )
1011 return Complex( 0 ).GetString();
1013 Complex
z( *(z_list
.Get(0)) );
1014 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
1015 z
.Mult( *(z_list
.Get(i
)) );
1017 return z
.GetString();
1020 double SAL_CALL
AnalysisAddIn::getImreal( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1022 double fRet
= Complex( aNum
).Real();
1023 RETURN_FINITE( fRet
);
1026 OUString SAL_CALL
AnalysisAddIn::getImsin( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1032 return z
.GetString();
1035 OUString SAL_CALL
AnalysisAddIn::getImsub( const OUString
& aNum1
, const OUString
& aNum2
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1039 z
.Sub( Complex( aNum2
) );
1041 return z
.GetString();
1044 OUString SAL_CALL
AnalysisAddIn::getImsum( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aFollowingPars
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1048 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
1049 z_list
.Append( aFollowingPars
, AH_IgnoreEmpty
);
1051 if( z_list
.empty() )
1052 return Complex( 0 ).GetString();
1054 Complex
z( *(z_list
.Get(0)) );
1055 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
1056 z
.Add( *(z_list
.Get(i
)) );
1058 return z
.GetString();
1061 OUString SAL_CALL
AnalysisAddIn::getImsqrt( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1067 return z
.GetString();
1070 OUString SAL_CALL
AnalysisAddIn::getImtan( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1076 return z
.GetString();
1079 OUString SAL_CALL
AnalysisAddIn::getImsec( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1085 return z
.GetString();
1088 OUString SAL_CALL
AnalysisAddIn::getImcsc( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1094 return z
.GetString();
1097 OUString SAL_CALL
AnalysisAddIn::getImcot( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1103 return z
.GetString();
1106 OUString SAL_CALL
AnalysisAddIn::getImsinh( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1112 return z
.GetString();
1115 OUString SAL_CALL
AnalysisAddIn::getImcosh( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1121 return z
.GetString();
1124 OUString SAL_CALL
AnalysisAddIn::getImsech( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1130 return z
.GetString();
1133 OUString SAL_CALL
AnalysisAddIn::getImcsch( const OUString
& aNum
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1139 return z
.GetString();
1142 OUString SAL_CALL
AnalysisAddIn::getComplex( double fR
, double fI
, const uno::Any
& rSuff
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1146 switch( rSuff
.getValueTypeClass() )
1148 case uno::TypeClass_VOID
:
1151 case uno::TypeClass_STRING
:
1153 const OUString
* pSuff
= static_cast<const OUString
*>(rSuff
.getValue());
1154 bi
= *pSuff
== "i" || pSuff
->isEmpty();
1155 if( !bi
&& *pSuff
!= "j" )
1156 throw lang::IllegalArgumentException();
1160 throw lang::IllegalArgumentException();
1163 return Complex( fR
, fI
, bi
? 'i' : 'j' ).GetString();
1166 double SAL_CALL
AnalysisAddIn::getConvert( double f
, const OUString
& aFU
, const OUString
& aTU
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
1169 pCDL
= new ConvertDataList();
1171 double fRet
= pCDL
->Convert( f
, aFU
, aTU
);
1172 RETURN_FINITE( fRet
);
1175 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */