Bump version to 6.0-36
[LibreOffice.git] / scaddins / source / analysis / analysis.cxx
blob862bd2532a8d5ac24440ec9f9c365d57d21151b4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include "bessel.hxx"
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>
31 #include <string.h>
32 #include <unotools/resmgr.hxx>
33 #include <algorithm>
34 #include <cmath>
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;
42 using namespace std;
44 extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL analysis_component_getFactory(
45 const sal_Char* pImplName, void* pServiceManager, void* /*pRegistryKey*/ )
47 void* pRet = nullptr;
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() ) );
57 if( xFactory.is() )
59 xFactory->acquire();
60 pRet = xFactory.get();
64 return pRet;
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));
76 delete pFD;
77 pFD = new FuncDataList;
78 InitFuncDataList(*pFD);
80 delete pDefLocales;
81 pDefLocales = nullptr;
84 AnalysisAddIn::AnalysisAddIn( const uno::Reference< uno::XComponentContext >& xContext ) :
85 pDefLocales( nullptr ),
86 pFD( nullptr ),
87 pFactDoubles( nullptr ),
88 pCDL( nullptr ),
89 aAnyConv( xContext )
93 AnalysisAddIn::~AnalysisAddIn()
95 delete pCDL;
96 delete pFD;
97 delete[] pDefLocales;
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();
107 return nMode;
110 #define MAXFACTDOUBLE 300
112 double AnalysisAddIn::FactDouble( sal_Int32 nNum )
114 if( nNum < 0 || nNum > MAXFACTDOUBLE )
115 throw lang::IllegalArgumentException();
117 if( !pFactDoubles )
119 pFactDoubles.reset( new double[ MAXFACTDOUBLE + 1 ] );
121 pFactDoubles[ 0 ] = 1.0; // by default
123 double fOdd = 1.0;
124 double fEven = 2.0;
126 pFactDoubles[ 1 ] = fOdd;
127 pFactDoubles[ 2 ] = fEven;
129 bool bOdd = true;
131 for( sal_uInt16 nCnt = 3 ; nCnt <= MAXFACTDOUBLE ; nCnt++ )
133 if( bOdd )
135 fOdd *= nCnt;
136 pFactDoubles[ nCnt ] = fOdd;
138 else
140 fEven *= nCnt;
141 pFactDoubles[ nCnt ] = fEven;
144 bOdd = !bOdd;
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;
163 return aRet;
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) ));
172 // XServiceName
173 OUString SAL_CALL AnalysisAddIn::getServiceName()
175 // name of specific AddIn service
176 return OUString( MY_SERVICE );
179 // XServiceInfo
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();
195 // XLocalizable
196 void SAL_CALL AnalysisAddIn::setLocale( const lang::Locale& eLocale )
198 aFuncLoc = eLocale;
200 InitData(); // change of locale invalidates resources!
203 lang::Locale SAL_CALL AnalysisAddIn::getLocale()
205 return aFuncLoc;
208 // XAddIn
209 OUString SAL_CALL AnalysisAddIn::getProgrammaticFuntionName( const OUString& )
211 // not used by calc
212 // (but should be implemented for other uses of the AddIn service)
214 return OUString();
217 OUString SAL_CALL AnalysisAddIn::getDisplayFunctionName( const OUString& aProgrammaticName )
219 OUString aRet;
221 auto it = std::find_if(pFD->begin(), pFD->end(), FindFuncData( aProgrammaticName ) );
222 if( it != pFD->end() )
224 aRet = AnalysisResId(it->GetUINameID());
225 if( it->IsDouble() )
227 const OUString& rSuffix = it->GetSuffix();
228 if (!rSuffix.isEmpty())
229 aRet += rSuffix;
230 else
231 aRet += "_ADD";
234 else
236 aRet = "UNKNOWNFUNC_" + aProgrammaticName;
239 return aRet;
242 OUString SAL_CALL AnalysisAddIn::getFunctionDescription( const OUString& aProgrammaticName )
244 OUString aRet;
246 auto it = std::find_if(pFD->begin(), pFD->end(), FindFuncData( aProgrammaticName ) );
247 if( it != pFD->end() )
248 aRet = GetFuncDescrStr( it->GetDescrID(), 1 );
250 return aRet;
253 OUString SAL_CALL AnalysisAddIn::getDisplayArgumentName( const OUString& aName, sal_Int32 nArg )
255 OUString aRet;
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 ) );
261 if( nStr )
262 aRet = GetFuncDescrStr( it->GetDescrID(), nStr );
263 else
264 aRet = "internal";
267 return aRet;
270 OUString SAL_CALL AnalysisAddIn::getArgumentDescription( const OUString& aName, sal_Int32 nArg )
272 OUString aRet;
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 ) );
278 if( nStr )
279 aRet = GetFuncDescrStr( it->GetDescrID(), nStr + 1 );
280 else
281 aRet = "for internal use only";
284 return aRet;
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 ) );
294 OUString aRet;
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;
306 else
307 aRet = pDefCatName;
309 return aRet;
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 ) );
316 OUString aRet;
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;
328 else
329 aRet = pDefCatName;
331 return aRet;
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 )
351 if( !pDefLocales )
352 InitDefLocales();
354 if( nInd < sizeof( pLang ) )
355 return pDefLocales[ nInd ];
356 else
357 return aFuncLoc;
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] );
378 return aRet;
381 // XAnalysis
382 /** Workday */
383 sal_Int32 SAL_CALL AnalysisAddIn::getWorkday( const uno::Reference< beans::XPropertySet >& xOptions,
384 sal_Int32 nDate, sal_Int32 nDays, const uno::Any& aHDay )
386 if( !nDays )
387 return nDate;
389 sal_Int32 nNullDate = GetNullDate( xOptions );
391 SortedIndividualInt32List aSrtLst;
393 aSrtLst.InsertHolidayList( aAnyConv, xOptions, aHDay, nNullDate );
395 sal_Int32 nActDate = nDate + nNullDate;
397 if( nDays > 0 )
399 if( GetDayOfWeek( nActDate ) == 5 )
400 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
401 nActDate++;
403 while( nDays )
405 nActDate++;
407 if( GetDayOfWeek( nActDate ) < 5 )
409 if( !aSrtLst.Find( nActDate ) )
410 nDays--;
412 else
413 nActDate++; // jump over weekend
416 else
418 if( GetDayOfWeek( nActDate ) == 6 )
419 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
420 nActDate--;
422 while( nDays )
424 nActDate--;
426 if( GetDayOfWeek( nActDate ) < 5 )
428 if( !aSrtLst.Find( nActDate ) )
429 nDays++;
431 else
432 nActDate--; // jump over weekend
436 return nActDate - nNullDate;
439 /** Yearfrac */
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 );
471 nDate += nNullDate;
472 sal_uInt16 nDay, nMonth, nYear;
473 DaysToDate( nDate, nDay, nMonth, nYear );
475 sal_Int32 nNewMonth = nMonth + nMonths;
477 if( nNewMonth > 12 )
479 nYear = sal::static_int_cast<sal_uInt16>( nYear + ( nNewMonth / 12 ) );
480 nNewMonth %= 12;
482 else if( nNewMonth < 1 )
484 nNewMonth = -nNewMonth;
485 nYear = sal::static_int_cast<sal_uInt16>( nYear - ( nNewMonth / 12 ) );
486 nYear--;
487 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;
505 sal_Int32 nCnt = 0;
507 if( nActDate <= nStopDate )
509 while( nActDate <= nStopDate )
511 if( GetDayOfWeek( nActDate ) < 5 && !aSrtLst.Find( nActDate ) )
512 nCnt++;
514 nActDate++;
517 else
519 while( nActDate >= nStopDate )
521 if( GetDayOfWeek( nActDate ) < 5 && !aSrtLst.Find( nActDate ) )
522 nCnt--;
524 nActDate--;
528 return nCnt;
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;
541 double SAL_CALL
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 )
551 return 0.0;
553 double nZ = 0;
554 double fRet = 1.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 );
560 if ( n < 0.0 )
561 throw lang::IllegalArgumentException();
563 if( n > 0.0 )
565 nZ += n;
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 )
574 double fRet = 0.0;
576 // #i32269# 0^0 is undefined, Excel returns #NUM! error
577 if( fX == 0.0 && fN == 0 )
578 throw uno::RuntimeException();
580 if( fX != 0.0 )
582 sal_Int32 n1, n2;
583 sal_Int32 nE1 = aCoeffList.getLength();
584 sal_Int32 nE2;
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 );
596 fN += fM;
601 RETURN_FINITE( fRet );
604 double SAL_CALL AnalysisAddIn::getQuotient( double fNum, double fDenom )
606 double fRet;
607 if( (fNum < 0) != (fDenom < 0) )
608 fRet = ::rtl::math::approxCeil( fNum / fDenom );
609 else
610 fRet = ::rtl::math::approxFloor( fNum / fDenom );
611 RETURN_FINITE( fRet );
614 double SAL_CALL AnalysisAddIn::getMround( double fNum, double fMult )
616 if( fMult == 0.0 )
617 return 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 );
633 if( fMin > fMax )
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 )
648 return 0.0;
650 double f = aValList.Get(0);
651 for( sal_uInt32 i = 1; i < aValList.Count(); ++i )
653 f = GetGcd( aValList.Get(i), f );
656 RETURN_FINITE( 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 )
667 return 0.0;
669 double f = rtl::math::approxFloor( aValList.Get(0) );
670 if( f < 0.0 )
671 throw lang::IllegalArgumentException();
673 if( f == 0.0 )
674 return f;
676 for( sal_uInt32 i = 1; i < aValList.Count(); ++i )
678 double fTmp = rtl::math::approxFloor( aValList.Get(i) );
679 if( fTmp < 0.0 )
680 throw lang::IllegalArgumentException();
682 f = fTmp * f / GetGcd( fTmp, f );
683 if( f == 0.0 )
684 return f;
687 RETURN_FINITE( 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 )
822 double fUL, fRet;
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 )
860 Complex z( aNum );
862 z.Power( 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 )
875 Complex z( aNum );
877 z.Cos();
879 return z.GetString();
882 OUString SAL_CALL AnalysisAddIn::getImdiv( const OUString& aDivid, const OUString& aDivis )
884 Complex z( aDivid );
886 z.Div( Complex( aDivis ) );
888 return z.GetString();
891 OUString SAL_CALL AnalysisAddIn::getImexp( const OUString& aNum )
893 Complex z( aNum );
895 z.Exp();
897 return z.GetString();
900 OUString SAL_CALL AnalysisAddIn::getImconjugate( const OUString& aNum )
902 Complex z( aNum );
904 z.Conjugate();
906 return z.GetString();
909 OUString SAL_CALL AnalysisAddIn::getImln( const OUString& aNum )
911 Complex z( aNum );
913 z.Ln();
915 return z.GetString();
918 OUString SAL_CALL AnalysisAddIn::getImlog10( const OUString& aNum )
920 Complex z( aNum );
922 z.Log10();
924 return z.GetString();
927 OUString SAL_CALL AnalysisAddIn::getImlog2( const OUString& aNum )
929 Complex z( aNum );
931 z.Log2();
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 )
938 ComplexList z_list;
940 z_list.Append( aNum1, AH_IgnoreEmpty );
941 z_list.Append( aNL, AH_IgnoreEmpty );
943 if( z_list.empty() )
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 )
961 Complex z( aNum );
963 z.Sin();
965 return z.GetString();
968 OUString SAL_CALL AnalysisAddIn::getImsub( const OUString& aNum1, const OUString& aNum2 )
970 Complex z( aNum1 );
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 )
979 ComplexList z_list;
981 z_list.Append( aNum1, AH_IgnoreEmpty );
982 z_list.Append( aFollowingPars, AH_IgnoreEmpty );
984 if( z_list.empty() )
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 )
996 Complex z( aNum );
998 z.Sqrt();
1000 return z.GetString();
1003 OUString SAL_CALL AnalysisAddIn::getImtan( const OUString& aNum )
1005 Complex z( aNum );
1007 z.Tan();
1009 return z.GetString();
1012 OUString SAL_CALL AnalysisAddIn::getImsec( const OUString& aNum )
1014 Complex z( aNum );
1016 z.Sec();
1018 return z.GetString();
1021 OUString SAL_CALL AnalysisAddIn::getImcsc( const OUString& aNum )
1023 Complex z( aNum );
1025 z.Csc();
1027 return z.GetString();
1030 OUString SAL_CALL AnalysisAddIn::getImcot( const OUString& aNum )
1032 Complex z( aNum );
1034 z.Cot();
1036 return z.GetString();
1039 OUString SAL_CALL AnalysisAddIn::getImsinh( const OUString& aNum )
1041 Complex z( aNum );
1043 z.Sinh();
1045 return z.GetString();
1048 OUString SAL_CALL AnalysisAddIn::getImcosh( const OUString& aNum )
1050 Complex z( aNum );
1052 z.Cosh();
1054 return z.GetString();
1057 OUString SAL_CALL AnalysisAddIn::getImsech( const OUString& aNum )
1059 Complex z( aNum );
1061 z.Sech();
1063 return z.GetString();
1066 OUString SAL_CALL AnalysisAddIn::getImcsch( const OUString& aNum )
1068 Complex z( aNum );
1070 z.Csch();
1072 return z.GetString();
1075 OUString SAL_CALL AnalysisAddIn::getComplex( double fR, double fI, const uno::Any& rSuff )
1077 bool bi;
1079 switch( rSuff.getValueTypeClass() )
1081 case uno::TypeClass_VOID:
1082 bi = true;
1083 break;
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();
1091 break;
1092 default:
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 )
1101 if( !pCDL )
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: */