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 const sal_uInt32 nNumOfLoc
= SAL_N_ELEMENTS(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 sal_uInt16 nFirstDayInYear
= GetDayOfWeek( nFirstInYear
);
412 return ( nDate
- nFirstInYear
+ ( ( nMode
== 1 )? ( nFirstDayInYear
+ 1 ) % 7 : nFirstDayInYear
) ) / 7 + 1;
415 sal_Int32 SAL_CALL
AnalysisAddIn::getEomonth( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nDate
, sal_Int32 nMonths
)
417 sal_Int32 nNullDate
= GetNullDate( xOpt
);
419 sal_uInt16 nDay
, nMonth
, nYear
;
420 DaysToDate( nDate
, nDay
, nMonth
, nYear
);
422 sal_Int32 nNewMonth
= nMonth
+ nMonths
;
426 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
+ ( nNewMonth
/ 12 ) );
429 else if( nNewMonth
< 1 )
431 nNewMonth
= -nNewMonth
;
432 nYear
= sal::static_int_cast
<sal_uInt16
>( nYear
- ( nNewMonth
/ 12 ) );
435 nNewMonth
= 12 - nNewMonth
;
438 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth
), nYear
), sal_uInt16( nNewMonth
), nYear
) - nNullDate
;
441 sal_Int32 SAL_CALL
AnalysisAddIn::getNetworkdays( const uno::Reference
< beans::XPropertySet
>& xOpt
,
442 sal_Int32 nStartDate
, sal_Int32 nEndDate
, const uno::Any
& aHDay
)
444 sal_Int32 nNullDate
= GetNullDate( xOpt
);
446 SortedIndividualInt32List aSrtLst
;
448 aSrtLst
.InsertHolidayList( aAnyConv
, xOpt
, aHDay
, nNullDate
);
450 sal_Int32 nActDate
= nStartDate
+ nNullDate
;
451 sal_Int32 nStopDate
= nEndDate
+ nNullDate
;
454 if( nActDate
<= nStopDate
)
456 while( nActDate
<= nStopDate
)
458 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
466 while( nActDate
>= nStopDate
)
468 if( GetDayOfWeek( nActDate
) < 5 && !aSrtLst
.Find( nActDate
) )
478 sal_Int32 SAL_CALL
AnalysisAddIn::getIseven( sal_Int32 nVal
)
480 return ( nVal
& 0x00000001 )? 0 : 1;
483 sal_Int32 SAL_CALL
AnalysisAddIn::getIsodd( sal_Int32 nVal
)
485 return ( nVal
& 0x00000001 )? 1 : 0;
489 AnalysisAddIn::getMultinomial( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< sal_Int32
> >& aVLst
,
490 const uno::Sequence
< uno::Any
>& aOptVLst
)
492 ScaDoubleListGE0 aValList
;
494 aValList
.Append( aVLst
);
495 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
497 if( aValList
.Count() == 0 )
503 for( sal_uInt32 i
= 0; i
< aValList
.Count(); ++i
)
505 const double d
= aValList
.Get(i
);
506 double n
= (d
>= 0.0) ? rtl::math::approxFloor( d
) : rtl::math::approxCeil( d
);
508 throw lang::IllegalArgumentException();
513 fRet
*= BinomialCoefficient(nZ
, n
);
516 return finiteOrThrow( fRet
);
519 double SAL_CALL
AnalysisAddIn::getSeriessum( double fX
, double fN
, double fM
, const uno::Sequence
< uno::Sequence
< double > >& aCoeffList
)
523 // #i32269# 0^0 is undefined, Excel returns #NUM! error
524 if( fX
== 0.0 && fN
== 0 )
525 throw uno::RuntimeException("undefined expression: 0^0");
529 for( const uno::Sequence
< double >& rList
: aCoeffList
)
531 for( const double fCoef
: rList
)
533 fRet
+= fCoef
* pow( fX
, fN
);
540 return finiteOrThrow( fRet
);
543 double SAL_CALL
AnalysisAddIn::getQuotient( double fNum
, double fDenom
)
546 if( (fNum
< 0) != (fDenom
< 0) )
547 fRet
= ::rtl::math::approxCeil( fNum
/ fDenom
);
549 fRet
= ::rtl::math::approxFloor( fNum
/ fDenom
);
550 return finiteOrThrow( fRet
);
553 double SAL_CALL
AnalysisAddIn::getMround( double fNum
, double fMult
)
558 double fRet
= fMult
* ::rtl::math::round( ::rtl::math::approxValue( fNum
/ fMult
));
559 return finiteOrThrow( fRet
);
562 double SAL_CALL
AnalysisAddIn::getSqrtpi( double fNum
)
564 double fRet
= sqrt( fNum
* M_PI
);
565 return finiteOrThrow( fRet
);
568 double SAL_CALL
AnalysisAddIn::getRandbetween( double fMin
, double fMax
)
570 fMin
= ::rtl::math::round( fMin
, 0, rtl_math_RoundingMode_Up
);
571 fMax
= ::rtl::math::round( fMax
, 0, rtl_math_RoundingMode_Up
);
573 throw lang::IllegalArgumentException();
575 double fRet
= floor(comphelper::rng::uniform_real_distribution(fMin
, nextafter(fMax
+1, -DBL_MAX
)));
576 return finiteOrThrow( fRet
);
579 double SAL_CALL
AnalysisAddIn::getGcd( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
)
581 ScaDoubleListGT0 aValList
;
583 aValList
.Append( aVLst
);
584 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
586 if( aValList
.Count() == 0 )
589 double f
= aValList
.Get(0);
590 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
592 f
= GetGcd( aValList
.Get(i
), f
);
595 return finiteOrThrow( f
);
598 double SAL_CALL
AnalysisAddIn::getLcm( const uno::Reference
< beans::XPropertySet
>& xOpt
, const uno::Sequence
< uno::Sequence
< double > >& aVLst
, const uno::Sequence
< uno::Any
>& aOptVLst
)
600 ScaDoubleListGE0 aValList
;
602 aValList
.Append( aVLst
);
603 aValList
.Append( aAnyConv
, xOpt
, aOptVLst
);
605 if( aValList
.Count() == 0 )
608 double f
= rtl::math::approxFloor( aValList
.Get(0) );
610 throw lang::IllegalArgumentException();
615 for( sal_uInt32 i
= 1; i
< aValList
.Count(); ++i
)
617 double fTmp
= rtl::math::approxFloor( aValList
.Get(i
) );
619 throw lang::IllegalArgumentException();
621 f
= fTmp
* f
/ GetGcd( fTmp
, f
);
626 return finiteOrThrow( f
);
629 double SAL_CALL
AnalysisAddIn::getBesseli( double fNum
, sal_Int32 nOrder
)
631 double fRet
= sca::analysis::BesselI( fNum
, nOrder
);
632 return finiteOrThrow( fRet
);
635 double SAL_CALL
AnalysisAddIn::getBesselj( double fNum
, sal_Int32 nOrder
)
637 double fRet
= sca::analysis::BesselJ( fNum
, nOrder
);
638 return finiteOrThrow( fRet
);
641 double SAL_CALL
AnalysisAddIn::getBesselk( double fNum
, sal_Int32 nOrder
)
643 if( nOrder
< 0 || fNum
<= 0.0 )
644 throw lang::IllegalArgumentException();
646 double fRet
= sca::analysis::BesselK( fNum
, nOrder
);
647 return finiteOrThrow( fRet
);
650 double SAL_CALL
AnalysisAddIn::getBessely( double fNum
, sal_Int32 nOrder
)
652 if( nOrder
< 0 || fNum
<= 0.0 )
653 throw lang::IllegalArgumentException();
655 double fRet
= sca::analysis::BesselY( fNum
, nOrder
);
656 return finiteOrThrow( fRet
);
659 const double SCA_MAX2
= 511.0; // min. val for binary numbers (9 bits + sign)
660 const double SCA_MIN2
= -SCA_MAX2
-1.0; // min. val for binary numbers (9 bits + sign)
661 const double SCA_MAX8
= 536870911.0; // max. val for octal numbers (29 bits + sign)
662 const double SCA_MIN8
= -SCA_MAX8
-1.0; // min. val for octal numbers (29 bits + sign)
663 const double SCA_MAX16
= 549755813887.0; // max. val for hexadecimal numbers (39 bits + sign)
664 const double SCA_MIN16
= -SCA_MAX16
-1.0; // min. val for hexadecimal numbers (39 bits + sign)
665 const sal_Int32 SCA_MAXPLACES
= 10; // max. number of places
667 OUString SAL_CALL
AnalysisAddIn::getBin2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
669 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
670 sal_Int32 nPlaces
= 0;
671 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
672 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
675 double SAL_CALL
AnalysisAddIn::getBin2Dec( const OUString
& aNum
)
677 double fRet
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
678 return finiteOrThrow( fRet
);
681 OUString SAL_CALL
AnalysisAddIn::getBin2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
683 double fVal
= ConvertToDec( aNum
, 2, SCA_MAXPLACES
);
684 sal_Int32 nPlaces
= 0;
685 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
686 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
689 OUString SAL_CALL
AnalysisAddIn::getOct2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
691 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
692 sal_Int32 nPlaces
= 0;
693 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
694 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
697 double SAL_CALL
AnalysisAddIn::getOct2Dec( const OUString
& aNum
)
699 double fRet
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
700 return finiteOrThrow( fRet
);
703 OUString SAL_CALL
AnalysisAddIn::getOct2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
705 double fVal
= ConvertToDec( aNum
, 8, SCA_MAXPLACES
);
706 sal_Int32 nPlaces
= 0;
707 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
708 return ConvertFromDec( fVal
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
711 OUString SAL_CALL
AnalysisAddIn::getDec2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
)
713 sal_Int32 nPlaces
= 0;
714 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
715 return ConvertFromDec( nNum
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
718 OUString SAL_CALL
AnalysisAddIn::getDec2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, sal_Int32 nNum
, const uno::Any
& rPlaces
)
720 sal_Int32 nPlaces
= 0;
721 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
722 return ConvertFromDec( nNum
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
725 OUString SAL_CALL
AnalysisAddIn::getDec2Hex( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rPlaces
)
727 sal_Int32 nPlaces
= 0;
728 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
729 return ConvertFromDec( fNum
, SCA_MIN16
, SCA_MAX16
, 16, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
732 OUString SAL_CALL
AnalysisAddIn::getHex2Bin( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
734 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
735 sal_Int32 nPlaces
= 0;
736 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
737 return ConvertFromDec( fVal
, SCA_MIN2
, SCA_MAX2
, 2, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
740 double SAL_CALL
AnalysisAddIn::getHex2Dec( const OUString
& aNum
)
742 double fRet
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
743 return finiteOrThrow( fRet
);
746 OUString SAL_CALL
AnalysisAddIn::getHex2Oct( const uno::Reference
< beans::XPropertySet
>& xOpt
, const OUString
& aNum
, const uno::Any
& rPlaces
)
748 double fVal
= ConvertToDec( aNum
, 16, SCA_MAXPLACES
);
749 sal_Int32 nPlaces
= 0;
750 bool bUsePlaces
= aAnyConv
.getInt32( nPlaces
, xOpt
, rPlaces
);
751 return ConvertFromDec( fVal
, SCA_MIN8
, SCA_MAX8
, 8, nPlaces
, SCA_MAXPLACES
, bUsePlaces
);
754 sal_Int32 SAL_CALL
AnalysisAddIn::getDelta( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum1
, const uno::Any
& rNum2
)
756 return sal_Int32(fNum1
== aAnyConv
.getDouble( xOpt
, rNum2
, 0.0 ));
759 double SAL_CALL
AnalysisAddIn::getErf( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fLL
, const uno::Any
& rUL
)
762 bool bContainsValue
= aAnyConv
.getDouble( fUL
, xOpt
, rUL
);
764 fRet
= bContainsValue
? (Erf( fUL
) - Erf( fLL
)) : Erf( fLL
);
765 return finiteOrThrow( fRet
);
768 double SAL_CALL
AnalysisAddIn::getErfc( double f
)
770 double fRet
= Erfc( f
);
771 return finiteOrThrow( fRet
);
774 sal_Int32 SAL_CALL
AnalysisAddIn::getGestep( const uno::Reference
< beans::XPropertySet
>& xOpt
, double fNum
, const uno::Any
& rStep
)
776 return sal_Int32(fNum
>= aAnyConv
.getDouble( xOpt
, rStep
, 0.0 ));
779 double SAL_CALL
AnalysisAddIn::getFactdouble( sal_Int32 nNum
)
781 double fRet
= FactDouble( nNum
);
782 return finiteOrThrow( fRet
);
785 double SAL_CALL
AnalysisAddIn::getImabs( const OUString
& aNum
)
787 double fRet
= Complex( aNum
).Abs();
788 return finiteOrThrow( fRet
);
791 double SAL_CALL
AnalysisAddIn::getImaginary( const OUString
& aNum
)
793 double fRet
= Complex( aNum
).Imag();
794 return finiteOrThrow( fRet
);
797 OUString SAL_CALL
AnalysisAddIn::getImpower( const OUString
& aNum
, double f
)
803 return z
.GetString();
806 double SAL_CALL
AnalysisAddIn::getImargument( const OUString
& aNum
)
808 double fRet
= Complex( aNum
).Arg();
809 return finiteOrThrow( fRet
);
812 OUString SAL_CALL
AnalysisAddIn::getImcos( const OUString
& aNum
)
818 return z
.GetString();
821 OUString SAL_CALL
AnalysisAddIn::getImdiv( const OUString
& aDivid
, const OUString
& aDivis
)
825 z
.Div( Complex( aDivis
) );
827 return z
.GetString();
830 OUString SAL_CALL
AnalysisAddIn::getImexp( const OUString
& aNum
)
836 return z
.GetString();
839 OUString SAL_CALL
AnalysisAddIn::getImconjugate( const OUString
& aNum
)
845 return z
.GetString();
848 OUString SAL_CALL
AnalysisAddIn::getImln( const OUString
& aNum
)
854 return z
.GetString();
857 OUString SAL_CALL
AnalysisAddIn::getImlog10( const OUString
& aNum
)
863 return z
.GetString();
866 OUString SAL_CALL
AnalysisAddIn::getImlog2( const OUString
& aNum
)
872 return z
.GetString();
875 OUString SAL_CALL
AnalysisAddIn::getImproduct( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aNL
)
879 z_list
.Append( aNum1
);
880 z_list
.Append( aNL
);
883 return Complex( 0 ).GetString();
885 Complex z
= z_list
.Get(0);
886 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
887 z
.Mult( z_list
.Get(i
) );
889 return z
.GetString();
892 double SAL_CALL
AnalysisAddIn::getImreal( const OUString
& aNum
)
894 double fRet
= Complex( aNum
).Real();
895 return finiteOrThrow( fRet
);
898 OUString SAL_CALL
AnalysisAddIn::getImsin( const OUString
& aNum
)
904 return z
.GetString();
907 OUString SAL_CALL
AnalysisAddIn::getImsub( const OUString
& aNum1
, const OUString
& aNum2
)
911 z
.Sub( Complex( aNum2
) );
913 return z
.GetString();
916 OUString SAL_CALL
AnalysisAddIn::getImsum( const uno::Reference
< beans::XPropertySet
>&, const uno::Sequence
< uno::Sequence
< OUString
> >& aNum1
, const uno::Sequence
< uno::Any
>& aFollowingPars
)
920 z_list
.Append( aNum1
);
921 z_list
.Append( aFollowingPars
);
924 return Complex( 0 ).GetString();
926 Complex
z( z_list
.Get(0) );
927 for( sal_uInt32 i
= 1; i
< z_list
.Count(); ++i
)
928 z
.Add( z_list
.Get(i
) );
930 return z
.GetString();
933 OUString SAL_CALL
AnalysisAddIn::getImsqrt( const OUString
& aNum
)
939 return z
.GetString();
942 OUString SAL_CALL
AnalysisAddIn::getImtan( const OUString
& aNum
)
948 return z
.GetString();
951 OUString SAL_CALL
AnalysisAddIn::getImsec( const OUString
& aNum
)
957 return z
.GetString();
960 OUString SAL_CALL
AnalysisAddIn::getImcsc( const OUString
& aNum
)
966 return z
.GetString();
969 OUString SAL_CALL
AnalysisAddIn::getImcot( const OUString
& aNum
)
975 return z
.GetString();
978 OUString SAL_CALL
AnalysisAddIn::getImsinh( const OUString
& aNum
)
984 return z
.GetString();
987 OUString SAL_CALL
AnalysisAddIn::getImcosh( const OUString
& aNum
)
993 return z
.GetString();
996 OUString SAL_CALL
AnalysisAddIn::getImsech( const OUString
& aNum
)
1002 return z
.GetString();
1005 OUString SAL_CALL
AnalysisAddIn::getImcsch( const OUString
& aNum
)
1011 return z
.GetString();
1014 OUString SAL_CALL
AnalysisAddIn::getComplex( double fR
, double fI
, const uno::Any
& rSuff
)
1018 switch( rSuff
.getValueTypeClass() )
1020 case uno::TypeClass_VOID
:
1023 case uno::TypeClass_STRING
:
1025 auto pSuff
= o3tl::forceAccess
<OUString
>(rSuff
);
1026 bi
= *pSuff
== "i" || pSuff
->isEmpty();
1027 if( !bi
&& *pSuff
!= "j" )
1028 throw lang::IllegalArgumentException();
1032 throw lang::IllegalArgumentException();
1035 return Complex( fR
, fI
, bi
? 'i' : 'j' ).GetString();
1038 double SAL_CALL
AnalysisAddIn::getConvert( double f
, const OUString
& aFU
, const OUString
& aTU
)
1041 pCDL
.reset(new ConvertDataList());
1043 double fRet
= pCDL
->Convert( f
, aFU
, aTU
);
1044 return finiteOrThrow( fRet
);
1047 OUString
AnalysisAddIn::AnalysisResId(TranslateId aResId
)
1049 return Translate::get(aResId
, aResLocale
);
1052 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1053 scaddins_AnalysisAddIn_get_implementation(
1054 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
1056 return cppu::acquire(new AnalysisAddIn(context
));
1059 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */