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 <comphelper/random.hxx>
24 #include <cppuhelper/supportsservice.hxx>
25 #include <cppuhelper/weak.hxx>
26 #include <o3tl/any.hxx>
27 #include <rtl/math.hxx>
28 #include <sal/macros.h>
29 #include <unotools/resmgr.hxx>
30 #include <i18nlangtag/languagetag.hxx>
35 constexpr OUString ADDIN_SERVICE
= u
"com.sun.star.sheet.AddIn"_ustr
;
36 constexpr OUString MY_SERVICE
= u
"com.sun.star.sheet.addin.Analysis"_ustr
;
37 constexpr OUStringLiteral MY_IMPLNAME
= u
"com.sun.star.sheet.addin.AnalysisImpl";
39 using namespace ::com::sun::star
;
40 using namespace sca::analysis
;
42 OUString
AnalysisAddIn::GetFuncDescrStr(const TranslateId
* pResId
, sal_uInt16 nStrIndex
)
44 return AnalysisResId(pResId
[nStrIndex
- 1]);
47 void AnalysisAddIn::InitData()
49 aResLocale
= Translate::Create("sca", LanguageTag(aFuncLoc
));
51 pFD
.reset(new FuncDataList
);
52 InitFuncDataList(*pFD
);
57 AnalysisAddIn::AnalysisAddIn( const uno::Reference
< uno::XComponentContext
>& xContext
) :
58 AnalysisAddIn_Base(m_aMutex
),
63 AnalysisAddIn::~AnalysisAddIn()
67 sal_Int32
AnalysisAddIn::getDateMode(
68 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
69 const uno::Any
& rAny
)
71 sal_Int32 nMode
= aAnyConv
.getInt32( xPropSet
, rAny
, 0 );
72 if( (nMode
< 0) || (nMode
> 4) )
73 throw lang::IllegalArgumentException();
77 #define MAXFACTDOUBLE 300
79 double AnalysisAddIn::FactDouble( sal_Int32 nNum
)
81 if( nNum
< 0 || nNum
> MAXFACTDOUBLE
)
82 throw lang::IllegalArgumentException();
86 pFactDoubles
.reset( new double[ MAXFACTDOUBLE
+ 1 ] );
88 pFactDoubles
[ 0 ] = 1.0; // by default
93 pFactDoubles
[ 1 ] = fOdd
;
94 pFactDoubles
[ 2 ] = fEven
;
98 for( sal_uInt16 nCnt
= 3 ; nCnt
<= MAXFACTDOUBLE
; nCnt
++ )
103 pFactDoubles
[ nCnt
] = fOdd
;
108 pFactDoubles
[ nCnt
] = fEven
;
116 return pFactDoubles
[ nNum
];
120 OUString SAL_CALL
AnalysisAddIn::getServiceName()
122 // name of specific AddIn service
127 OUString SAL_CALL
AnalysisAddIn::getImplementationName()
132 sal_Bool SAL_CALL
AnalysisAddIn::supportsService( const OUString
& aName
)
134 return cppu::supportsService(this, aName
);
137 uno::Sequence
< OUString
> SAL_CALL
AnalysisAddIn::getSupportedServiceNames()
139 return { ADDIN_SERVICE
, MY_SERVICE
};
143 void SAL_CALL
AnalysisAddIn::setLocale( const lang::Locale
& eLocale
)
147 InitData(); // change of locale invalidates resources!
150 lang::Locale SAL_CALL
AnalysisAddIn::getLocale()
156 OUString SAL_CALL
AnalysisAddIn::getProgrammaticFuntionName( const OUString
& )
159 // (but should be implemented for other uses of the AddIn service)
164 OUString SAL_CALL
AnalysisAddIn::getDisplayFunctionName( const OUString
& aProgrammaticName
)
168 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
169 if( it
!= pFD
->end() )
171 aRet
= AnalysisResId(it
->GetUINameID());
174 const OUString
& rSuffix
= it
->GetSuffix();
175 if (!rSuffix
.isEmpty())
183 aRet
= "UNKNOWNFUNC_" + aProgrammaticName
;
189 OUString SAL_CALL
AnalysisAddIn::getFunctionDescription( const OUString
& aProgrammaticName
)
193 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
194 if( it
!= pFD
->end() )
195 aRet
= GetFuncDescrStr( it
->GetDescrID(), 1 );
200 OUString SAL_CALL
AnalysisAddIn::getDisplayArgumentName( const OUString
& aName
, sal_Int32 nArg
)
204 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
205 if( it
!= pFD
->end() && nArg
<= 0xFFFF )
207 sal_uInt16 nStr
= it
->GetStrIndex( sal_uInt16( nArg
) );
209 aRet
= GetFuncDescrStr( it
->GetDescrID(), nStr
);
217 OUString SAL_CALL
AnalysisAddIn::getArgumentDescription( const OUString
& aName
, sal_Int32 nArg
)
221 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
222 if( it
!= pFD
->end() && nArg
<= 0xFFFF )
224 sal_uInt16 nStr
= it
->GetStrIndex( sal_uInt16( nArg
) );
226 aRet
= GetFuncDescrStr( it
->GetDescrID(), nStr
+ 1 );
228 aRet
= "for internal use only";
234 constexpr OUString pDefCatName
= u
"Add-In"_ustr
;
236 OUString SAL_CALL
AnalysisAddIn::getProgrammaticCategoryName( const OUString
& aName
)
238 // return non-translated strings
239 // return OUString( "Add-In" );
240 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aName
) );
242 if( it
!= pFD
->end() )
244 switch( it
->GetCategory() )
246 case FDCategory::DateTime
: aRet
= "Date&Time"; break;
247 case FDCategory::Finance
: aRet
= "Financial"; break;
248 case FDCategory::Inf
: aRet
= "Information"; break;
249 case FDCategory::Math
: aRet
= "Mathematical"; break;
250 case FDCategory::Tech
: aRet
= "Technical"; break;
259 OUString SAL_CALL
AnalysisAddIn::getDisplayCategoryName( const OUString
& aProgrammaticFunctionName
)
261 // return translated strings, not used for predefined categories
262 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticFunctionName
) );
264 if( it
!= pFD
->end() )
266 switch( it
->GetCategory() )
268 case FDCategory::DateTime
: aRet
= "Date&Time"; break;
269 case FDCategory::Finance
: aRet
= "Financial"; break;
270 case FDCategory::Inf
: aRet
= "Information"; break;
271 case FDCategory::Math
: aRet
= "Mathematical"; break;
272 case FDCategory::Tech
: aRet
= "Technical"; break;
281 static const char* pLang
[] = { "de", "en" };
282 static const char* pCoun
[] = { "DE", "US" };
283 constexpr sal_uInt32 nNumOfLoc
= std::size(pLang
);
285 void AnalysisAddIn::InitDefLocales()
287 pDefLocales
.reset( new lang::Locale
[ nNumOfLoc
] );
289 for( sal_uInt32 n
= 0 ; n
< nNumOfLoc
; n
++ )
291 pDefLocales
[ n
].Language
= OUString::createFromAscii( pLang
[ n
] );
292 pDefLocales
[ n
].Country
= OUString::createFromAscii( pCoun
[ n
] );
296 inline const lang::Locale
& AnalysisAddIn::GetLocale( sal_uInt32 nInd
)
301 if( nInd
< nNumOfLoc
)
302 return pDefLocales
[ nInd
];
307 uno::Sequence
< sheet::LocalizedName
> SAL_CALL
AnalysisAddIn::getCompatibilityNames( const OUString
& aProgrammaticName
)
309 auto it
= std::find_if(pFD
->begin(), pFD
->end(), FindFuncData( aProgrammaticName
) );
310 if( it
== pFD
->end() )
311 return uno::Sequence
< sheet::LocalizedName
>( 0 );
313 const std::vector
<OUString
>& r
= it
->GetCompNameList();
314 sal_uInt32 nCount
= r
.size();
316 uno::Sequence
< sheet::LocalizedName
> aRet( nCount
);
318 sheet::LocalizedName
* pArray
= aRet
.getArray();
320 for( sal_uInt32 n
= 0 ; n
< nCount
; n
++ )
322 pArray
[ n
] = sheet::LocalizedName( GetLocale( n
), r
[n
] );
330 sal_Int32 SAL_CALL
AnalysisAddIn::getWorkday( const uno::Reference
< beans::XPropertySet
>& xOptions
,
331 sal_Int32 nDate
, sal_Int32 nDays
, const uno::Any
& aHDay
)
336 sal_Int32 nNullDate
= GetNullDate( xOptions
);
338 SortedIndividualInt32List aSrtLst
;
340 aSrtLst
.InsertHolidayList( aAnyConv
, xOptions
, aHDay
, nNullDate
);
342 sal_Int32 nActDate
= nDate
+ nNullDate
;
346 if( GetDayOfWeek( nActDate
) == 5 )
347 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
354 if( GetDayOfWeek( nActDate
) < 5 )
356 if( !aSrtLst
.Find( nActDate
) )
360 nActDate
++; // jump over weekend
365 if( GetDayOfWeek( nActDate
) == 6 )
366 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
373 if( GetDayOfWeek( nActDate
) < 5 )
375 if( !aSrtLst
.Find( nActDate
) )
379 nActDate
--; // jump over weekend
383 return nActDate
- nNullDate
;
387 double SAL_CALL
AnalysisAddIn::getYearfrac( const uno::Reference
< beans::XPropertySet
>& xOpt
,
388 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& rMode
)
390 double fRet
= GetYearFrac( xOpt
, nStartDate
, nEndDate
, getDateMode( xOpt
, rMode
) );
391 return finiteOrThrow( fRet
);
394 sal_Int32 SAL_CALL
AnalysisAddIn::getEdate( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nStartDate
, sal_Int32 nMonths
)
396 sal_Int32 nNullDate
= GetNullDate( xOpt
);
397 ScaDate
aDate( nNullDate
, nStartDate
, 5 );
398 aDate
.addMonths( nMonths
);
399 return aDate
.getDate( nNullDate
);
402 sal_Int32 SAL_CALL
AnalysisAddIn::getWeeknum( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMode
)
404 nDate
+= GetNullDate( xOpt
);
406 sal_uInt16 nDay
, nMonth
, nYear
;
407 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
409 sal_Int32 nFirstInYear
= DateToDays( 1, 1, nYear
);
410 // coverity[ tainted_data_return : FALSE ] version 2023.12.2
411 sal_uInt16 nFirstDayInYear
= GetDayOfWeek( nFirstInYear
);
413 return ( nDate
- nFirstInYear
+ ( ( nMode
== 1 )? ( nFirstDayInYear
+ 1 ) % 7 : nFirstDayInYear
) ) / 7 + 1;
416 sal_Int32 SAL_CALL
AnalysisAddIn::getEomonth( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMonths
)
418 sal_Int32 nNullDate
= GetNullDate( xOpt
);
420 sal_uInt16 nDay
, nMonth
, nYear
;
421 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
423 sal_Int32 nNewMonth
= nMonth
+ nMonths
;
427 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
+ ( nNewMonth
/ 12 ) );
430 else if( nNewMonth
< 1 )
432 nNewMonth
= -nNewMonth
;
433 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
- ( nNewMonth
/ 12 ) );
436 nNewMonth
= 12 - nNewMonth
;
439 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth
), nYear
), sal_uInt16( nNewMonth
), nYear
) - nNullDate
;
442 sal_Int32 SAL_CALL
AnalysisAddIn::getNetworkdays( const uno::Reference
< beans::XPropertySet
>& xOpt
,
443 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& aHDay
)
445 sal_Int32 nNullDate
= GetNullDate( xOpt
);
447 SortedIndividualInt32List aSrtLst
;
449 aSrtLst
.InsertHolidayList( aAnyConv
, xOpt
, aHDay
, nNullDate
);
451 sal_Int32 nActDate
= nStartDate
+ nNullDate
;
452 sal_Int32 nStopDate
= nEndDate
+ nNullDate
;
455 if( nActDate
<= nStopDate
)
457 while( nActDate
<= nStopDate
)
459 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
467 while( nActDate
>= nStopDate
)
469 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
479 sal_Int32 SAL_CALL
AnalysisAddIn::getIseven( sal_Int32 nVal
)
481 return ( nVal
& 0x00000001 )? 0 : 1;
484 sal_Int32 SAL_CALL
AnalysisAddIn::getIsodd( sal_Int32 nVal
)
486 return ( nVal
& 0x00000001 )? 1 : 0;
490 AnalysisAddIn::getMultinomial( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< sal_Int32
> >& aVLst
,
491 const uno::Sequence
< uno::Any
>& aOptVLst
)
493 ScaDoubleListGE0 aValList
;
495 aValList
.Append( aVLst
);
496 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
498 if( aValList
.Count() == 0 )
504 for( sal_uInt32 i
= 0; i
< aValList
.Count(); ++i
)
506 const double d
= aValList
.Get(i
);
507 double n
= (d
>= 0.0) ? rtl::math::approxFloor( d
) : rtl::math::approxCeil( d
);
509 throw lang::IllegalArgumentException();
514 fRet
*= BinomialCoefficient(nZ
, n
);
517 return finiteOrThrow( fRet
);
520 double SAL_CALL
AnalysisAddIn::getSeriessum( double fX
, double fN
, double fM
, const uno::Sequence
< uno::Sequence
< double > >& aCoeffList
)
524 // #i32269# 0^0 is undefined, Excel returns #NUM! error
525 if( fX
== 0.0 && fN
== 0 )
526 throw uno::RuntimeException(u
"undefined expression: 0^0"_ustr
);
530 for( const uno::Sequence
< double >& rList
: aCoeffList
)
532 for( const double fCoef
: rList
)
534 fRet
+= fCoef
* pow( fX
, fN
);
541 return finiteOrThrow( fRet
);
544 double SAL_CALL
AnalysisAddIn::getQuotient( double fNum
, double fDenom
)
547 if( (fNum
< 0) != (fDenom
< 0) )
548 fRet
= ::rtl::math::approxCeil( fNum
/ fDenom
);
550 fRet
= ::rtl::math::approxFloor( fNum
/ fDenom
);
551 return finiteOrThrow( fRet
);
554 double SAL_CALL
AnalysisAddIn::getMround( double fNum
, double fMult
)
559 double fRet
= fMult
* ::rtl::math::round( ::rtl::math::approxValue( fNum
/ fMult
));
560 return finiteOrThrow( fRet
);
563 double SAL_CALL
AnalysisAddIn::getSqrtpi( double fNum
)
565 double fRet
= sqrt( fNum
* M_PI
);
566 return finiteOrThrow( fRet
);
569 double SAL_CALL
AnalysisAddIn::getRandbetween( double fMin
, double fMax
)
571 fMin
= ::rtl::math::round( fMin
, 0, rtl_math_RoundingMode_Up
);
572 fMax
= ::rtl::math::round( fMax
, 0, rtl_math_RoundingMode_Up
);
574 throw lang::IllegalArgumentException();
576 double fRet
= floor(comphelper::rng::uniform_real_distribution(fMin
, nextafter(fMax
+1, -DBL_MAX
)));
577 return finiteOrThrow( fRet
);
580 double SAL_CALL
AnalysisAddIn::getGcd( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
)
582 ScaDoubleListGT0 aValList
;
584 aValList
.Append( aVLst
);
585 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
587 if( aValList
.Count() == 0 )
590 double f
= aValList
.Get(0);
591 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
593 f
= GetGcd( aValList
.Get(i
), f
);
596 return finiteOrThrow( f
);
599 double SAL_CALL
AnalysisAddIn::getLcm( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
)
601 ScaDoubleListGE0 aValList
;
603 aValList
.Append( aVLst
);
604 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
606 if( aValList
.Count() == 0 )
609 double f
= rtl::math::approxFloor( aValList
.Get(0) );
611 throw lang::IllegalArgumentException();
616 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
618 double fTmp
= rtl::math::approxFloor( aValList
.Get(i
) );
620 throw lang::IllegalArgumentException();
622 f
= fTmp
* f
/ GetGcd( fTmp
, f
);
627 return finiteOrThrow( f
);
630 double SAL_CALL
AnalysisAddIn::getBesseli( double fNum
, sal_Int32 nOrder
)
632 double fRet
= sca::analysis::BesselI( fNum
, nOrder
);
633 return finiteOrThrow( fRet
);
636 double SAL_CALL
AnalysisAddIn::getBesselj( double fNum
, sal_Int32 nOrder
)
638 double fRet
= sca::analysis::BesselJ( fNum
, nOrder
);
639 return finiteOrThrow( fRet
);
642 double SAL_CALL
AnalysisAddIn::getBesselk( double fNum
, sal_Int32 nOrder
)
644 if( nOrder
< 0 || fNum
<= 0.0 )
645 throw lang::IllegalArgumentException();
647 double fRet
= sca::analysis::BesselK( fNum
, nOrder
);
648 return finiteOrThrow( fRet
);
651 double SAL_CALL
AnalysisAddIn::getBessely( double fNum
, sal_Int32 nOrder
)
653 if( nOrder
< 0 || fNum
<= 0.0 )
654 throw lang::IllegalArgumentException();
656 double fRet
= sca::analysis::BesselY( fNum
, nOrder
);
657 return finiteOrThrow( fRet
);
660 const double SCA_MAX2
= 511.0; // min. val for binary numbers (9 bits + sign)
661 const double SCA_MIN2
= -SCA_MAX2
-1.0; // min. val for binary numbers (9 bits + sign)
662 const double SCA_MAX8
= 536870911.0; // max. val for octal numbers (29 bits + sign)
663 const double SCA_MIN8
= -SCA_MAX8
-1.0; // min. val for octal numbers (29 bits + sign)
664 const double SCA_MAX16
= 549755813887.0; // max. val for hexadecimal numbers (39 bits + sign)
665 const double SCA_MIN16
= -SCA_MAX16
-1.0; // min. val for hexadecimal numbers (39 bits + sign)
666 const sal_Int32 SCA_MAXPLACES
= 10; // max. number of places
668 OUString SAL_CALL
AnalysisAddIn::getBin2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
670 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
671 sal_Int32 nPlaces
= 0;
672 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
673 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
676 double SAL_CALL
AnalysisAddIn::getBin2Dec( const OUString
& aNum
)
678 double fRet
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
679 return finiteOrThrow( fRet
);
682 OUString SAL_CALL
AnalysisAddIn::getBin2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
684 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
685 sal_Int32 nPlaces
= 0;
686 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
687 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
690 OUString SAL_CALL
AnalysisAddIn::getOct2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
692 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
693 sal_Int32 nPlaces
= 0;
694 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
695 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
698 double SAL_CALL
AnalysisAddIn::getOct2Dec( const OUString
& aNum
)
700 double fRet
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
701 return finiteOrThrow( fRet
);
704 OUString SAL_CALL
AnalysisAddIn::getOct2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
706 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
707 sal_Int32 nPlaces
= 0;
708 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
709 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
712 OUString SAL_CALL
AnalysisAddIn::getDec2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
)
714 sal_Int32 nPlaces
= 0;
715 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
716 return ConvertFromDec( nNum
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
719 OUString SAL_CALL
AnalysisAddIn::getDec2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
)
721 sal_Int32 nPlaces
= 0;
722 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
723 return ConvertFromDec( nNum
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
726 OUString SAL_CALL
AnalysisAddIn::getDec2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rPlaces
)
728 sal_Int32 nPlaces
= 0;
729 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
730 return ConvertFromDec( fNum
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
733 OUString SAL_CALL
AnalysisAddIn::getHex2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
735 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
736 sal_Int32 nPlaces
= 0;
737 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
738 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
741 double SAL_CALL
AnalysisAddIn::getHex2Dec( const OUString
& aNum
)
743 double fRet
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
744 return finiteOrThrow( fRet
);
747 OUString SAL_CALL
AnalysisAddIn::getHex2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
749 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
750 sal_Int32 nPlaces
= 0;
751 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
752 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
755 sal_Int32 SAL_CALL
AnalysisAddIn::getDelta( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum1
, const uno::Any
& rNum2
)
757 return sal_Int32(fNum1
== aAnyConv
.getDouble( xOpt
, rNum2
, 0.0 ));
760 double SAL_CALL
AnalysisAddIn::getErf( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fLL
, const uno::Any
& rUL
)
763 bool bContainsValue
= aAnyConv
.getDouble( fUL
, xOpt
, rUL
);
765 fRet
= bContainsValue
? (Erf( fUL
) - Erf( fLL
)) : Erf( fLL
);
766 return finiteOrThrow( fRet
);
769 double SAL_CALL
AnalysisAddIn::getErfc( double f
)
771 double fRet
= Erfc( f
);
772 return finiteOrThrow( fRet
);
775 sal_Int32 SAL_CALL
AnalysisAddIn::getGestep( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rStep
)
777 return sal_Int32(fNum
>= aAnyConv
.getDouble( xOpt
, rStep
, 0.0 ));
780 double SAL_CALL
AnalysisAddIn::getFactdouble( sal_Int32 nNum
)
782 double fRet
= FactDouble( nNum
);
783 return finiteOrThrow( fRet
);
786 double SAL_CALL
AnalysisAddIn::getImabs( const OUString
& aNum
)
788 double fRet
= Complex( aNum
).Abs();
789 return finiteOrThrow( fRet
);
792 double SAL_CALL
AnalysisAddIn::getImaginary( const OUString
& aNum
)
794 double fRet
= Complex( aNum
).Imag();
795 return finiteOrThrow( fRet
);
798 OUString SAL_CALL
AnalysisAddIn::getImpower( const OUString
& aNum
, double f
)
804 return z
.GetString();
807 double SAL_CALL
AnalysisAddIn::getImargument( const OUString
& aNum
)
809 double fRet
= Complex( aNum
).Arg();
810 return finiteOrThrow( fRet
);
813 OUString SAL_CALL
AnalysisAddIn::getImcos( const OUString
& aNum
)
819 return z
.GetString();
822 OUString SAL_CALL
AnalysisAddIn::getImdiv( const OUString
& aDivid
, const OUString
& aDivis
)
826 z
.Div( Complex( aDivis
) );
828 return z
.GetString();
831 OUString SAL_CALL
AnalysisAddIn::getImexp( const OUString
& aNum
)
837 return z
.GetString();
840 OUString SAL_CALL
AnalysisAddIn::getImconjugate( const OUString
& aNum
)
846 return z
.GetString();
849 OUString SAL_CALL
AnalysisAddIn::getImln( const OUString
& aNum
)
855 return z
.GetString();
858 OUString SAL_CALL
AnalysisAddIn::getImlog10( const OUString
& aNum
)
864 return z
.GetString();
867 OUString SAL_CALL
AnalysisAddIn::getImlog2( const OUString
& aNum
)
873 return z
.GetString();
876 OUString SAL_CALL
AnalysisAddIn::getImproduct( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aNL
)
880 z_list
.Append( aNum1
);
881 z_list
.Append( aNL
);
884 return Complex( 0 ).GetString();
886 Complex z
= z_list
.Get(0);
887 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
888 z
.Mult( z_list
.Get(i
) );
890 return z
.GetString();
893 double SAL_CALL
AnalysisAddIn::getImreal( const OUString
& aNum
)
895 double fRet
= Complex( aNum
).Real();
896 return finiteOrThrow( fRet
);
899 OUString SAL_CALL
AnalysisAddIn::getImsin( const OUString
& aNum
)
905 return z
.GetString();
908 OUString SAL_CALL
AnalysisAddIn::getImsub( const OUString
& aNum1
, const OUString
& aNum2
)
912 z
.Sub( Complex( aNum2
) );
914 return z
.GetString();
917 OUString SAL_CALL
AnalysisAddIn::getImsum( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aFollowingPars
)
921 z_list
.Append( aNum1
);
922 z_list
.Append( aFollowingPars
);
925 return Complex( 0 ).GetString();
927 Complex
z( z_list
.Get(0) );
928 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
929 z
.Add( z_list
.Get(i
) );
931 return z
.GetString();
934 OUString SAL_CALL
AnalysisAddIn::getImsqrt( const OUString
& aNum
)
940 return z
.GetString();
943 OUString SAL_CALL
AnalysisAddIn::getImtan( const OUString
& aNum
)
949 return z
.GetString();
952 OUString SAL_CALL
AnalysisAddIn::getImsec( const OUString
& aNum
)
958 return z
.GetString();
961 OUString SAL_CALL
AnalysisAddIn::getImcsc( const OUString
& aNum
)
967 return z
.GetString();
970 OUString SAL_CALL
AnalysisAddIn::getImcot( const OUString
& aNum
)
976 return z
.GetString();
979 OUString SAL_CALL
AnalysisAddIn::getImsinh( const OUString
& aNum
)
985 return z
.GetString();
988 OUString SAL_CALL
AnalysisAddIn::getImcosh( const OUString
& aNum
)
994 return z
.GetString();
997 OUString SAL_CALL
AnalysisAddIn::getImsech( const OUString
& aNum
)
1003 return z
.GetString();
1006 OUString SAL_CALL
AnalysisAddIn::getImcsch( const OUString
& aNum
)
1012 return z
.GetString();
1015 OUString SAL_CALL
AnalysisAddIn::getComplex( double fR
, double fI
, const uno::Any
& rSuff
)
1019 switch( rSuff
.getValueTypeClass() )
1021 case uno::TypeClass_VOID
:
1024 case uno::TypeClass_STRING
:
1026 auto pSuff
= o3tl::forceAccess
<OUString
>(rSuff
);
1027 bi
= *pSuff
== "i" || pSuff
->isEmpty();
1028 if( !bi
&& *pSuff
!= "j" )
1029 throw lang::IllegalArgumentException();
1033 throw lang::IllegalArgumentException();
1036 return Complex( fR
, fI
, bi
? 'i' : 'j' ).GetString();
1039 double SAL_CALL
AnalysisAddIn::getConvert( double f
, const OUString
& aFU
, const OUString
& aTU
)
1042 pCDL
.reset(new ConvertDataList());
1044 double fRet
= pCDL
->Convert( f
, aFU
, aTU
);
1045 return finiteOrThrow( fRet
);
1048 OUString
AnalysisAddIn::AnalysisResId(TranslateId aResId
)
1050 return Translate::get(aResId
, aResLocale
);
1053 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1054 scaddins_AnalysisAddIn_get_implementation(
1055 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
1057 return cppu::acquire(new AnalysisAddIn(context
));
1060 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */