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 <strings.hrc>
23 #include <cppuhelper/factory.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include <comphelper/random.hxx>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <o3tl/any.hxx>
28 #include <rtl/ustrbuf.hxx>
29 #include <rtl/math.hxx>
30 #include <sal/macros.h>
32 #include <unotools/resmgr.hxx>
36 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
37 #define MY_SERVICE "com.sun.star.sheet.addin.Analysis"
38 #define MY_IMPLNAME "com.sun.star.sheet.addin.AnalysisImpl"
40 using namespace ::com::sun::star
;
41 using namespace sca::analysis
;
44 extern "C" SAL_DLLPUBLIC_EXPORT
void* SAL_CALL
analysis_component_getFactory(
45 const sal_Char
* pImplName
, void* pServiceManager
, void* /*pRegistryKey*/ )
49 if( pServiceManager
&& OUString::createFromAscii( pImplName
) == AnalysisAddIn::getImplementationName_Static() )
51 uno::Reference
< lang::XSingleServiceFactory
> xFactory( cppu::createOneInstanceFactory(
52 static_cast< lang::XMultiServiceFactory
* >( pServiceManager
),
53 AnalysisAddIn::getImplementationName_Static(),
54 AnalysisAddIn_CreateInstance
,
55 AnalysisAddIn::getSupportedServiceNames_Static() ) );
60 pRet
= xFactory
.get();
67 OUString
AnalysisAddIn::GetFuncDescrStr(const char** pResId
, sal_uInt16 nStrIndex
)
69 return AnalysisResId(pResId
[nStrIndex
- 1]);
72 void AnalysisAddIn::InitData()
74 aResLocale
= Translate::Create("sca", LanguageTag(aFuncLoc
));
77 pFD
= new FuncDataList
;
78 InitFuncDataList(*pFD
);
81 pDefLocales
= nullptr;
84 AnalysisAddIn::AnalysisAddIn( const uno::Reference
< uno::XComponentContext
>& xContext
) :
85 pDefLocales( nullptr ),
87 pFactDoubles( nullptr ),
93 AnalysisAddIn::~AnalysisAddIn()
100 sal_Int32
AnalysisAddIn::getDateMode(
101 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
102 const uno::Any
& rAny
)
104 sal_Int32 nMode
= aAnyConv
.getInt32( xPropSet
, rAny
, 0 );
105 if( (nMode
< 0) || (nMode
> 4) )
106 throw lang::IllegalArgumentException();
110 #define MAXFACTDOUBLE 300
112 double AnalysisAddIn::FactDouble( sal_Int32 nNum
)
114 if( nNum
< 0 || nNum
> MAXFACTDOUBLE
)
115 throw lang::IllegalArgumentException();
119 pFactDoubles
.reset( new double[ MAXFACTDOUBLE
+ 1 ] );
121 pFactDoubles
[ 0 ] = 1.0; // by default
126 pFactDoubles
[ 1 ] = fOdd
;
127 pFactDoubles
[ 2 ] = fEven
;
131 for( sal_uInt16 nCnt
= 3 ; nCnt
<= MAXFACTDOUBLE
; nCnt
++ )
136 pFactDoubles
[ nCnt
] = fOdd
;
141 pFactDoubles
[ nCnt
] = fEven
;
149 return pFactDoubles
[ nNum
];
152 OUString
AnalysisAddIn::getImplementationName_Static()
154 return OUString( MY_IMPLNAME
);
157 uno::Sequence
< OUString
> AnalysisAddIn::getSupportedServiceNames_Static()
159 uno::Sequence
< OUString
> aRet(2);
160 OUString
* pArray
= aRet
.getArray();
161 pArray
[0] = ADDIN_SERVICE
;
162 pArray
[1] = MY_SERVICE
;
166 uno::Reference
< uno::XInterface
> SAL_CALL
AnalysisAddIn_CreateInstance(
167 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
)
169 return static_cast<cppu::OWeakObject
*>(new AnalysisAddIn( comphelper::getComponentContext(xServiceFact
) ));
173 OUString SAL_CALL
AnalysisAddIn::getServiceName()
175 // name of specific AddIn service
176 return OUString( MY_SERVICE
);
180 OUString SAL_CALL
AnalysisAddIn::getImplementationName()
182 return getImplementationName_Static();
185 sal_Bool SAL_CALL
AnalysisAddIn::supportsService( const OUString
& aName
)
187 return cppu::supportsService(this, aName
);
190 uno::Sequence
< OUString
> SAL_CALL
AnalysisAddIn::getSupportedServiceNames()
192 return getSupportedServiceNames_Static();
196 void SAL_CALL
AnalysisAddIn::setLocale( const lang::Locale
& eLocale
)
200 InitData(); // change of locale invalidates resources!
203 lang::Locale SAL_CALL
AnalysisAddIn::getLocale()
209 OUString SAL_CALL
AnalysisAddIn::getProgrammaticFuntionName( const OUString
& )
212 // (but should be implemented for other uses of the AddIn service)
217 OUString SAL_CALL
AnalysisAddIn::getDisplayFunctionName( const OUString
& aProgrammaticName
)
221 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
222 if( it
!= pFD
->end() )
224 aRet
= AnalysisResId(it
->GetUINameID());
227 const OUString
& rSuffix
= it
->GetSuffix();
228 if (!rSuffix
.isEmpty())
236 aRet
= "UNKNOWNFUNC_" + aProgrammaticName
;
242 OUString SAL_CALL
AnalysisAddIn::getFunctionDescription( const OUString
& aProgrammaticName
)
246 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
247 if( it
!= pFD
->end() )
248 aRet
= GetFuncDescrStr( it
->GetDescrID(), 1 );
253 OUString SAL_CALL
AnalysisAddIn::getDisplayArgumentName( const OUString
& aName
, sal_Int32 nArg
)
257 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
258 if( it
!= pFD
->end() && nArg
<= 0xFFFF )
260 sal_uInt16 nStr
= it
->GetStrIndex( sal_uInt16( nArg
) );
262 aRet
= GetFuncDescrStr( it
->GetDescrID(), nStr
);
270 OUString SAL_CALL
AnalysisAddIn::getArgumentDescription( const OUString
& aName
, sal_Int32 nArg
)
274 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
275 if( it
!= pFD
->end() && nArg
<= 0xFFFF )
277 sal_uInt16 nStr
= it
->GetStrIndex( sal_uInt16( nArg
) );
279 aRet
= GetFuncDescrStr( it
->GetDescrID(), nStr
+ 1 );
281 aRet
= "for internal use only";
287 static const char pDefCatName
[] = "Add-In";
289 OUString SAL_CALL
AnalysisAddIn::getProgrammaticCategoryName( const OUString
& aName
)
291 // return non-translated strings
292 // return OUString( "Add-In" );
293 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
295 if( it
!= pFD
->end() )
297 switch( it
->GetCategory() )
299 case FDCategory::DateTime
: aRet
= "Date&Time"; break;
300 case FDCategory::Finance
: aRet
= "Financial"; break;
301 case FDCategory::Inf
: aRet
= "Information"; break;
302 case FDCategory::Math
: aRet
= "Mathematical"; break;
303 case FDCategory::Tech
: aRet
= "Technical"; break;
312 OUString SAL_CALL
AnalysisAddIn::getDisplayCategoryName( const OUString
& aProgrammaticFunctionName
)
314 // return translated strings, not used for predefined categories
315 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticFunctionName
) );
317 if( it
!= pFD
->end() )
319 switch( it
->GetCategory() )
321 case FDCategory::DateTime
: aRet
= "Date&Time"; break;
322 case FDCategory::Finance
: aRet
= "Financial"; break;
323 case FDCategory::Inf
: aRet
= "Information"; break;
324 case FDCategory::Math
: aRet
= "Mathematical"; break;
325 case FDCategory::Tech
: aRet
= "Technical"; break;
334 static const sal_Char
* pLang
[] = { "de", "en" };
335 static const sal_Char
* pCoun
[] = { "DE", "US" };
336 static const sal_uInt32 nNumOfLoc
= SAL_N_ELEMENTS(pLang
);
338 void AnalysisAddIn::InitDefLocales()
340 pDefLocales
= new lang::Locale
[ nNumOfLoc
];
342 for( sal_uInt32 n
= 0 ; n
< nNumOfLoc
; n
++ )
344 pDefLocales
[ n
].Language
= OUString::createFromAscii( pLang
[ n
] );
345 pDefLocales
[ n
].Country
= OUString::createFromAscii( pCoun
[ n
] );
349 inline const lang::Locale
& AnalysisAddIn::GetLocale( sal_uInt32 nInd
)
354 if( nInd
< sizeof( pLang
) )
355 return pDefLocales
[ nInd
];
360 uno::Sequence
< sheet::LocalizedName
> SAL_CALL
AnalysisAddIn::getCompatibilityNames( const OUString
& aProgrammaticName
)
362 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
363 if( it
== pFD
->end() )
364 return uno::Sequence
< sheet::LocalizedName
>( 0 );
366 const std::vector
<OUString
>& r
= it
->GetCompNameList();
367 sal_uInt32 nCount
= r
.size();
369 uno::Sequence
< sheet::LocalizedName
> aRet( nCount
);
371 sheet::LocalizedName
* pArray
= aRet
.getArray();
373 for( sal_uInt32 n
= 0 ; n
< nCount
; n
++ )
375 pArray
[ n
] = sheet::LocalizedName( GetLocale( n
), r
[n
] );
383 sal_Int32 SAL_CALL
AnalysisAddIn::getWorkday( const uno::Reference
< beans::XPropertySet
>& xOptions
,
384 sal_Int32 nDate
, sal_Int32 nDays
, const uno::Any
& aHDay
)
389 sal_Int32 nNullDate
= GetNullDate( xOptions
);
391 SortedIndividualInt32List aSrtLst
;
393 aSrtLst
.InsertHolidayList( aAnyConv
, xOptions
, aHDay
, nNullDate
);
395 sal_Int32 nActDate
= nDate
+ nNullDate
;
399 if( GetDayOfWeek( nActDate
) == 5 )
400 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
407 if( GetDayOfWeek( nActDate
) < 5 )
409 if( !aSrtLst
.Find( nActDate
) )
413 nActDate
++; // jump over weekend
418 if( GetDayOfWeek( nActDate
) == 6 )
419 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
426 if( GetDayOfWeek( nActDate
) < 5 )
428 if( !aSrtLst
.Find( nActDate
) )
432 nActDate
--; // jump over weekend
436 return nActDate
- nNullDate
;
440 double SAL_CALL
AnalysisAddIn::getYearfrac( const uno::Reference
< beans::XPropertySet
>& xOpt
,
441 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& rMode
)
443 double fRet
= GetYearFrac( xOpt
, nStartDate
, nEndDate
, getDateMode( xOpt
, rMode
) );
444 RETURN_FINITE( fRet
);
447 sal_Int32 SAL_CALL
AnalysisAddIn::getEdate( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nStartDate
, sal_Int32 nMonths
)
449 sal_Int32 nNullDate
= GetNullDate( xOpt
);
450 ScaDate
aDate( nNullDate
, nStartDate
, 5 );
451 aDate
.addMonths( nMonths
);
452 return aDate
.getDate( nNullDate
);
455 sal_Int32 SAL_CALL
AnalysisAddIn::getWeeknum( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMode
)
457 nDate
+= GetNullDate( xOpt
);
459 sal_uInt16 nDay
, nMonth
, nYear
;
460 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
462 sal_Int32 nFirstInYear
= DateToDays( 1, 1, nYear
);
463 sal_uInt16 nFirstDayInYear
= GetDayOfWeek( nFirstInYear
);
465 return ( nDate
- nFirstInYear
+ ( ( nMode
== 1 )? ( nFirstDayInYear
+ 1 ) % 7 : nFirstDayInYear
) ) / 7 + 1;
468 sal_Int32 SAL_CALL
AnalysisAddIn::getEomonth( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMonths
)
470 sal_Int32 nNullDate
= GetNullDate( xOpt
);
472 sal_uInt16 nDay
, nMonth
, nYear
;
473 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
475 sal_Int32 nNewMonth
= nMonth
+ nMonths
;
479 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
+ ( nNewMonth
/ 12 ) );
482 else if( nNewMonth
< 1 )
484 nNewMonth
= -nNewMonth
;
485 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
- ( nNewMonth
/ 12 ) );
488 nNewMonth
= 12 - nNewMonth
;
491 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth
), nYear
), sal_uInt16( nNewMonth
), nYear
) - nNullDate
;
494 sal_Int32 SAL_CALL
AnalysisAddIn::getNetworkdays( const uno::Reference
< beans::XPropertySet
>& xOpt
,
495 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& aHDay
)
497 sal_Int32 nNullDate
= GetNullDate( xOpt
);
499 SortedIndividualInt32List aSrtLst
;
501 aSrtLst
.InsertHolidayList( aAnyConv
, xOpt
, aHDay
, nNullDate
);
503 sal_Int32 nActDate
= nStartDate
+ nNullDate
;
504 sal_Int32 nStopDate
= nEndDate
+ nNullDate
;
507 if( nActDate
<= nStopDate
)
509 while( nActDate
<= nStopDate
)
511 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
519 while( nActDate
>= nStopDate
)
521 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
531 sal_Int32 SAL_CALL
AnalysisAddIn::getIseven( sal_Int32 nVal
)
533 return ( nVal
& 0x00000001 )? 0 : 1;
536 sal_Int32 SAL_CALL
AnalysisAddIn::getIsodd( sal_Int32 nVal
)
538 return ( nVal
& 0x00000001 )? 1 : 0;
542 AnalysisAddIn::getMultinomial( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< sal_Int32
> >& aVLst
,
543 const uno::Sequence
< uno::Any
>& aOptVLst
)
545 ScaDoubleListGE0 aValList
;
547 aValList
.Append( aVLst
);
548 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
550 if( aValList
.Count() == 0 )
556 for( sal_uInt32 i
= 0; i
< aValList
.Count(); ++i
)
558 const double d
= aValList
.Get(i
);
559 double n
= (d
>= 0.0) ? rtl::math::approxFloor( d
) : rtl::math::approxCeil( d
);
561 throw lang::IllegalArgumentException();
566 fRet
*= BinomialCoefficient(nZ
, n
);
569 RETURN_FINITE( fRet
);
572 double SAL_CALL
AnalysisAddIn::getSeriessum( double fX
, double fN
, double fM
, const uno::Sequence
< uno::Sequence
< double > >& aCoeffList
)
576 // #i32269# 0^0 is undefined, Excel returns #NUM! error
577 if( fX
== 0.0 && fN
== 0 )
578 throw uno::RuntimeException();
583 sal_Int32 nE1
= aCoeffList
.getLength();
586 for( n1
= 0 ; n1
< nE1
; n1
++ )
588 const uno::Sequence
< double >& rList
= aCoeffList
[ n1
];
589 nE2
= rList
.getLength();
590 const double* pList
= rList
.getConstArray();
592 for( n2
= 0 ; n2
< nE2
; n2
++ )
594 fRet
+= pList
[ n2
] * pow( fX
, fN
);
601 RETURN_FINITE( fRet
);
604 double SAL_CALL
AnalysisAddIn::getQuotient( double fNum
, double fDenom
)
607 if( (fNum
< 0) != (fDenom
< 0) )
608 fRet
= ::rtl::math::approxCeil( fNum
/ fDenom
);
610 fRet
= ::rtl::math::approxFloor( fNum
/ fDenom
);
611 RETURN_FINITE( fRet
);
614 double SAL_CALL
AnalysisAddIn::getMround( double fNum
, double fMult
)
619 double fRet
= fMult
* ::rtl::math::round( fNum
/ fMult
);
620 RETURN_FINITE( fRet
);
623 double SAL_CALL
AnalysisAddIn::getSqrtpi( double fNum
)
625 double fRet
= sqrt( fNum
* PI
);
626 RETURN_FINITE( fRet
);
629 double SAL_CALL
AnalysisAddIn::getRandbetween( double fMin
, double fMax
)
631 fMin
= ::rtl::math::round( fMin
, 0, rtl_math_RoundingMode_Up
);
632 fMax
= ::rtl::math::round( fMax
, 0, rtl_math_RoundingMode_Up
);
634 throw lang::IllegalArgumentException();
636 double fRet
= floor(comphelper::rng::uniform_real_distribution(fMin
, nextafter(fMax
+1, -DBL_MAX
)));
637 RETURN_FINITE( fRet
);
640 double SAL_CALL
AnalysisAddIn::getGcd( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
)
642 ScaDoubleListGT0 aValList
;
644 aValList
.Append( aVLst
);
645 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
647 if( aValList
.Count() == 0 )
650 double f
= aValList
.Get(0);
651 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
653 f
= GetGcd( aValList
.Get(i
), f
);
659 double SAL_CALL
AnalysisAddIn::getLcm( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
)
661 ScaDoubleListGE0 aValList
;
663 aValList
.Append( aVLst
);
664 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
666 if( aValList
.Count() == 0 )
669 double f
= rtl::math::approxFloor( aValList
.Get(0) );
671 throw lang::IllegalArgumentException();
676 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
678 double fTmp
= rtl::math::approxFloor( aValList
.Get(i
) );
680 throw lang::IllegalArgumentException();
682 f
= fTmp
* f
/ GetGcd( fTmp
, f
);
690 double SAL_CALL
AnalysisAddIn::getBesseli( double fNum
, sal_Int32 nOrder
)
692 double fRet
= sca::analysis::BesselI( fNum
, nOrder
);
693 RETURN_FINITE( fRet
);
696 double SAL_CALL
AnalysisAddIn::getBesselj( double fNum
, sal_Int32 nOrder
)
698 double fRet
= sca::analysis::BesselJ( fNum
, nOrder
);
699 RETURN_FINITE( fRet
);
702 double SAL_CALL
AnalysisAddIn::getBesselk( double fNum
, sal_Int32 nOrder
)
704 if( nOrder
< 0 || fNum
<= 0.0 )
705 throw lang::IllegalArgumentException();
707 double fRet
= sca::analysis::BesselK( fNum
, nOrder
);
708 RETURN_FINITE( fRet
);
711 double SAL_CALL
AnalysisAddIn::getBessely( double fNum
, sal_Int32 nOrder
)
713 if( nOrder
< 0 || fNum
<= 0.0 )
714 throw lang::IllegalArgumentException();
716 double fRet
= sca::analysis::BesselY( fNum
, nOrder
);
717 RETURN_FINITE( fRet
);
720 const double SCA_MAX2
= 511.0; // min. val for binary numbers (9 bits + sign)
721 const double SCA_MIN2
= -SCA_MAX2
-1.0; // min. val for binary numbers (9 bits + sign)
722 const double SCA_MAX8
= 536870911.0; // max. val for octal numbers (29 bits + sign)
723 const double SCA_MIN8
= -SCA_MAX8
-1.0; // min. val for octal numbers (29 bits + sign)
724 const double SCA_MAX16
= 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
725 const double SCA_MIN16
= -SCA_MAX16
-1.0; // min. val for hexadecimal numbers (39 bits + sign)
726 const sal_Int32 SCA_MAXPLACES
= 10; // max. number of places
728 OUString SAL_CALL
AnalysisAddIn::getBin2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
730 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
731 sal_Int32 nPlaces
= 0;
732 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
733 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
736 double SAL_CALL
AnalysisAddIn::getBin2Dec( const OUString
& aNum
)
738 double fRet
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
739 RETURN_FINITE( fRet
);
742 OUString SAL_CALL
AnalysisAddIn::getBin2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
744 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
745 sal_Int32 nPlaces
= 0;
746 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
747 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
750 OUString SAL_CALL
AnalysisAddIn::getOct2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
752 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
753 sal_Int32 nPlaces
= 0;
754 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
755 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
758 double SAL_CALL
AnalysisAddIn::getOct2Dec( const OUString
& aNum
)
760 double fRet
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
761 RETURN_FINITE( fRet
);
764 OUString SAL_CALL
AnalysisAddIn::getOct2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
766 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
767 sal_Int32 nPlaces
= 0;
768 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
769 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
772 OUString SAL_CALL
AnalysisAddIn::getDec2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
)
774 sal_Int32 nPlaces
= 0;
775 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
776 return ConvertFromDec( nNum
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
779 OUString SAL_CALL
AnalysisAddIn::getDec2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
)
781 sal_Int32 nPlaces
= 0;
782 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
783 return ConvertFromDec( nNum
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
786 OUString SAL_CALL
AnalysisAddIn::getDec2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rPlaces
)
788 sal_Int32 nPlaces
= 0;
789 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
790 return ConvertFromDec( fNum
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
793 OUString SAL_CALL
AnalysisAddIn::getHex2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
795 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
796 sal_Int32 nPlaces
= 0;
797 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
798 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
801 double SAL_CALL
AnalysisAddIn::getHex2Dec( const OUString
& aNum
)
803 double fRet
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
804 RETURN_FINITE( fRet
);
807 OUString SAL_CALL
AnalysisAddIn::getHex2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
809 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
810 sal_Int32 nPlaces
= 0;
811 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
812 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
815 sal_Int32 SAL_CALL
AnalysisAddIn::getDelta( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum1
, const uno::Any
& rNum2
)
817 return sal_Int32(fNum1
== aAnyConv
.getDouble( xOpt
, rNum2
, 0.0 ));
820 double SAL_CALL
AnalysisAddIn::getErf( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fLL
, const uno::Any
& rUL
)
823 bool bContainsValue
= aAnyConv
.getDouble( fUL
, xOpt
, rUL
);
825 fRet
= bContainsValue
? (Erf( fUL
) - Erf( fLL
)) : Erf( fLL
);
826 RETURN_FINITE( fRet
);
829 double SAL_CALL
AnalysisAddIn::getErfc( double f
)
831 double fRet
= Erfc( f
);
832 RETURN_FINITE( fRet
);
835 sal_Int32 SAL_CALL
AnalysisAddIn::getGestep( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rStep
)
837 return sal_Int32(fNum
>= aAnyConv
.getDouble( xOpt
, rStep
, 0.0 ));
840 double SAL_CALL
AnalysisAddIn::getFactdouble( sal_Int32 nNum
)
842 double fRet
= FactDouble( nNum
);
843 RETURN_FINITE( fRet
);
846 double SAL_CALL
AnalysisAddIn::getImabs( const OUString
& aNum
)
848 double fRet
= Complex( aNum
).Abs();
849 RETURN_FINITE( fRet
);
852 double SAL_CALL
AnalysisAddIn::getImaginary( const OUString
& aNum
)
854 double fRet
= Complex( aNum
).Imag();
855 RETURN_FINITE( fRet
);
858 OUString SAL_CALL
AnalysisAddIn::getImpower( const OUString
& aNum
, double f
)
864 return z
.GetString();
867 double SAL_CALL
AnalysisAddIn::getImargument( const OUString
& aNum
)
869 double fRet
= Complex( aNum
).Arg();
870 RETURN_FINITE( fRet
);
873 OUString SAL_CALL
AnalysisAddIn::getImcos( const OUString
& aNum
)
879 return z
.GetString();
882 OUString SAL_CALL
AnalysisAddIn::getImdiv( const OUString
& aDivid
, const OUString
& aDivis
)
886 z
.Div( Complex( aDivis
) );
888 return z
.GetString();
891 OUString SAL_CALL
AnalysisAddIn::getImexp( const OUString
& aNum
)
897 return z
.GetString();
900 OUString SAL_CALL
AnalysisAddIn::getImconjugate( const OUString
& aNum
)
906 return z
.GetString();
909 OUString SAL_CALL
AnalysisAddIn::getImln( const OUString
& aNum
)
915 return z
.GetString();
918 OUString SAL_CALL
AnalysisAddIn::getImlog10( const OUString
& aNum
)
924 return z
.GetString();
927 OUString SAL_CALL
AnalysisAddIn::getImlog2( const OUString
& aNum
)
933 return z
.GetString();
936 OUString SAL_CALL
AnalysisAddIn::getImproduct( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aNL
)
940 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
941 z_list
.Append( aNL
, AH_IgnoreEmpty
);
944 return Complex( 0 ).GetString();
946 Complex z
= z_list
.Get(0);
947 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
948 z
.Mult( z_list
.Get(i
) );
950 return z
.GetString();
953 double SAL_CALL
AnalysisAddIn::getImreal( const OUString
& aNum
)
955 double fRet
= Complex( aNum
).Real();
956 RETURN_FINITE( fRet
);
959 OUString SAL_CALL
AnalysisAddIn::getImsin( const OUString
& aNum
)
965 return z
.GetString();
968 OUString SAL_CALL
AnalysisAddIn::getImsub( const OUString
& aNum1
, const OUString
& aNum2
)
972 z
.Sub( Complex( aNum2
) );
974 return z
.GetString();
977 OUString SAL_CALL
AnalysisAddIn::getImsum( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aFollowingPars
)
981 z_list
.Append( aNum1
, AH_IgnoreEmpty
);
982 z_list
.Append( aFollowingPars
, AH_IgnoreEmpty
);
985 return Complex( 0 ).GetString();
987 Complex
z( z_list
.Get(0) );
988 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
989 z
.Add( z_list
.Get(i
) );
991 return z
.GetString();
994 OUString SAL_CALL
AnalysisAddIn::getImsqrt( const OUString
& aNum
)
1000 return z
.GetString();
1003 OUString SAL_CALL
AnalysisAddIn::getImtan( const OUString
& aNum
)
1009 return z
.GetString();
1012 OUString SAL_CALL
AnalysisAddIn::getImsec( const OUString
& aNum
)
1018 return z
.GetString();
1021 OUString SAL_CALL
AnalysisAddIn::getImcsc( const OUString
& aNum
)
1027 return z
.GetString();
1030 OUString SAL_CALL
AnalysisAddIn::getImcot( const OUString
& aNum
)
1036 return z
.GetString();
1039 OUString SAL_CALL
AnalysisAddIn::getImsinh( const OUString
& aNum
)
1045 return z
.GetString();
1048 OUString SAL_CALL
AnalysisAddIn::getImcosh( const OUString
& aNum
)
1054 return z
.GetString();
1057 OUString SAL_CALL
AnalysisAddIn::getImsech( const OUString
& aNum
)
1063 return z
.GetString();
1066 OUString SAL_CALL
AnalysisAddIn::getImcsch( const OUString
& aNum
)
1072 return z
.GetString();
1075 OUString SAL_CALL
AnalysisAddIn::getComplex( double fR
, double fI
, const uno::Any
& rSuff
)
1079 switch( rSuff
.getValueTypeClass() )
1081 case uno::TypeClass_VOID
:
1084 case uno::TypeClass_STRING
:
1086 auto pSuff
= o3tl::forceAccess
<OUString
>(rSuff
);
1087 bi
= *pSuff
== "i" || pSuff
->isEmpty();
1088 if( !bi
&& *pSuff
!= "j" )
1089 throw lang::IllegalArgumentException();
1093 throw lang::IllegalArgumentException();
1096 return Complex( fR
, fI
, bi
? 'i' : 'j' ).GetString();
1099 double SAL_CALL
AnalysisAddIn::getConvert( double f
, const OUString
& aFU
, const OUString
& aTU
)
1102 pCDL
= new ConvertDataList();
1104 double fRet
= pCDL
->Convert( f
, aFU
, aTU
);
1105 RETURN_FINITE( fRet
);
1108 OUString
AnalysisAddIn::AnalysisResId(const char* pResId
)
1110 return Translate::get(pResId
, aResLocale
);
1113 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */