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 "analysisdefs.hxx"
21 #include "analysis.hxx"
23 #include <cppuhelper/factory.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include <comphelper/random.hxx>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
28 #include <o3tl/any.hxx>
29 #include <rtl/math.hxx>
30 #include <sal/macros.h>
31 #include <unotools/resmgr.hxx>
32 #include <i18nlangtag/languagetag.hxx>
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* 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 OUString
AnalysisAddIn::GetFuncDescrStr(const char** pResId
, sal_uInt16 nStrIndex
)
70 return AnalysisResId(pResId
[nStrIndex
- 1]);
73 void AnalysisAddIn::InitData()
75 aResLocale
= Translate::Create("sca", LanguageTag(aFuncLoc
));
77 pFD
.reset(new FuncDataList
);
78 InitFuncDataList(*pFD
);
83 AnalysisAddIn::AnalysisAddIn( const uno::Reference
< uno::XComponentContext
>& xContext
) :
88 AnalysisAddIn::~AnalysisAddIn()
92 sal_Int32
AnalysisAddIn::getDateMode(
93 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
94 const uno::Any
& rAny
)
96 sal_Int32 nMode
= aAnyConv
.getInt32( xPropSet
, rAny
, 0 );
97 if( (nMode
< 0) || (nMode
> 4) )
98 throw lang::IllegalArgumentException();
102 #define MAXFACTDOUBLE 300
104 double AnalysisAddIn::FactDouble( sal_Int32 nNum
)
106 if( nNum
< 0 || nNum
> MAXFACTDOUBLE
)
107 throw lang::IllegalArgumentException();
111 pFactDoubles
.reset( new double[ MAXFACTDOUBLE
+ 1 ] );
113 pFactDoubles
[ 0 ] = 1.0; // by default
118 pFactDoubles
[ 1 ] = fOdd
;
119 pFactDoubles
[ 2 ] = fEven
;
123 for( sal_uInt16 nCnt
= 3 ; nCnt
<= MAXFACTDOUBLE
; nCnt
++ )
128 pFactDoubles
[ nCnt
] = fOdd
;
133 pFactDoubles
[ nCnt
] = fEven
;
141 return pFactDoubles
[ nNum
];
144 OUString
AnalysisAddIn::getImplementationName_Static()
146 return OUString( MY_IMPLNAME
);
149 uno::Sequence
< OUString
> AnalysisAddIn::getSupportedServiceNames_Static()
151 uno::Sequence
< OUString
> aRet(2);
152 OUString
* pArray
= aRet
.getArray();
153 pArray
[0] = ADDIN_SERVICE
;
154 pArray
[1] = MY_SERVICE
;
158 uno::Reference
< uno::XInterface
> AnalysisAddIn_CreateInstance(
159 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
)
161 return static_cast<cppu::OWeakObject
*>(new AnalysisAddIn( comphelper::getComponentContext(xServiceFact
) ));
165 OUString SAL_CALL
AnalysisAddIn::getServiceName()
167 // name of specific AddIn service
168 return OUString( MY_SERVICE
);
172 OUString SAL_CALL
AnalysisAddIn::getImplementationName()
174 return getImplementationName_Static();
177 sal_Bool SAL_CALL
AnalysisAddIn::supportsService( const OUString
& aName
)
179 return cppu::supportsService(this, aName
);
182 uno::Sequence
< OUString
> SAL_CALL
AnalysisAddIn::getSupportedServiceNames()
184 return getSupportedServiceNames_Static();
188 void SAL_CALL
AnalysisAddIn::setLocale( const lang::Locale
& eLocale
)
192 InitData(); // change of locale invalidates resources!
195 lang::Locale SAL_CALL
AnalysisAddIn::getLocale()
201 OUString SAL_CALL
AnalysisAddIn::getProgrammaticFuntionName( const OUString
& )
204 // (but should be implemented for other uses of the AddIn service)
209 OUString SAL_CALL
AnalysisAddIn::getDisplayFunctionName( const OUString
& aProgrammaticName
)
213 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
214 if( it
!= pFD
->end() )
216 aRet
= AnalysisResId(it
->GetUINameID());
219 const OUString
& rSuffix
= it
->GetSuffix();
220 if (!rSuffix
.isEmpty())
228 aRet
= "UNKNOWNFUNC_" + aProgrammaticName
;
234 OUString SAL_CALL
AnalysisAddIn::getFunctionDescription( const OUString
& aProgrammaticName
)
238 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
239 if( it
!= pFD
->end() )
240 aRet
= GetFuncDescrStr( it
->GetDescrID(), 1 );
245 OUString SAL_CALL
AnalysisAddIn::getDisplayArgumentName( const OUString
& aName
, sal_Int32 nArg
)
249 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
250 if( it
!= pFD
->end() && nArg
<= 0xFFFF )
252 sal_uInt16 nStr
= it
->GetStrIndex( sal_uInt16( nArg
) );
254 aRet
= GetFuncDescrStr( it
->GetDescrID(), nStr
);
262 OUString SAL_CALL
AnalysisAddIn::getArgumentDescription( const OUString
& aName
, sal_Int32 nArg
)
266 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
267 if( it
!= pFD
->end() && nArg
<= 0xFFFF )
269 sal_uInt16 nStr
= it
->GetStrIndex( sal_uInt16( nArg
) );
271 aRet
= GetFuncDescrStr( it
->GetDescrID(), nStr
+ 1 );
273 aRet
= "for internal use only";
279 static const char pDefCatName
[] = "Add-In";
281 OUString SAL_CALL
AnalysisAddIn::getProgrammaticCategoryName( const OUString
& aName
)
283 // return non-translated strings
284 // return OUString( "Add-In" );
285 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
287 if( it
!= pFD
->end() )
289 switch( it
->GetCategory() )
291 case FDCategory::DateTime
: aRet
= "Date&Time"; break;
292 case FDCategory::Finance
: aRet
= "Financial"; break;
293 case FDCategory::Inf
: aRet
= "Information"; break;
294 case FDCategory::Math
: aRet
= "Mathematical"; break;
295 case FDCategory::Tech
: aRet
= "Technical"; break;
304 OUString SAL_CALL
AnalysisAddIn::getDisplayCategoryName( const OUString
& aProgrammaticFunctionName
)
306 // return translated strings, not used for predefined categories
307 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticFunctionName
) );
309 if( it
!= pFD
->end() )
311 switch( it
->GetCategory() )
313 case FDCategory::DateTime
: aRet
= "Date&Time"; break;
314 case FDCategory::Finance
: aRet
= "Financial"; break;
315 case FDCategory::Inf
: aRet
= "Information"; break;
316 case FDCategory::Math
: aRet
= "Mathematical"; break;
317 case FDCategory::Tech
: aRet
= "Technical"; break;
326 static const sal_Char
* pLang
[] = { "de", "en" };
327 static const sal_Char
* pCoun
[] = { "DE", "US" };
328 static const sal_uInt32 nNumOfLoc
= SAL_N_ELEMENTS(pLang
);
330 void AnalysisAddIn::InitDefLocales()
332 pDefLocales
.reset( new lang::Locale
[ nNumOfLoc
] );
334 for( sal_uInt32 n
= 0 ; n
< nNumOfLoc
; n
++ )
336 pDefLocales
[ n
].Language
= OUString::createFromAscii( pLang
[ n
] );
337 pDefLocales
[ n
].Country
= OUString::createFromAscii( pCoun
[ n
] );
341 inline const lang::Locale
& AnalysisAddIn::GetLocale( sal_uInt32 nInd
)
346 if( nInd
< sizeof( pLang
) )
347 return pDefLocales
[ nInd
];
352 uno::Sequence
< sheet::LocalizedName
> SAL_CALL
AnalysisAddIn::getCompatibilityNames( const OUString
& aProgrammaticName
)
354 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
355 if( it
== pFD
->end() )
356 return uno::Sequence
< sheet::LocalizedName
>( 0 );
358 const std::vector
<OUString
>& r
= it
->GetCompNameList();
359 sal_uInt32 nCount
= r
.size();
361 uno::Sequence
< sheet::LocalizedName
> aRet( nCount
);
363 sheet::LocalizedName
* pArray
= aRet
.getArray();
365 for( sal_uInt32 n
= 0 ; n
< nCount
; n
++ )
367 pArray
[ n
] = sheet::LocalizedName( GetLocale( n
), r
[n
] );
375 sal_Int32 SAL_CALL
AnalysisAddIn::getWorkday( const uno::Reference
< beans::XPropertySet
>& xOptions
,
376 sal_Int32 nDate
, sal_Int32 nDays
, const uno::Any
& aHDay
)
381 sal_Int32 nNullDate
= GetNullDate( xOptions
);
383 SortedIndividualInt32List aSrtLst
;
385 aSrtLst
.InsertHolidayList( aAnyConv
, xOptions
, aHDay
, nNullDate
);
387 sal_Int32 nActDate
= nDate
+ nNullDate
;
391 if( GetDayOfWeek( nActDate
) == 5 )
392 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
399 if( GetDayOfWeek( nActDate
) < 5 )
401 if( !aSrtLst
.Find( nActDate
) )
405 nActDate
++; // jump over weekend
410 if( GetDayOfWeek( nActDate
) == 6 )
411 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
418 if( GetDayOfWeek( nActDate
) < 5 )
420 if( !aSrtLst
.Find( nActDate
) )
424 nActDate
--; // jump over weekend
428 return nActDate
- nNullDate
;
432 double SAL_CALL
AnalysisAddIn::getYearfrac( const uno::Reference
< beans::XPropertySet
>& xOpt
,
433 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& rMode
)
435 double fRet
= GetYearFrac( xOpt
, nStartDate
, nEndDate
, getDateMode( xOpt
, rMode
) );
436 RETURN_FINITE( fRet
);
439 sal_Int32 SAL_CALL
AnalysisAddIn::getEdate( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nStartDate
, sal_Int32 nMonths
)
441 sal_Int32 nNullDate
= GetNullDate( xOpt
);
442 ScaDate
aDate( nNullDate
, nStartDate
, 5 );
443 aDate
.addMonths( nMonths
);
444 return aDate
.getDate( nNullDate
);
447 sal_Int32 SAL_CALL
AnalysisAddIn::getWeeknum( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMode
)
449 nDate
+= GetNullDate( xOpt
);
451 sal_uInt16 nDay
, nMonth
, nYear
;
452 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
454 sal_Int32 nFirstInYear
= DateToDays( 1, 1, nYear
);
455 sal_uInt16 nFirstDayInYear
= GetDayOfWeek( nFirstInYear
);
457 return ( nDate
- nFirstInYear
+ ( ( nMode
== 1 )? ( nFirstDayInYear
+ 1 ) % 7 : nFirstDayInYear
) ) / 7 + 1;
460 sal_Int32 SAL_CALL
AnalysisAddIn::getEomonth( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMonths
)
462 sal_Int32 nNullDate
= GetNullDate( xOpt
);
464 sal_uInt16 nDay
, nMonth
, nYear
;
465 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
467 sal_Int32 nNewMonth
= nMonth
+ nMonths
;
471 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
+ ( nNewMonth
/ 12 ) );
474 else if( nNewMonth
< 1 )
476 nNewMonth
= -nNewMonth
;
477 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
- ( nNewMonth
/ 12 ) );
480 nNewMonth
= 12 - nNewMonth
;
483 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth
), nYear
), sal_uInt16( nNewMonth
), nYear
) - nNullDate
;
486 sal_Int32 SAL_CALL
AnalysisAddIn::getNetworkdays( const uno::Reference
< beans::XPropertySet
>& xOpt
,
487 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& aHDay
)
489 sal_Int32 nNullDate
= GetNullDate( xOpt
);
491 SortedIndividualInt32List aSrtLst
;
493 aSrtLst
.InsertHolidayList( aAnyConv
, xOpt
, aHDay
, nNullDate
);
495 sal_Int32 nActDate
= nStartDate
+ nNullDate
;
496 sal_Int32 nStopDate
= nEndDate
+ nNullDate
;
499 if( nActDate
<= nStopDate
)
501 while( nActDate
<= nStopDate
)
503 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
511 while( nActDate
>= nStopDate
)
513 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
523 sal_Int32 SAL_CALL
AnalysisAddIn::getIseven( sal_Int32 nVal
)
525 return ( nVal
& 0x00000001 )? 0 : 1;
528 sal_Int32 SAL_CALL
AnalysisAddIn::getIsodd( sal_Int32 nVal
)
530 return ( nVal
& 0x00000001 )? 1 : 0;
534 AnalysisAddIn::getMultinomial( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< sal_Int32
> >& aVLst
,
535 const uno::Sequence
< uno::Any
>& aOptVLst
)
537 ScaDoubleListGE0 aValList
;
539 aValList
.Append( aVLst
);
540 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
542 if( aValList
.Count() == 0 )
548 for( sal_uInt32 i
= 0; i
< aValList
.Count(); ++i
)
550 const double d
= aValList
.Get(i
);
551 double n
= (d
>= 0.0) ? rtl::math::approxFloor( d
) : rtl::math::approxCeil( d
);
553 throw lang::IllegalArgumentException();
558 fRet
*= BinomialCoefficient(nZ
, n
);
561 RETURN_FINITE( fRet
);
564 double SAL_CALL
AnalysisAddIn::getSeriessum( double fX
, double fN
, double fM
, const uno::Sequence
< uno::Sequence
< double > >& aCoeffList
)
568 // #i32269# 0^0 is undefined, Excel returns #NUM! error
569 if( fX
== 0.0 && fN
== 0 )
570 throw uno::RuntimeException();
575 sal_Int32 nE1
= aCoeffList
.getLength();
578 for( n1
= 0 ; n1
< nE1
; n1
++ )
580 const uno::Sequence
< double >& rList
= aCoeffList
[ n1
];
581 nE2
= rList
.getLength();
582 const double* pList
= rList
.getConstArray();
584 for( n2
= 0 ; n2
< nE2
; n2
++ )
586 fRet
+= pList
[ n2
] * pow( fX
, fN
);
593 RETURN_FINITE( fRet
);
596 double SAL_CALL
AnalysisAddIn::getQuotient( double fNum
, double fDenom
)
599 if( (fNum
< 0) != (fDenom
< 0) )
600 fRet
= ::rtl::math::approxCeil( fNum
/ fDenom
);
602 fRet
= ::rtl::math::approxFloor( fNum
/ fDenom
);
603 RETURN_FINITE( fRet
);
606 double SAL_CALL
AnalysisAddIn::getMround( double fNum
, double fMult
)
611 double fRet
= fMult
* ::rtl::math::round( fNum
/ fMult
);
612 RETURN_FINITE( fRet
);
615 double SAL_CALL
AnalysisAddIn::getSqrtpi( double fNum
)
617 double fRet
= sqrt( fNum
* PI
);
618 RETURN_FINITE( fRet
);
621 double SAL_CALL
AnalysisAddIn::getRandbetween( double fMin
, double fMax
)
623 fMin
= ::rtl::math::round( fMin
, 0, rtl_math_RoundingMode_Up
);
624 fMax
= ::rtl::math::round( fMax
, 0, rtl_math_RoundingMode_Up
);
626 throw lang::IllegalArgumentException();
628 double fRet
= floor(comphelper::rng::uniform_real_distribution(fMin
, nextafter(fMax
+1, -DBL_MAX
)));
629 RETURN_FINITE( fRet
);
632 double SAL_CALL
AnalysisAddIn::getGcd( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
)
634 ScaDoubleListGT0 aValList
;
636 aValList
.Append( aVLst
);
637 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
639 if( aValList
.Count() == 0 )
642 double f
= aValList
.Get(0);
643 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
645 f
= GetGcd( aValList
.Get(i
), f
);
651 double SAL_CALL
AnalysisAddIn::getLcm( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
)
653 ScaDoubleListGE0 aValList
;
655 aValList
.Append( aVLst
);
656 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
658 if( aValList
.Count() == 0 )
661 double f
= rtl::math::approxFloor( aValList
.Get(0) );
663 throw lang::IllegalArgumentException();
668 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
670 double fTmp
= rtl::math::approxFloor( aValList
.Get(i
) );
672 throw lang::IllegalArgumentException();
674 f
= fTmp
* f
/ GetGcd( fTmp
, f
);
682 double SAL_CALL
AnalysisAddIn::getBesseli( double fNum
, sal_Int32 nOrder
)
684 double fRet
= sca::analysis::BesselI( fNum
, nOrder
);
685 RETURN_FINITE( fRet
);
688 double SAL_CALL
AnalysisAddIn::getBesselj( double fNum
, sal_Int32 nOrder
)
690 double fRet
= sca::analysis::BesselJ( fNum
, nOrder
);
691 RETURN_FINITE( fRet
);
694 double SAL_CALL
AnalysisAddIn::getBesselk( double fNum
, sal_Int32 nOrder
)
696 if( nOrder
< 0 || fNum
<= 0.0 )
697 throw lang::IllegalArgumentException();
699 double fRet
= sca::analysis::BesselK( fNum
, nOrder
);
700 RETURN_FINITE( fRet
);
703 double SAL_CALL
AnalysisAddIn::getBessely( double fNum
, sal_Int32 nOrder
)
705 if( nOrder
< 0 || fNum
<= 0.0 )
706 throw lang::IllegalArgumentException();
708 double fRet
= sca::analysis::BesselY( fNum
, nOrder
);
709 RETURN_FINITE( fRet
);
712 const double SCA_MAX2
= 511.0; // min. val for binary numbers (9 bits + sign)
713 const double SCA_MIN2
= -SCA_MAX2
-1.0; // min. val for binary numbers (9 bits + sign)
714 const double SCA_MAX8
= 536870911.0; // max. val for octal numbers (29 bits + sign)
715 const double SCA_MIN8
= -SCA_MAX8
-1.0; // min. val for octal numbers (29 bits + sign)
716 const double SCA_MAX16
= 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
717 const double SCA_MIN16
= -SCA_MAX16
-1.0; // min. val for hexadecimal numbers (39 bits + sign)
718 const sal_Int32 SCA_MAXPLACES
= 10; // max. number of places
720 OUString SAL_CALL
AnalysisAddIn::getBin2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
722 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
723 sal_Int32 nPlaces
= 0;
724 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
725 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
728 double SAL_CALL
AnalysisAddIn::getBin2Dec( const OUString
& aNum
)
730 double fRet
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
731 RETURN_FINITE( fRet
);
734 OUString SAL_CALL
AnalysisAddIn::getBin2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
736 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
737 sal_Int32 nPlaces
= 0;
738 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
739 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
742 OUString SAL_CALL
AnalysisAddIn::getOct2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
744 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
745 sal_Int32 nPlaces
= 0;
746 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
747 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
750 double SAL_CALL
AnalysisAddIn::getOct2Dec( const OUString
& aNum
)
752 double fRet
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
753 RETURN_FINITE( fRet
);
756 OUString SAL_CALL
AnalysisAddIn::getOct2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
758 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
759 sal_Int32 nPlaces
= 0;
760 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
761 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
764 OUString SAL_CALL
AnalysisAddIn::getDec2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
)
766 sal_Int32 nPlaces
= 0;
767 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
768 return ConvertFromDec( nNum
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
771 OUString SAL_CALL
AnalysisAddIn::getDec2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
)
773 sal_Int32 nPlaces
= 0;
774 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
775 return ConvertFromDec( nNum
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
778 OUString SAL_CALL
AnalysisAddIn::getDec2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rPlaces
)
780 sal_Int32 nPlaces
= 0;
781 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
782 return ConvertFromDec( fNum
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
785 OUString SAL_CALL
AnalysisAddIn::getHex2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
787 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
788 sal_Int32 nPlaces
= 0;
789 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
790 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
793 double SAL_CALL
AnalysisAddIn::getHex2Dec( const OUString
& aNum
)
795 double fRet
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
796 RETURN_FINITE( fRet
);
799 OUString SAL_CALL
AnalysisAddIn::getHex2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
801 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
802 sal_Int32 nPlaces
= 0;
803 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
804 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
807 sal_Int32 SAL_CALL
AnalysisAddIn::getDelta( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum1
, const uno::Any
& rNum2
)
809 return sal_Int32(fNum1
== aAnyConv
.getDouble( xOpt
, rNum2
, 0.0 ));
812 double SAL_CALL
AnalysisAddIn::getErf( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fLL
, const uno::Any
& rUL
)
815 bool bContainsValue
= aAnyConv
.getDouble( fUL
, xOpt
, rUL
);
817 fRet
= bContainsValue
? (Erf( fUL
) - Erf( fLL
)) : Erf( fLL
);
818 RETURN_FINITE( fRet
);
821 double SAL_CALL
AnalysisAddIn::getErfc( double f
)
823 double fRet
= Erfc( f
);
824 RETURN_FINITE( fRet
);
827 sal_Int32 SAL_CALL
AnalysisAddIn::getGestep( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rStep
)
829 return sal_Int32(fNum
>= aAnyConv
.getDouble( xOpt
, rStep
, 0.0 ));
832 double SAL_CALL
AnalysisAddIn::getFactdouble( sal_Int32 nNum
)
834 double fRet
= FactDouble( nNum
);
835 RETURN_FINITE( fRet
);
838 double SAL_CALL
AnalysisAddIn::getImabs( const OUString
& aNum
)
840 double fRet
= Complex( aNum
).Abs();
841 RETURN_FINITE( fRet
);
844 double SAL_CALL
AnalysisAddIn::getImaginary( const OUString
& aNum
)
846 double fRet
= Complex( aNum
).Imag();
847 RETURN_FINITE( fRet
);
850 OUString SAL_CALL
AnalysisAddIn::getImpower( const OUString
& aNum
, double f
)
856 return z
.GetString();
859 double SAL_CALL
AnalysisAddIn::getImargument( const OUString
& aNum
)
861 double fRet
= Complex( aNum
).Arg();
862 RETURN_FINITE( fRet
);
865 OUString SAL_CALL
AnalysisAddIn::getImcos( const OUString
& aNum
)
871 return z
.GetString();
874 OUString SAL_CALL
AnalysisAddIn::getImdiv( const OUString
& aDivid
, const OUString
& aDivis
)
878 z
.Div( Complex( aDivis
) );
880 return z
.GetString();
883 OUString SAL_CALL
AnalysisAddIn::getImexp( const OUString
& aNum
)
889 return z
.GetString();
892 OUString SAL_CALL
AnalysisAddIn::getImconjugate( const OUString
& aNum
)
898 return z
.GetString();
901 OUString SAL_CALL
AnalysisAddIn::getImln( const OUString
& aNum
)
907 return z
.GetString();
910 OUString SAL_CALL
AnalysisAddIn::getImlog10( const OUString
& aNum
)
916 return z
.GetString();
919 OUString SAL_CALL
AnalysisAddIn::getImlog2( const OUString
& aNum
)
925 return z
.GetString();
928 OUString SAL_CALL
AnalysisAddIn::getImproduct( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aNL
)
932 z_list
.Append( aNum1
);
933 z_list
.Append( aNL
);
936 return Complex( 0 ).GetString();
938 Complex z
= z_list
.Get(0);
939 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
940 z
.Mult( z_list
.Get(i
) );
942 return z
.GetString();
945 double SAL_CALL
AnalysisAddIn::getImreal( const OUString
& aNum
)
947 double fRet
= Complex( aNum
).Real();
948 RETURN_FINITE( fRet
);
951 OUString SAL_CALL
AnalysisAddIn::getImsin( const OUString
& aNum
)
957 return z
.GetString();
960 OUString SAL_CALL
AnalysisAddIn::getImsub( const OUString
& aNum1
, const OUString
& aNum2
)
964 z
.Sub( Complex( aNum2
) );
966 return z
.GetString();
969 OUString SAL_CALL
AnalysisAddIn::getImsum( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aFollowingPars
)
973 z_list
.Append( aNum1
);
974 z_list
.Append( aFollowingPars
);
977 return Complex( 0 ).GetString();
979 Complex
z( z_list
.Get(0) );
980 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
981 z
.Add( z_list
.Get(i
) );
983 return z
.GetString();
986 OUString SAL_CALL
AnalysisAddIn::getImsqrt( const OUString
& aNum
)
992 return z
.GetString();
995 OUString SAL_CALL
AnalysisAddIn::getImtan( const OUString
& aNum
)
1001 return z
.GetString();
1004 OUString SAL_CALL
AnalysisAddIn::getImsec( const OUString
& aNum
)
1010 return z
.GetString();
1013 OUString SAL_CALL
AnalysisAddIn::getImcsc( const OUString
& aNum
)
1019 return z
.GetString();
1022 OUString SAL_CALL
AnalysisAddIn::getImcot( const OUString
& aNum
)
1028 return z
.GetString();
1031 OUString SAL_CALL
AnalysisAddIn::getImsinh( const OUString
& aNum
)
1037 return z
.GetString();
1040 OUString SAL_CALL
AnalysisAddIn::getImcosh( const OUString
& aNum
)
1046 return z
.GetString();
1049 OUString SAL_CALL
AnalysisAddIn::getImsech( const OUString
& aNum
)
1055 return z
.GetString();
1058 OUString SAL_CALL
AnalysisAddIn::getImcsch( const OUString
& aNum
)
1064 return z
.GetString();
1067 OUString SAL_CALL
AnalysisAddIn::getComplex( double fR
, double fI
, const uno::Any
& rSuff
)
1071 switch( rSuff
.getValueTypeClass() )
1073 case uno::TypeClass_VOID
:
1076 case uno::TypeClass_STRING
:
1078 auto pSuff
= o3tl::forceAccess
<OUString
>(rSuff
);
1079 bi
= *pSuff
== "i" || pSuff
->isEmpty();
1080 if( !bi
&& *pSuff
!= "j" )
1081 throw lang::IllegalArgumentException();
1085 throw lang::IllegalArgumentException();
1088 return Complex( fR
, fI
, bi
? 'i' : 'j' ).GetString();
1091 double SAL_CALL
AnalysisAddIn::getConvert( double f
, const OUString
& aFU
, const OUString
& aTU
)
1094 pCDL
.reset(new ConvertDataList());
1096 double fRet
= pCDL
->Convert( f
, aFU
, aTU
);
1097 RETURN_FINITE( fRet
);
1100 OUString
AnalysisAddIn::AnalysisResId(const char* pResId
)
1102 return Translate::get(pResId
, aResLocale
);
1105 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */