Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / scaddins / source / analysis / analysis.cxx
blob2215f28340d26a280ddb8505fb4310d27ea9a8c7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "analysis.hxx"
31 #include <cppuhelper/factory.hxx>
32 #include <osl/diagnose.h>
33 #include <rtl/ustrbuf.hxx>
34 #include <rtl/math.hxx>
35 #include <sal/macros.h>
36 #include <string.h>
38 #include <tools/resmgr.hxx>
39 #include <tools/rcid.h>
40 #include "analysis.hrc"
41 #include "bessel.hxx"
43 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
44 #define MY_SERVICE "com.sun.star.sheet.addin.Analysis"
45 #define MY_IMPLNAME "com.sun.star.sheet.addin.AnalysisImpl"
47 using namespace ::rtl;
48 using namespace ::com::sun::star;
51 extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL analysis_component_getFactory(
52 const sal_Char* pImplName, void* pServiceManager, void* /*pRegistryKey*/ )
54 void* pRet = 0;
56 if( pServiceManager && STRING::createFromAscii( pImplName ) == AnalysisAddIn::getImplementationName_Static() )
58 REF( lang::XSingleServiceFactory ) xFactory( cppu::createOneInstanceFactory(
59 reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ),
60 AnalysisAddIn::getImplementationName_Static(),
61 AnalysisAddIn_CreateInstance,
62 AnalysisAddIn::getSupportedServiceNames_Static() ) );
64 if( xFactory.is() )
66 xFactory->acquire();
67 pRet = xFactory.get();
71 return pRet;
75 //------------------------------------------------------------------------
77 // "normal" service implementation
79 //------------------------------------------------------------------------
82 ResMgr& AnalysisAddIn::GetResMgr( void ) THROWDEF_RTE
84 if( !pResMgr )
86 InitData(); // try to get resource manager
88 if( !pResMgr )
89 THROW_RTE;
92 return *pResMgr;
96 STRING AnalysisAddIn::GetDisplFuncStr( sal_uInt16 nFuncNum ) THROWDEF_RTE
98 return String( AnalysisRscStrLoader( RID_ANALYSIS_FUNCTION_NAMES, nFuncNum, GetResMgr() ).GetString() );
102 class AnalysisResourcePublisher : public Resource
104 public:
105 AnalysisResourcePublisher( const AnalysisResId& rId ) : Resource( rId ) {}
106 sal_Bool IsAvailableRes( const ResId& rId ) const { return Resource::IsAvailableRes( rId ); }
107 void FreeResource() { Resource::FreeResource(); }
111 class AnalysisFuncRes : public Resource
113 public:
114 AnalysisFuncRes( ResId& rRes, ResMgr& rResMgr, sal_uInt16 nInd, STRING& rRet );
118 AnalysisFuncRes::AnalysisFuncRes( ResId& rRes, ResMgr& rResMgr, sal_uInt16 nInd, STRING& rRet ) : Resource( rRes )
120 rRet = String( AnalysisResId( nInd, rResMgr ) );
122 FreeResource();
126 STRING AnalysisAddIn::GetFuncDescrStr( sal_uInt16 nResId, sal_uInt16 nStrIndex ) THROWDEF_RTE
128 STRING aRet;
129 AnalysisResourcePublisher aResPubl( AnalysisResId( RID_ANALYSIS_FUNCTION_DESCRIPTIONS, GetResMgr() ) );
130 AnalysisResId aRes( nResId, GetResMgr() );
131 aRes.SetRT( RSC_RESOURCE );
132 if( aResPubl.IsAvailableRes( aRes ) )
134 AnalysisFuncRes aSubRes( aRes, GetResMgr(), nStrIndex, aRet );
137 aResPubl.FreeResource();
139 return aRet;
143 void AnalysisAddIn::InitData( void )
145 if( pResMgr )
146 delete pResMgr;
148 OString aModName( "analysis" );
149 pResMgr = ResMgr::CreateResMgr( aModName.getStr(), aFuncLoc );
151 if( pFD )
152 delete pFD;
154 if( pResMgr )
155 pFD = new FuncDataList( *pResMgr );
156 else
157 pFD = NULL;
159 if( pDefLocales )
161 delete pDefLocales;
162 pDefLocales = NULL;
167 AnalysisAddIn::AnalysisAddIn( const uno::Reference< lang::XMultiServiceFactory >& xServiceFact ) :
168 pDefLocales( NULL ),
169 pFD( NULL ),
170 pFactDoubles( NULL ),
171 pCDL( NULL ),
172 pResMgr( NULL ),
173 aAnyConv( xServiceFact )
178 AnalysisAddIn::~AnalysisAddIn()
180 if( pFD )
181 delete pFD;
183 if( pFactDoubles )
184 delete[] pFactDoubles;
186 if( pCDL )
187 delete pCDL;
189 if( pDefLocales )
190 delete[] pDefLocales;
194 sal_Int32 AnalysisAddIn::getDateMode(
195 const uno::Reference< beans::XPropertySet >& xPropSet,
196 const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
198 sal_Int32 nMode = aAnyConv.getInt32( xPropSet, rAny, 0 );
199 if( (nMode < 0) || (nMode > 4) )
200 throw lang::IllegalArgumentException();
201 return nMode;
206 //-----------------------------------------------------------------------------
209 #define MAXFACTDOUBLE 300
211 double AnalysisAddIn::FactDouble( sal_Int32 nNum ) THROWDEF_RTE_IAE
213 if( nNum < 0 || nNum > MAXFACTDOUBLE )
214 THROW_IAE;
216 if( !pFactDoubles )
218 pFactDoubles = new double[ MAXFACTDOUBLE + 1 ];
220 pFactDoubles[ 0 ] = 1.0; // by default
222 double fOdd = 1.0;
223 double fEven = 2.0;
225 pFactDoubles[ 1 ] = fOdd;
226 pFactDoubles[ 2 ] = fEven;
228 sal_Bool bOdd = sal_True;
230 for( sal_uInt16 nCnt = 3 ; nCnt <= MAXFACTDOUBLE ; nCnt++ )
232 if( bOdd )
234 fOdd *= nCnt;
235 pFactDoubles[ nCnt ] = fOdd;
237 else
239 fEven *= nCnt;
240 pFactDoubles[ nCnt ] = fEven;
243 bOdd = !bOdd;
248 return pFactDoubles[ nNum ];
252 STRING AnalysisAddIn::getImplementationName_Static()
254 return STRFROMASCII( MY_IMPLNAME );
258 SEQ( STRING ) AnalysisAddIn::getSupportedServiceNames_Static()
260 SEQ( STRING ) aRet(2);
261 STRING* pArray = aRet.getArray();
262 pArray[0] = STRFROMASCII( ADDIN_SERVICE );
263 pArray[1] = STRFROMASCII( MY_SERVICE );
264 return aRet;
268 REF( uno::XInterface ) SAL_CALL AnalysisAddIn_CreateInstance(
269 const uno::Reference< lang::XMultiServiceFactory >& xServiceFact )
271 static uno::Reference< uno::XInterface > xInst = (cppu::OWeakObject*) new AnalysisAddIn( xServiceFact );
272 return xInst;
276 // XServiceName
278 STRING SAL_CALL AnalysisAddIn::getServiceName() THROWDEF_RTE
280 // name of specific AddIn service
281 return STRFROMASCII( MY_SERVICE );
285 // XServiceInfo
287 STRING SAL_CALL AnalysisAddIn::getImplementationName() THROWDEF_RTE
289 return getImplementationName_Static();
293 sal_Bool SAL_CALL AnalysisAddIn::supportsService( const STRING& aName ) THROWDEF_RTE
295 return aName.compareToAscii( ADDIN_SERVICE ) == 0 || aName.compareToAscii( MY_SERVICE ) == 0;
299 SEQ( STRING ) SAL_CALL AnalysisAddIn::getSupportedServiceNames() THROWDEF_RTE
301 return getSupportedServiceNames_Static();
305 // XLocalizable
307 void SAL_CALL AnalysisAddIn::setLocale( const lang::Locale& eLocale ) THROWDEF_RTE
309 aFuncLoc = eLocale;
311 InitData(); // change of locale invalidates resources!
314 lang::Locale SAL_CALL AnalysisAddIn::getLocale() THROWDEF_RTE
316 return aFuncLoc;
320 // XAddIn
322 STRING SAL_CALL AnalysisAddIn::getProgrammaticFuntionName( const STRING& ) THROWDEF_RTE
324 // not used by calc
325 // (but should be implemented for other uses of the AddIn service)
327 return STRING();
331 STRING SAL_CALL AnalysisAddIn::getDisplayFunctionName( const STRING& aProgrammaticName ) THROWDEF_RTE
333 STRING aRet;
335 const FuncData* p = pFD->Get( aProgrammaticName );
336 if( p )
338 aRet = GetDisplFuncStr( p->GetUINameID() );
339 if( p->IsDouble() )
340 aRet += STRFROMANSI( "_ADD" );
342 else
344 aRet = STRFROMANSI( "UNKNOWNFUNC_" );
345 aRet += aProgrammaticName;
348 return aRet;
352 STRING SAL_CALL AnalysisAddIn::getFunctionDescription( const STRING& aProgrammaticName ) THROWDEF_RTE
354 STRING aRet;
356 const FuncData* p = pFD->Get( aProgrammaticName );
357 if( p )
358 aRet = GetFuncDescrStr( p->GetDescrID(), 1 );
360 return aRet;
364 STRING SAL_CALL AnalysisAddIn::getDisplayArgumentName( const STRING& aName, sal_Int32 nArg ) THROWDEF_RTE
366 STRING aRet;
368 const FuncData* p = pFD->Get( aName );
369 if( p && nArg <= 0xFFFF )
371 sal_uInt16 nStr = p->GetStrIndex( sal_uInt16( nArg ) );
372 if( nStr )
373 aRet = GetFuncDescrStr( p->GetDescrID(), nStr );
374 else
375 aRet = STRFROMANSI( "internal" );
378 return aRet;
382 STRING SAL_CALL AnalysisAddIn::getArgumentDescription( const STRING& aName, sal_Int32 nArg ) THROWDEF_RTE
384 STRING aRet;
386 const FuncData* p = pFD->Get( aName );
387 if( p && nArg <= 0xFFFF )
389 sal_uInt16 nStr = p->GetStrIndex( sal_uInt16( nArg ) );
390 if( nStr )
391 aRet = GetFuncDescrStr( p->GetDescrID(), nStr + 1 );
392 else
393 aRet = STRFROMANSI( "for internal use only" );
396 return aRet;
400 static const char* pDefCatName = "Add-In";
403 STRING SAL_CALL AnalysisAddIn::getProgrammaticCategoryName( const STRING& aName ) THROWDEF_RTE
405 // return non-translated strings
406 // return STRFROMASCII( "Add-In" );
407 const FuncData* p = pFD->Get( aName );
408 STRING aRet;
409 if( p )
411 const sal_Char* pStr;
413 switch( p->GetCategory() )
415 case FDCat_DateTime: pStr = "Date&Time"; break;
416 case FDCat_Finance: pStr = "Financial"; break;
417 case FDCat_Inf: pStr = "Information"; break;
418 case FDCat_Math: pStr = "Mathematical"; break;
419 case FDCat_Tech: pStr = "Technical"; break;
420 default:
421 pStr = pDefCatName; break;
424 aRet = STRFROMASCII( pStr );
426 else
427 aRet = STRFROMASCII( pDefCatName );
429 return aRet;
433 STRING SAL_CALL AnalysisAddIn::getDisplayCategoryName( const STRING& aProgrammaticFunctionName ) THROWDEF_RTE
435 // return translated strings, not used for predefined categories
436 // return STRFROMASCII( "Add-In" );
437 const FuncData* p = pFD->Get( aProgrammaticFunctionName );
438 STRING aRet;
439 if( p )
441 const sal_Char* pStr;
443 switch( p->GetCategory() )
445 case FDCat_DateTime: pStr = "Date&Time"; break;
446 case FDCat_Finance: pStr = "Financial"; break;
447 case FDCat_Inf: pStr = "Information"; break;
448 case FDCat_Math: pStr = "Mathematical"; break;
449 case FDCat_Tech: pStr = "Technical"; break;
450 default:
451 pStr = pDefCatName; break;
454 aRet = STRFROMASCII( pStr );
456 else
457 aRet = STRFROMASCII( pDefCatName );
459 return aRet;
463 static const sal_Char* pLang[] = { "de", "en" };
464 static const sal_Char* pCoun[] = { "DE", "US" };
465 static const sal_uInt32 nNumOfLoc = SAL_N_ELEMENTS(pLang);
468 void AnalysisAddIn::InitDefLocales( void )
470 pDefLocales = new ::com::sun::star::lang::Locale[ nNumOfLoc ];
472 for( sal_uInt32 n = 0 ; n < nNumOfLoc ; n++ )
474 pDefLocales[ n ].Language = STRING::createFromAscii( pLang[ n ] );
475 pDefLocales[ n ].Country = STRING::createFromAscii( pCoun[ n ] );
480 inline const ::com::sun::star::lang::Locale& AnalysisAddIn::GetLocale( sal_uInt32 nInd )
482 if( !pDefLocales )
483 InitDefLocales();
485 if( nInd < sizeof( pLang ) )
486 return pDefLocales[ nInd ];
487 else
488 return aFuncLoc;
492 SEQofLocName SAL_CALL AnalysisAddIn::getCompatibilityNames( const STRING& aProgrammaticName ) THROWDEF_RTE
494 const FuncData* p = pFD->Get( aProgrammaticName );
496 if( !p )
497 return SEQofLocName( 0 );
499 const StringList& r = p->GetCompNameList();
500 sal_uInt32 nCount = r.Count();
502 SEQofLocName aRet( nCount );
504 ::com::sun::star::sheet::LocalizedName* pArray = aRet.getArray();
506 for( sal_uInt32 n = 0 ; n < nCount ; n++ )
508 pArray[ n ] = ::com::sun::star::sheet::LocalizedName( GetLocale( n ), *r.Get( n ) );
511 return aRet;
515 // XAnalysis
518 * Workday
521 sal_Int32 SAL_CALL AnalysisAddIn::getWorkday( constREFXPS& xOptions,
522 sal_Int32 nDate, sal_Int32 nDays, const ANY& aHDay ) THROWDEF_RTE_IAE
524 if( !nDays )
525 return nDate;
527 sal_Int32 nNullDate = GetNullDate( xOptions );
529 SortedIndividualInt32List aSrtLst;
531 aSrtLst.InsertHolidayList( aAnyConv, xOptions, aHDay, nNullDate, sal_False );
533 sal_Int32 nActDate = nDate + nNullDate;
535 if( nDays > 0 )
537 if( GetDayOfWeek( nActDate ) == 5 )
538 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
539 nActDate++;
541 while( nDays )
543 nActDate++;
545 if( GetDayOfWeek( nActDate ) < 5 )
547 if( !aSrtLst.Find( nActDate ) )
548 nDays--;
550 else
551 nActDate++; // jump over weekend
554 else
556 if( GetDayOfWeek( nActDate ) == 6 )
557 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
558 nActDate--;
560 while( nDays )
562 nActDate--;
564 if( GetDayOfWeek( nActDate ) < 5 )
566 if( !aSrtLst.Find( nActDate ) )
567 nDays++;
569 else
570 nActDate--; // jump over weekend
574 return nActDate - nNullDate;
579 * Yearfrac
582 double SAL_CALL AnalysisAddIn::getYearfrac( constREFXPS& xOpt,
583 sal_Int32 nStartDate, sal_Int32 nEndDate, const ANY& rMode ) THROWDEF_RTE_IAE
585 double fRet = GetYearFrac( xOpt, nStartDate, nEndDate, getDateMode( xOpt, rMode ) );
586 RETURN_FINITE( fRet );
590 sal_Int32 SAL_CALL AnalysisAddIn::getEdate( constREFXPS& xOpt, sal_Int32 nStartDate, sal_Int32 nMonths ) THROWDEF_RTE_IAE
592 sal_Int32 nNullDate = GetNullDate( xOpt );
593 ScaDate aDate( nNullDate, nStartDate, 5 );
594 aDate.addMonths( nMonths );
595 return aDate.getDate( nNullDate );
599 sal_Int32 SAL_CALL AnalysisAddIn::getWeeknum( constREFXPS& xOpt, sal_Int32 nDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
601 nDate += GetNullDate( xOpt );
603 sal_uInt16 nDay, nMonth, nYear;
604 DaysToDate( nDate, nDay, nMonth, nYear );
606 sal_Int32 nFirstInYear = DateToDays( 1, 1, nYear );
607 sal_uInt16 nFirstDayInYear = GetDayOfWeek( nFirstInYear );
609 return ( nDate - nFirstInYear + ( ( nMode == 1 )? ( nFirstDayInYear + 1 ) % 7 : nFirstDayInYear ) ) / 7 + 1;
613 sal_Int32 SAL_CALL AnalysisAddIn::getEomonth( constREFXPS& xOpt, sal_Int32 nDate, sal_Int32 nMonths ) THROWDEF_RTE_IAE
615 sal_Int32 nNullDate = GetNullDate( xOpt );
616 nDate += nNullDate;
617 sal_uInt16 nDay, nMonth, nYear;
618 DaysToDate( nDate, nDay, nMonth, nYear );
620 sal_Int32 nNewMonth = nMonth + nMonths;
622 if( nNewMonth > 12 )
624 nYear = sal::static_int_cast<sal_uInt16>( nYear + ( nNewMonth / 12 ) );
625 nNewMonth %= 12;
627 else if( nNewMonth < 1 )
629 nNewMonth = -nNewMonth;
630 nYear = sal::static_int_cast<sal_uInt16>( nYear - ( nNewMonth / 12 ) );
631 nYear--;
632 nNewMonth %= 12;
633 nNewMonth = 12 - nNewMonth;
636 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth ), nYear ), sal_uInt16( nNewMonth ), nYear ) - nNullDate;
640 sal_Int32 SAL_CALL AnalysisAddIn::getNetworkdays( constREFXPS& xOpt,
641 sal_Int32 nStartDate, sal_Int32 nEndDate, const ANY& aHDay ) THROWDEF_RTE_IAE
643 sal_Int32 nNullDate = GetNullDate( xOpt );
645 SortedIndividualInt32List aSrtLst;
647 aSrtLst.InsertHolidayList( aAnyConv, xOpt, aHDay, nNullDate, sal_False );
649 sal_Int32 nActDate = nStartDate + nNullDate;
650 sal_Int32 nStopDate = nEndDate + nNullDate;
651 sal_Int32 nCnt = 0;
653 if( nActDate <= nStopDate )
655 while( nActDate <= nStopDate )
657 if( GetDayOfWeek( nActDate ) < 5 && !aSrtLst.Find( nActDate ) )
658 nCnt++;
660 nActDate++;
663 else
665 while( nActDate >= nStopDate )
667 if( GetDayOfWeek( nActDate ) < 5 && !aSrtLst.Find( nActDate ) )
668 nCnt--;
670 nActDate--;
674 return nCnt;
678 sal_Int32 SAL_CALL AnalysisAddIn::getIseven( sal_Int32 nVal ) THROWDEF_RTE_IAE
680 return ( nVal & 0x00000001 )? 0 : 1;
684 sal_Int32 SAL_CALL AnalysisAddIn::getIsodd( sal_Int32 nVal ) THROWDEF_RTE_IAE
686 return ( nVal & 0x00000001 )? 1 : 0;
689 double SAL_CALL
690 AnalysisAddIn::getMultinomial( constREFXPS& xOpt, const SEQSEQ( sal_Int32 )& aVLst,
691 const SEQ( uno::Any )& aOptVLst ) THROWDEF_RTE_IAE
693 ScaDoubleListGE0 aValList;
695 aValList.Append( aVLst );
696 aValList.Append( aAnyConv, xOpt, aOptVLst );
698 if( aValList.Count() == 0 )
699 return 0.0;
701 sal_Int32 nZ = 0;
702 double fN = 1.0;
704 for( const double *p = aValList.First(); p; p = aValList.Next() )
706 double fInt = (*p >= 0.0) ? rtl::math::approxFloor( *p ) : rtl::math::approxCeil( *p );
707 if ( fInt < 0.0 || fInt > 170.0 )
708 THROW_IAE;
709 sal_Int32 n = static_cast< sal_Int32 >( fInt );
710 if( n > 0 )
712 nZ += n;
713 fN *= Fak( n );
717 if( nZ > 170 )
718 THROW_IAE;
720 double fRet = Fak( nZ ) / fN;
721 RETURN_FINITE( fRet );
725 double SAL_CALL AnalysisAddIn::getSeriessum( double fX, double fN, double fM, const SEQSEQ( double )& aCoeffList ) THROWDEF_RTE_IAE
727 double fRet = 0.0;
729 // #i32269# 0^0 is undefined, Excel returns #NUM! error
730 if( fX == 0.0 && fN == 0 )
731 THROW_RTE;
733 if( fX != 0.0 )
735 sal_Int32 n1, n2;
736 sal_Int32 nE1 = aCoeffList.getLength();
737 sal_Int32 nE2;
739 for( n1 = 0 ; n1 < nE1 ; n1++ )
741 const SEQ( double )& rList = aCoeffList[ n1 ];
742 nE2 = rList.getLength();
743 const double* pList = rList.getConstArray();
745 for( n2 = 0 ; n2 < nE2 ; n2++ )
747 fRet += pList[ n2 ] * pow( fX, fN );
749 fN += fM;
754 RETURN_FINITE( fRet );
758 double SAL_CALL AnalysisAddIn::getQuotient( double fNum, double fDenom ) THROWDEF_RTE_IAE
760 double fRet;
761 if( (fNum < 0) != (fDenom < 0) )
762 fRet = ::rtl::math::approxCeil( fNum / fDenom );
763 else
764 fRet = ::rtl::math::approxFloor( fNum / fDenom );
765 RETURN_FINITE( fRet );
769 double SAL_CALL AnalysisAddIn::getMround( double fNum, double fMult ) THROWDEF_RTE_IAE
771 if( fMult == 0.0 )
772 return fMult;
774 double fRet = fMult * ::rtl::math::round( fNum / fMult );
775 RETURN_FINITE( fRet );
779 double SAL_CALL AnalysisAddIn::getSqrtpi( double fNum ) THROWDEF_RTE_IAE
781 double fRet = sqrt( fNum * PI );
782 RETURN_FINITE( fRet );
786 double SAL_CALL AnalysisAddIn::getRandbetween( double fMin, double fMax ) THROWDEF_RTE_IAE
788 fMin = ::rtl::math::round( fMin, 0, rtl_math_RoundingMode_Up );
789 fMax = ::rtl::math::round( fMax, 0, rtl_math_RoundingMode_Up );
790 if( fMin > fMax )
791 THROW_IAE;
793 // fMax -> range
794 double fRet = fMax - fMin + 1.0;
795 fRet *= rand();
796 fRet /= (RAND_MAX + 1.0);
797 fRet += fMin;
798 fRet = floor( fRet ); // simple floor is sufficient here
799 RETURN_FINITE( fRet );
803 double SAL_CALL AnalysisAddIn::getGcd( constREFXPS& xOpt, const SEQSEQ( double )& aVLst, const SEQ( uno::Any )& aOptVLst ) THROWDEF_RTE_IAE
805 ScaDoubleListGT0 aValList;
807 aValList.Append( aVLst );
808 aValList.Append( aAnyConv, xOpt, aOptVLst );
810 if( aValList.Count() == 0 )
811 return 0.0;
813 const double* p = aValList.First();
814 double f = *p;
816 p = aValList.Next();
818 while( p )
820 f = GetGcd( *p, f );
821 p = aValList.Next();
824 RETURN_FINITE( f );
828 double SAL_CALL AnalysisAddIn::getLcm( constREFXPS& xOpt, const SEQSEQ( double )& aVLst, const SEQ( uno::Any )& aOptVLst ) THROWDEF_RTE_IAE
830 ScaDoubleListGE0 aValList;
832 aValList.Append( aVLst );
833 aValList.Append( aAnyConv, xOpt, aOptVLst );
835 if( aValList.Count() == 0 )
836 return 0.0;
838 const double* p = aValList.First();
839 double f = *p;
841 if( f == 0.0 )
842 return f;
844 p = aValList.Next();
846 while( p )
848 double fTmp = *p;
849 if( f == 0.0 )
850 return f;
851 else
852 f = fTmp * f / GetGcd( fTmp, f );
853 p = aValList.Next();
856 RETURN_FINITE( f );
860 double SAL_CALL AnalysisAddIn::getBesseli( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
862 double fRet = sca::analysis::BesselI( fNum, nOrder );
863 RETURN_FINITE( fRet );
867 double SAL_CALL AnalysisAddIn::getBesselj( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
869 double fRet = sca::analysis::BesselJ( fNum, nOrder );
870 RETURN_FINITE( fRet );
874 double SAL_CALL AnalysisAddIn::getBesselk( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
876 if( nOrder < 0 || fNum <= 0.0 )
877 THROW_IAE;
879 double fRet = sca::analysis::BesselK( fNum, nOrder );
880 RETURN_FINITE( fRet );
884 double SAL_CALL AnalysisAddIn::getBessely( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
886 if( nOrder < 0 || fNum <= 0.0 )
887 THROW_IAE;
889 double fRet = sca::analysis::BesselY( fNum, nOrder );
890 RETURN_FINITE( fRet );
894 const double SCA_MAX2 = 511.0; // min. val for binary numbers (9 bits + sign)
895 const double SCA_MIN2 = -SCA_MAX2-1.0; // min. val for binary numbers (9 bits + sign)
896 const double SCA_MAX8 = 536870911.0; // max. val for octal numbers (29 bits + sign)
897 const double SCA_MIN8 = -SCA_MAX8-1.0; // min. val for octal numbers (29 bits + sign)
898 const double SCA_MAX16 = 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
899 const double SCA_MIN16 = -SCA_MAX16-1.0; // min. val for hexadecimal numbers (39 bits + sign)
900 const sal_Int32 SCA_MAXPLACES = 10; // max. number of places
903 STRING SAL_CALL AnalysisAddIn::getBin2Oct( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
905 double fVal = ConvertToDec( aNum, 2, SCA_MAXPLACES );
906 sal_Int32 nPlaces = 0;
907 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
908 return ConvertFromDec( fVal, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
912 double SAL_CALL AnalysisAddIn::getBin2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
914 double fRet = ConvertToDec( aNum, 2, SCA_MAXPLACES );
915 RETURN_FINITE( fRet );
919 STRING SAL_CALL AnalysisAddIn::getBin2Hex( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
921 double fVal = ConvertToDec( aNum, 2, SCA_MAXPLACES );
922 sal_Int32 nPlaces = 0;
923 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
924 return ConvertFromDec( fVal, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
928 STRING SAL_CALL AnalysisAddIn::getOct2Bin( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
930 double fVal = ConvertToDec( aNum, 8, SCA_MAXPLACES );
931 sal_Int32 nPlaces = 0;
932 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
933 return ConvertFromDec( fVal, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
937 double SAL_CALL AnalysisAddIn::getOct2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
939 double fRet = ConvertToDec( aNum, 8, SCA_MAXPLACES );
940 RETURN_FINITE( fRet );
944 STRING SAL_CALL AnalysisAddIn::getOct2Hex( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
946 double fVal = ConvertToDec( aNum, 8, SCA_MAXPLACES );
947 sal_Int32 nPlaces = 0;
948 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
949 return ConvertFromDec( fVal, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
953 STRING SAL_CALL AnalysisAddIn::getDec2Bin( constREFXPS& xOpt, sal_Int32 nNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
955 sal_Int32 nPlaces = 0;
956 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
957 return ConvertFromDec( nNum, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
961 STRING SAL_CALL AnalysisAddIn::getDec2Oct( constREFXPS& xOpt, sal_Int32 nNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
963 sal_Int32 nPlaces = 0;
964 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
965 return ConvertFromDec( nNum, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
969 STRING SAL_CALL AnalysisAddIn::getDec2Hex( constREFXPS& xOpt, double fNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
971 sal_Int32 nPlaces = 0;
972 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
973 return ConvertFromDec( fNum, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
977 STRING SAL_CALL AnalysisAddIn::getHex2Bin( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
979 double fVal = ConvertToDec( aNum, 16, SCA_MAXPLACES );
980 sal_Int32 nPlaces = 0;
981 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
982 return ConvertFromDec( fVal, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
986 double SAL_CALL AnalysisAddIn::getHex2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
988 double fRet = ConvertToDec( aNum, 16, SCA_MAXPLACES );
989 RETURN_FINITE( fRet );
993 STRING SAL_CALL AnalysisAddIn::getHex2Oct( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
995 double fVal = ConvertToDec( aNum, 16, SCA_MAXPLACES );
996 sal_Int32 nPlaces = 0;
997 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
998 return ConvertFromDec( fVal, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
1002 sal_Int32 SAL_CALL AnalysisAddIn::getDelta( constREFXPS& xOpt, double fNum1, const ANY& rNum2 ) THROWDEF_RTE_IAE
1004 return fNum1 == aAnyConv.getDouble( xOpt, rNum2, 0.0 );
1008 double SAL_CALL AnalysisAddIn::getErf( constREFXPS& xOpt, double fLL, const ANY& rUL ) THROWDEF_RTE_IAE
1010 double fUL, fRet;
1011 sal_Bool bContainsValue = aAnyConv.getDouble( fUL, xOpt, rUL );
1013 fRet = bContainsValue ? (Erf( fUL ) - Erf( fLL )) : Erf( fLL );
1014 RETURN_FINITE( fRet );
1018 double SAL_CALL AnalysisAddIn::getErfc( double f ) THROWDEF_RTE_IAE
1020 double fRet = Erfc( f );
1021 RETURN_FINITE( fRet );
1025 sal_Int32 SAL_CALL AnalysisAddIn::getGestep( constREFXPS& xOpt, double fNum, const ANY& rStep ) THROWDEF_RTE_IAE
1027 return fNum >= aAnyConv.getDouble( xOpt, rStep, 0.0 );
1031 double SAL_CALL AnalysisAddIn::getFactdouble( sal_Int32 nNum ) THROWDEF_RTE_IAE
1033 double fRet = FactDouble( nNum );
1034 RETURN_FINITE( fRet );
1038 double SAL_CALL AnalysisAddIn::getImabs( const STRING& aNum ) THROWDEF_RTE_IAE
1040 double fRet = Complex( aNum ).Abs();
1041 RETURN_FINITE( fRet );
1045 double SAL_CALL AnalysisAddIn::getImaginary( const STRING& aNum ) THROWDEF_RTE_IAE
1047 double fRet = Complex( aNum ).Imag();
1048 RETURN_FINITE( fRet );
1052 STRING SAL_CALL AnalysisAddIn::getImpower( const STRING& aNum, double f ) THROWDEF_RTE_IAE
1054 Complex z( aNum );
1056 z.Power( f );
1058 return z.GetString();
1062 double SAL_CALL AnalysisAddIn::getImargument( const STRING& aNum ) THROWDEF_RTE_IAE
1064 double fRet = Complex( aNum ).Arg();
1065 RETURN_FINITE( fRet );
1069 STRING SAL_CALL AnalysisAddIn::getImcos( const STRING& aNum ) THROWDEF_RTE_IAE
1071 Complex z( aNum );
1073 z.Cos();
1075 return z.GetString();
1079 STRING SAL_CALL AnalysisAddIn::getImdiv( const STRING& aDivid, const STRING& aDivis ) THROWDEF_RTE_IAE
1081 Complex z( aDivid );
1083 z.Div( Complex( aDivis ) );
1085 return z.GetString();
1089 STRING SAL_CALL AnalysisAddIn::getImexp( const STRING& aNum ) THROWDEF_RTE_IAE
1091 Complex z( aNum );
1093 z.Exp();
1095 return z.GetString();
1099 STRING SAL_CALL AnalysisAddIn::getImconjugate( const STRING& aNum ) THROWDEF_RTE_IAE
1101 Complex z( aNum );
1103 z.Conjugate();
1105 return z.GetString();
1109 STRING SAL_CALL AnalysisAddIn::getImln( const STRING& aNum ) THROWDEF_RTE_IAE
1111 Complex z( aNum );
1113 z.Ln();
1115 return z.GetString();
1119 STRING SAL_CALL AnalysisAddIn::getImlog10( const STRING& aNum ) THROWDEF_RTE_IAE
1121 Complex z( aNum );
1123 z.Log10();
1125 return z.GetString();
1129 STRING SAL_CALL AnalysisAddIn::getImlog2( const STRING& aNum ) THROWDEF_RTE_IAE
1131 Complex z( aNum );
1133 z.Log2();
1135 return z.GetString();
1139 STRING SAL_CALL AnalysisAddIn::getImproduct( constREFXPS&, const SEQSEQ( STRING )& aNum1, const SEQ( uno::Any )& aNL ) THROWDEF_RTE_IAE
1141 ComplexList z_list;
1143 z_list.Append( aNum1, AH_IgnoreEmpty );
1144 z_list.Append( aNL, AH_IgnoreEmpty );
1146 const Complex* p = z_list.First();
1148 if( !p )
1149 return Complex( 0 ).GetString();
1151 Complex z( *p );
1153 for( p = z_list.Next() ; p ; p = z_list.Next() )
1154 z.Mult( *p );
1156 return z.GetString();
1160 double SAL_CALL AnalysisAddIn::getImreal( const STRING& aNum ) THROWDEF_RTE_IAE
1162 double fRet = Complex( aNum ).Real();
1163 RETURN_FINITE( fRet );
1167 STRING SAL_CALL AnalysisAddIn::getImsin( const STRING& aNum ) THROWDEF_RTE_IAE
1169 Complex z( aNum );
1171 z.Sin();
1173 return z.GetString();
1177 STRING SAL_CALL AnalysisAddIn::getImsub( const STRING& aNum1, const STRING& aNum2 ) THROWDEF_RTE_IAE
1179 Complex z( aNum1 );
1181 z.Sub( Complex( aNum2 ) );
1183 return z.GetString();
1187 STRING SAL_CALL AnalysisAddIn::getImsum( constREFXPS&, const SEQSEQ( STRING )& aNum1, const SEQ( ::com::sun::star::uno::Any )& aFollowingPars ) THROWDEF_RTE_IAE
1189 ComplexList z_list;
1191 z_list.Append( aNum1, AH_IgnoreEmpty );
1192 z_list.Append( aFollowingPars, AH_IgnoreEmpty );
1194 const Complex* p = z_list.First();
1196 if( !p )
1197 return Complex( 0 ).GetString();
1199 Complex z( *p );
1201 for( p = z_list.Next() ; p ; p = z_list.Next() )
1202 z.Add( *p );
1204 return z.GetString();
1208 STRING SAL_CALL AnalysisAddIn::getImsqrt( const STRING& aNum ) THROWDEF_RTE_IAE
1210 Complex z( aNum );
1212 z.Sqrt();
1214 return z.GetString();
1218 STRING SAL_CALL AnalysisAddIn::getImtan( const STRING& aNum ) THROWDEF_RTE_IAE
1220 Complex z( aNum );
1222 z.Tan();
1224 return z.GetString();
1228 STRING SAL_CALL AnalysisAddIn::getImsec( const STRING& aNum ) THROWDEF_RTE_IAE
1230 Complex z( aNum );
1232 z.Sec();
1234 return z.GetString();
1238 STRING SAL_CALL AnalysisAddIn::getImcsc( const STRING& aNum ) THROWDEF_RTE_IAE
1240 Complex z( aNum );
1242 z.Csc();
1244 return z.GetString();
1248 STRING SAL_CALL AnalysisAddIn::getImcot( const STRING& aNum ) THROWDEF_RTE_IAE
1250 Complex z( aNum );
1252 z.Cot();
1254 return z.GetString();
1258 STRING SAL_CALL AnalysisAddIn::getImsinh( const STRING& aNum ) THROWDEF_RTE_IAE
1260 Complex z( aNum );
1262 z.Sinh();
1264 return z.GetString();
1268 STRING SAL_CALL AnalysisAddIn::getImcosh( const STRING& aNum ) THROWDEF_RTE_IAE
1270 Complex z( aNum );
1272 z.Cosh();
1274 return z.GetString();
1278 STRING SAL_CALL AnalysisAddIn::getImsech( const STRING& aNum ) THROWDEF_RTE_IAE
1280 Complex z( aNum );
1282 z.Sech();
1284 return z.GetString();
1288 STRING SAL_CALL AnalysisAddIn::getImcsch( const STRING& aNum ) THROWDEF_RTE_IAE
1290 Complex z( aNum );
1292 z.Csch();
1294 return z.GetString();
1298 STRING SAL_CALL AnalysisAddIn::getComplex( double fR, double fI, const ANY& rSuff ) THROWDEF_RTE_IAE
1300 sal_Bool bi;
1302 switch( rSuff.getValueTypeClass() )
1304 case uno::TypeClass_VOID:
1305 bi = sal_True;
1306 break;
1307 case uno::TypeClass_STRING:
1309 const STRING* pSuff = ( const STRING* ) rSuff.getValue();
1310 bi = pSuff->compareToAscii( "i" ) == 0 || pSuff->isEmpty();
1311 if( !bi && pSuff->compareToAscii( "j" ) != 0 )
1312 THROW_IAE;
1314 break;
1315 default:
1316 THROW_IAE;
1319 return Complex( fR, fI, bi ? 'i' : 'j' ).GetString();
1323 double SAL_CALL AnalysisAddIn::getConvert( double f, const STRING& aFU, const STRING& aTU ) THROWDEF_RTE_IAE
1325 if( !pCDL )
1326 pCDL = new ConvertDataList();
1328 double fRet = pCDL->Convert( f, aFU, aTU );
1329 RETURN_FINITE( fRet );
1333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */