1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "analysis.hxx"
25
26 #include <cppuhelper/factory.hxx>
27 #include <osl/diagnose.h>
28 #include <rtl/ustrbuf.hxx>
29 #include <rtl/math.hxx>
30 #include <rtl/random.h>
31 #include <string.h>
32
33 #include <tools/resmgr.hxx>
34 #include <tools/rcid.h>
35 #include "analysis.hrc"
36 #include "bessel.hxx"
37
38 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
39 #define MY_SERVICE "com.sun.star.sheet.addin.Analysis"
40 #define MY_IMPLNAME "com.sun.star.sheet.addin.AnalysisImpl"
41
42 using namespace ::rtl;
43 using namespace ::com::sun::star;
44
45 //------------------------------------------------------------------
46 //
47 // entry points for service registration / instantiation
48 //
49 //------------------------------------------------------------------
50
51 extern "C" {
52
53
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)54 void SAL_CALL component_getImplementationEnvironment( const sal_Char** ppEnvTypeName, uno_Environment** /*ppEnv*/ )
55 {
56 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
57 }
58
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void *)59 void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /*pRegistryKey*/ )
60 {
61 void* pRet = 0;
62
63 if( pServiceManager && STRING::createFromAscii( pImplName ) == AnalysisAddIn::getImplementationName_Static() )
64 {
65 REF( lang::XSingleServiceFactory ) xFactory( cppu::createOneInstanceFactory(
66 reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ),
67 AnalysisAddIn::getImplementationName_Static(),
68 AnalysisAddIn_CreateInstance,
69 AnalysisAddIn::getSupportedServiceNames_Static() ) );
70
71 if( xFactory.is() )
72 {
73 xFactory->acquire();
74 pRet = xFactory.get();
75 }
76 }
77
78 return pRet;
79 }
80
81
82 } // extern C
83
84
85
86
87 //------------------------------------------------------------------------
88 //
89 // "normal" service implementation
90 //
91 //------------------------------------------------------------------------
92
93
GetResMgr(void)94 ResMgr& AnalysisAddIn::GetResMgr( void ) THROWDEF_RTE
95 {
96 if( !pResMgr )
97 {
98 InitData(); // try to get resource manager
99
100 if( !pResMgr )
101 THROW_RTE;
102 }
103
104 return *pResMgr;
105 }
106
107
GetDisplFuncStr(sal_uInt16 nFuncNum)108 STRING AnalysisAddIn::GetDisplFuncStr( sal_uInt16 nFuncNum ) THROWDEF_RTE
109 {
110 return String( AnalysisRscStrLoader( RID_ANALYSIS_FUNCTION_NAMES, nFuncNum, GetResMgr() ).GetString() );
111 }
112
113
114 class AnalysisResourcePublisher : public Resource
115 {
116 public:
AnalysisResourcePublisher(const AnalysisResId & rId)117 AnalysisResourcePublisher( const AnalysisResId& rId ) : Resource( rId ) {}
IsAvailableRes(const ResId & rId) const118 sal_Bool IsAvailableRes( const ResId& rId ) const { return Resource::IsAvailableRes( rId ); }
FreeResource()119 void FreeResource() { Resource::FreeResource(); }
120 };
121
122
123 class AnalysisFuncRes : public Resource
124 {
125 public:
126 AnalysisFuncRes( ResId& rRes, ResMgr& rResMgr, sal_uInt16 nInd, STRING& rRet );
127 };
128
129
AnalysisFuncRes(ResId & rRes,ResMgr & rResMgr,sal_uInt16 nInd,STRING & rRet)130 AnalysisFuncRes::AnalysisFuncRes( ResId& rRes, ResMgr& rResMgr, sal_uInt16 nInd, STRING& rRet ) : Resource( rRes )
131 {
132 rRet = String( AnalysisResId( nInd, rResMgr ) );
133
134 FreeResource();
135 }
136
137
GetFuncDescrStr(sal_uInt16 nResId,sal_uInt16 nStrIndex)138 STRING AnalysisAddIn::GetFuncDescrStr( sal_uInt16 nResId, sal_uInt16 nStrIndex ) THROWDEF_RTE
139 {
140 STRING aRet;
141 AnalysisResourcePublisher aResPubl( AnalysisResId( RID_ANALYSIS_FUNCTION_DESCRIPTIONS, GetResMgr() ) );
142 AnalysisResId aRes( nResId, GetResMgr() );
143 aRes.SetRT( RSC_RESOURCE );
144 if( aResPubl.IsAvailableRes( aRes ) )
145 {
146 AnalysisFuncRes aSubRes( aRes, GetResMgr(), nStrIndex, aRet );
147 }
148
149 aResPubl.FreeResource();
150
151 return aRet;
152 }
153
154
InitData(void)155 void AnalysisAddIn::InitData( void )
156 {
157 if( pResMgr )
158 delete pResMgr;
159
160 OString aModName( "analysis" );
161 pResMgr = ResMgr::CreateResMgr( aModName.getStr(), aFuncLoc );
162
163 if( pFD )
164 delete pFD;
165
166 if( pResMgr )
167 pFD = new FuncDataList( *pResMgr );
168 else
169 pFD = NULL;
170
171 if( pDefLocales )
172 {
173 delete pDefLocales;
174 pDefLocales = NULL;
175 }
176 }
177
178
AnalysisAddIn(const uno::Reference<lang::XMultiServiceFactory> & xServiceFact)179 AnalysisAddIn::AnalysisAddIn( const uno::Reference< lang::XMultiServiceFactory >& xServiceFact ) :
180 pDefLocales( NULL ),
181 pFD( NULL ),
182 pFactDoubles( NULL ),
183 pCDL( NULL ),
184 pResMgr( NULL ),
185 aAnyConv( xServiceFact )
186 {
187 }
188
189
~AnalysisAddIn()190 AnalysisAddIn::~AnalysisAddIn()
191 {
192 if( pFD )
193 delete pFD;
194
195 if( pFactDoubles )
196 delete[] pFactDoubles;
197
198 if( pCDL )
199 delete pCDL;
200
201 // if( pResMgr ) no delete, because _all_ resource managers are deleted _before_ this dtor is called
202 // delete pResMgr;
203
204 if( pDefLocales )
205 delete[] pDefLocales;
206 }
207
208
getDateMode(const uno::Reference<beans::XPropertySet> & xPropSet,const uno::Any & rAny)209 sal_Int32 AnalysisAddIn::getDateMode(
210 const uno::Reference< beans::XPropertySet >& xPropSet,
211 const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
212 {
213 sal_Int32 nMode = aAnyConv.getInt32( xPropSet, rAny, 0 );
214 if( (nMode < 0) || (nMode > 4) )
215 throw lang::IllegalArgumentException();
216 return nMode;
217 }
218
219
220
221 //-----------------------------------------------------------------------------
222
223
224 #define MAXFACTDOUBLE 300
225
FactDouble(sal_Int32 nNum)226 double AnalysisAddIn::FactDouble( sal_Int32 nNum ) THROWDEF_RTE_IAE
227 {
228 if( nNum < 0 || nNum > MAXFACTDOUBLE )
229 THROW_IAE;
230
231 if( !pFactDoubles )
232 {
233 pFactDoubles = new double[ MAXFACTDOUBLE + 1 ];
234
235 pFactDoubles[ 0 ] = 1.0; // by default
236
237 double fOdd = 1.0;
238 double fEven = 2.0;
239
240 pFactDoubles[ 1 ] = fOdd;
241 pFactDoubles[ 2 ] = fEven;
242
243 sal_Bool bOdd = sal_True;
244
245 for( sal_uInt16 nCnt = 3 ; nCnt <= MAXFACTDOUBLE ; nCnt++ )
246 {
247 if( bOdd )
248 {
249 fOdd *= nCnt;
250 pFactDoubles[ nCnt ] = fOdd;
251 }
252 else
253 {
254 fEven *= nCnt;
255 pFactDoubles[ nCnt ] = fEven;
256 }
257
258 bOdd = !bOdd;
259
260 }
261 }
262
263 return pFactDoubles[ nNum ];
264 }
265
266
getImplementationName_Static()267 STRING AnalysisAddIn::getImplementationName_Static()
268 {
269 return STRFROMASCII( MY_IMPLNAME );
270 }
271
272
SEQ(STRING)273 SEQ( STRING ) AnalysisAddIn::getSupportedServiceNames_Static()
274 {
275 SEQ( STRING ) aRet(2);
276 STRING* pArray = aRet.getArray();
277 pArray[0] = STRFROMASCII( ADDIN_SERVICE );
278 pArray[1] = STRFROMASCII( MY_SERVICE );
279 return aRet;
280 }
281
282
REF(uno::XInterface)283 REF( uno::XInterface ) SAL_CALL AnalysisAddIn_CreateInstance(
284 const uno::Reference< lang::XMultiServiceFactory >& xServiceFact )
285 {
286 static uno::Reference< uno::XInterface > xInst = (cppu::OWeakObject*) new AnalysisAddIn( xServiceFact );
287 return xInst;
288 }
289
290
291 // XServiceName
292
getServiceName()293 STRING SAL_CALL AnalysisAddIn::getServiceName() THROWDEF_RTE
294 {
295 // name of specific AddIn service
296 return STRFROMASCII( MY_SERVICE );
297 }
298
299
300 // XServiceInfo
301
getImplementationName()302 STRING SAL_CALL AnalysisAddIn::getImplementationName() THROWDEF_RTE
303 {
304 return getImplementationName_Static();
305 }
306
307
supportsService(const STRING & aName)308 sal_Bool SAL_CALL AnalysisAddIn::supportsService( const STRING& aName ) THROWDEF_RTE
309 {
310 return aName.compareToAscii( ADDIN_SERVICE ) == 0 || aName.compareToAscii( MY_SERVICE ) == 0;
311 }
312
313
SEQ(STRING)314 SEQ( STRING ) SAL_CALL AnalysisAddIn::getSupportedServiceNames() THROWDEF_RTE
315 {
316 return getSupportedServiceNames_Static();
317 }
318
319
320 // XLocalizable
321
setLocale(const lang::Locale & eLocale)322 void SAL_CALL AnalysisAddIn::setLocale( const lang::Locale& eLocale ) THROWDEF_RTE
323 {
324 aFuncLoc = eLocale;
325
326 InitData(); // change of locale invalidates resources!
327 }
328
getLocale()329 lang::Locale SAL_CALL AnalysisAddIn::getLocale() THROWDEF_RTE
330 {
331 return aFuncLoc;
332 }
333
334
335 // XAddIn
336
getProgrammaticFuntionName(const STRING &)337 STRING SAL_CALL AnalysisAddIn::getProgrammaticFuntionName( const STRING& ) THROWDEF_RTE
338 {
339 // not used by calc
340 // (but should be implemented for other uses of the AddIn service)
341
342 return STRING();
343 }
344
345
getDisplayFunctionName(const STRING & aProgrammaticName)346 STRING SAL_CALL AnalysisAddIn::getDisplayFunctionName( const STRING& aProgrammaticName ) THROWDEF_RTE
347 {
348 STRING aRet;
349
350 const FuncData* p = pFD->Get( aProgrammaticName );
351 if( p )
352 {
353 aRet = GetDisplFuncStr( p->GetUINameID() );
354 if( p->IsDouble() )
355 aRet += STRFROMANSI( "_ADD" );
356 }
357 else
358 {
359 aRet = STRFROMANSI( "UNKNOWNFUNC_" );
360 aRet += aProgrammaticName;
361 }
362
363 return aRet;
364 }
365
366
getFunctionDescription(const STRING & aProgrammaticName)367 STRING SAL_CALL AnalysisAddIn::getFunctionDescription( const STRING& aProgrammaticName ) THROWDEF_RTE
368 {
369 STRING aRet;
370
371 const FuncData* p = pFD->Get( aProgrammaticName );
372 if( p )
373 aRet = GetFuncDescrStr( p->GetDescrID(), 1 );
374
375 return aRet;
376 }
377
378
getDisplayArgumentName(const STRING & aName,sal_Int32 nArg)379 STRING SAL_CALL AnalysisAddIn::getDisplayArgumentName( const STRING& aName, sal_Int32 nArg ) THROWDEF_RTE
380 {
381 STRING aRet;
382
383 const FuncData* p = pFD->Get( aName );
384 if( p && nArg <= 0xFFFF )
385 {
386 sal_uInt16 nStr = p->GetStrIndex( sal_uInt16( nArg ) );
387 if( nStr /*&& nStr < 4*/ )
388 aRet = GetFuncDescrStr( p->GetDescrID(), nStr );
389 else
390 aRet = STRFROMANSI( "internal" );
391 }
392
393 return aRet;
394 }
395
396
getArgumentDescription(const STRING & aName,sal_Int32 nArg)397 STRING SAL_CALL AnalysisAddIn::getArgumentDescription( const STRING& aName, sal_Int32 nArg ) THROWDEF_RTE
398 {
399 STRING aRet;
400
401 const FuncData* p = pFD->Get( aName );
402 if( p && nArg <= 0xFFFF )
403 {
404 sal_uInt16 nStr = p->GetStrIndex( sal_uInt16( nArg ) );
405 if( nStr /*&& nStr < 4*/ )
406 aRet = GetFuncDescrStr( p->GetDescrID(), nStr + 1 );
407 else
408 aRet = STRFROMANSI( "for internal use only" );
409 }
410
411 return aRet;
412 }
413
414
415 static const char* pDefCatName = "Add-In";
416
417
getProgrammaticCategoryName(const STRING & aName)418 STRING SAL_CALL AnalysisAddIn::getProgrammaticCategoryName( const STRING& aName ) THROWDEF_RTE
419 {
420 // return non-translated strings
421 // return STRFROMASCII( "Add-In" );
422 const FuncData* p = pFD->Get( aName );
423 STRING aRet;
424 if( p )
425 {
426 const sal_Char* pStr;
427
428 switch( p->GetCategory() )
429 {
430 case FDCat_DateTime: pStr = "Date&Time"; break;
431 case FDCat_Finance: pStr = "Financial"; break;
432 case FDCat_Inf: pStr = "Information"; break;
433 case FDCat_Math: pStr = "Mathematical"; break;
434 case FDCat_Tech: pStr = "Technical"; break;
435 default:
436 pStr = pDefCatName; break;
437 }
438
439 aRet = STRFROMASCII( pStr );
440 }
441 else
442 aRet = STRFROMASCII( pDefCatName );
443
444 return aRet;
445 }
446
447
getDisplayCategoryName(const STRING & aProgrammaticFunctionName)448 STRING SAL_CALL AnalysisAddIn::getDisplayCategoryName( const STRING& aProgrammaticFunctionName ) THROWDEF_RTE
449 {
450 // return translated strings, not used for predefined categories
451 // return STRFROMASCII( "Add-In" );
452 const FuncData* p = pFD->Get( aProgrammaticFunctionName );
453 STRING aRet;
454 if( p )
455 {
456 const sal_Char* pStr;
457
458 switch( p->GetCategory() )
459 {
460 case FDCat_DateTime: pStr = "Date&Time"; break;
461 case FDCat_Finance: pStr = "Financial"; break;
462 case FDCat_Inf: pStr = "Information"; break;
463 case FDCat_Math: pStr = "Mathematical"; break;
464 case FDCat_Tech: pStr = "Technical"; break;
465 default:
466 pStr = pDefCatName; break;
467 }
468
469 aRet = STRFROMASCII( pStr );
470 }
471 else
472 aRet = STRFROMASCII( pDefCatName );
473
474 return aRet;
475 }
476
477
478 static const sal_Char* pLang[] = { "de", "en" };
479 static const sal_Char* pCoun[] = { "DE", "US" };
480 static const sal_uInt32 nNumOfLoc = sizeof( pLang ) / sizeof( sal_Char* );
481
482
InitDefLocales(void)483 void AnalysisAddIn::InitDefLocales( void )
484 {
485 pDefLocales = new CSS::lang::Locale[ nNumOfLoc ];
486
487 for( sal_uInt32 n = 0 ; n < nNumOfLoc ; n++ )
488 {
489 pDefLocales[ n ].Language = STRING::createFromAscii( pLang[ n ] );
490 pDefLocales[ n ].Country = STRING::createFromAscii( pCoun[ n ] );
491 }
492 }
493
494
GetLocale(sal_uInt32 nInd)495 inline const CSS::lang::Locale& AnalysisAddIn::GetLocale( sal_uInt32 nInd )
496 {
497 if( !pDefLocales )
498 InitDefLocales();
499
500 if( nInd < sizeof( pLang ) )
501 return pDefLocales[ nInd ];
502 else
503 return aFuncLoc;
504 }
505
506
getCompatibilityNames(const STRING & aProgrammaticName)507 SEQofLocName SAL_CALL AnalysisAddIn::getCompatibilityNames( const STRING& aProgrammaticName ) THROWDEF_RTE
508 {
509 const FuncData* p = pFD->Get( aProgrammaticName );
510
511 if( !p )
512 return SEQofLocName( 0 );
513
514 const StringList& r = p->GetCompNameList();
515 sal_uInt32 nCount = r.Count();
516
517 SEQofLocName aRet( nCount );
518
519 CSS::sheet::LocalizedName* pArray = aRet.getArray();
520
521 for( sal_uInt32 n = 0 ; n < nCount ; n++ )
522 {
523 pArray[ n ] = CSS::sheet::LocalizedName( GetLocale( n ), *r.Get( n ) );
524 }
525
526 return aRet;
527 }
528
529
530 // XAnalysis
531
532 /*double SAL_CALL AnalysisAddIn::get_Test( constREFXPS&,
533 sal_Int32 nMode, double f1, double f2, double f3 ) THROWDEF_RTE
534 {
535 return _Test( nMode, f1, f2, f3 );
536 }*/
537
538
539 /**
540 * Workday
541 */
542
getWorkday(constREFXPS & xOptions,sal_Int32 nDate,sal_Int32 nDays,const ANY & aHDay)543 sal_Int32 SAL_CALL AnalysisAddIn::getWorkday( constREFXPS& xOptions,
544 sal_Int32 nDate, sal_Int32 nDays, const ANY& aHDay ) THROWDEF_RTE_IAE
545 {
546 if( !nDays )
547 return nDate;
548
549 sal_Int32 nNullDate = GetNullDate( xOptions );
550
551 SortedIndividualInt32List aSrtLst;
552
553 aSrtLst.InsertHolidayList( aAnyConv, xOptions, aHDay, nNullDate, sal_False );
554
555 sal_Int32 nActDate = nDate + nNullDate;
556
557 if( nDays > 0 )
558 {
559 if( GetDayOfWeek( nActDate ) == 5 )
560 // when starting on Saturday, assuming we're starting on Sunday to get the jump over the weekend
561 nActDate++;
562
563 while( nDays )
564 {
565 nActDate++;
566
567 if( GetDayOfWeek( nActDate ) < 5 )
568 {
569 if( !aSrtLst.Find( nActDate ) )
570 nDays--;
571 }
572 else
573 nActDate++; // jump over weekend
574 }
575 }
576 else
577 {
578 if( GetDayOfWeek( nActDate ) == 6 )
579 // when starting on Sunday, assuming we're starting on Saturday to get the jump over the weekend
580 nActDate--;
581
582 while( nDays )
583 {
584 nActDate--;
585
586 if( GetDayOfWeek( nActDate ) < 5 )
587 {
588 if( !aSrtLst.Find( nActDate ) )
589 nDays++;
590 }
591 else
592 nActDate--; // jump over weekend
593 }
594 }
595
596 return nActDate - nNullDate;
597 }
598
599
600 /**
601 * Yearfrac
602 */
603
getYearfrac(constREFXPS & xOpt,sal_Int32 nStartDate,sal_Int32 nEndDate,const ANY & rMode)604 double SAL_CALL AnalysisAddIn::getYearfrac( constREFXPS& xOpt,
605 sal_Int32 nStartDate, sal_Int32 nEndDate, const ANY& rMode ) THROWDEF_RTE_IAE
606 {
607 double fRet = GetYearFrac( xOpt, nStartDate, nEndDate, getDateMode( xOpt, rMode ) );
608 RETURN_FINITE( fRet );
609 }
610
611
getEdate(constREFXPS & xOpt,sal_Int32 nStartDate,sal_Int32 nMonths)612 sal_Int32 SAL_CALL AnalysisAddIn::getEdate( constREFXPS& xOpt, sal_Int32 nStartDate, sal_Int32 nMonths ) THROWDEF_RTE_IAE
613 {
614 sal_Int32 nNullDate = GetNullDate( xOpt );
615 ScaDate aDate( nNullDate, nStartDate, 5 );
616 aDate.addMonths( nMonths );
617 return aDate.getDate( nNullDate );
618 }
619
620
getWeeknum(constREFXPS & xOpt,sal_Int32 nDate,sal_Int32 nMode)621 sal_Int32 SAL_CALL AnalysisAddIn::getWeeknum( constREFXPS& xOpt, sal_Int32 nDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
622 {
623 nDate += GetNullDate( xOpt );
624
625 sal_uInt16 nDay, nMonth, nYear;
626 DaysToDate( nDate, nDay, nMonth, nYear );
627
628 sal_Int32 nFirstInYear = DateToDays( 1, 1, nYear );
629 sal_uInt16 nFirstDayInYear = GetDayOfWeek( nFirstInYear );
630
631 return ( nDate - nFirstInYear + ( ( nMode == 1 )? ( nFirstDayInYear + 1 ) % 7 : nFirstDayInYear ) ) / 7 + 1;
632 }
633
634
getEomonth(constREFXPS & xOpt,sal_Int32 nDate,sal_Int32 nMonths)635 sal_Int32 SAL_CALL AnalysisAddIn::getEomonth( constREFXPS& xOpt, sal_Int32 nDate, sal_Int32 nMonths ) THROWDEF_RTE_IAE
636 {
637 sal_Int32 nNullDate = GetNullDate( xOpt );
638 nDate += nNullDate;
639 sal_uInt16 nDay, nMonth, nYear;
640 DaysToDate( nDate, nDay, nMonth, nYear );
641
642 sal_Int32 nNewMonth = nMonth + nMonths;
643
644 if( nNewMonth > 12 )
645 {
646 nYear = sal::static_int_cast<sal_uInt16>( nYear + ( nNewMonth / 12 ) );
647 nNewMonth %= 12;
648 }
649 else if( nNewMonth < 1 )
650 {
651 nNewMonth = -nNewMonth;
652 nYear = sal::static_int_cast<sal_uInt16>( nYear - ( nNewMonth / 12 ) );
653 nYear--;
654 nNewMonth %= 12;
655 nNewMonth = 12 - nNewMonth;
656 }
657
658 return DateToDays( DaysInMonth( sal_uInt16( nNewMonth ), nYear ), sal_uInt16( nNewMonth ), nYear ) - nNullDate;
659 }
660
661
getNetworkdays(constREFXPS & xOpt,sal_Int32 nStartDate,sal_Int32 nEndDate,const ANY & aHDay)662 sal_Int32 SAL_CALL AnalysisAddIn::getNetworkdays( constREFXPS& xOpt,
663 sal_Int32 nStartDate, sal_Int32 nEndDate, const ANY& aHDay ) THROWDEF_RTE_IAE
664 {
665 sal_Int32 nNullDate = GetNullDate( xOpt );
666
667 SortedIndividualInt32List aSrtLst;
668
669 aSrtLst.InsertHolidayList( aAnyConv, xOpt, aHDay, nNullDate, sal_False );
670
671 sal_Int32 nActDate = nStartDate + nNullDate;
672 sal_Int32 nStopDate = nEndDate + nNullDate;
673 sal_Int32 nCnt = 0;
674
675 if( nActDate <= nStopDate )
676 {
677 while( nActDate <= nStopDate )
678 {
679 if( GetDayOfWeek( nActDate ) < 5 && !aSrtLst.Find( nActDate ) )
680 nCnt++;
681
682 nActDate++;
683 }
684 }
685 else
686 {
687 while( nActDate >= nStopDate )
688 {
689 if( GetDayOfWeek( nActDate ) < 5 && !aSrtLst.Find( nActDate ) )
690 nCnt--;
691
692 nActDate--;
693 }
694 }
695
696 return nCnt;
697 }
698
699
getIseven(sal_Int32 nVal)700 sal_Int32 SAL_CALL AnalysisAddIn::getIseven( sal_Int32 nVal ) THROWDEF_RTE_IAE
701 {
702 return ( nVal & 0x00000001 )? 0 : 1;
703 }
704
705
getIsodd(sal_Int32 nVal)706 sal_Int32 SAL_CALL AnalysisAddIn::getIsodd( sal_Int32 nVal ) THROWDEF_RTE_IAE
707 {
708 return ( nVal & 0x00000001 )? 1 : 0;
709 }
710
711 double SAL_CALL
getMultinomial(constREFXPS & xOpt,const SEQSEQ (sal_Int32)& aVLst,const SEQ (uno::Any)& aOptVLst)712 AnalysisAddIn::getMultinomial( constREFXPS& xOpt, const SEQSEQ( sal_Int32 )& aVLst,
713 const SEQ( uno::Any )& aOptVLst ) THROWDEF_RTE_IAE
714 {
715 ScaDoubleListGE0 aValList;
716
717 aValList.Append( aVLst );
718 aValList.Append( aAnyConv, xOpt, aOptVLst );
719
720 if( aValList.Count() == 0 )
721 return 0.0;
722
723 sal_Int32 nZ = 0;
724 double fN = 1.0;
725
726 for( const double *p = aValList.First(); p; p = aValList.Next() )
727 {
728 double fInt = (*p >= 0.0) ? rtl::math::approxFloor( *p ) : rtl::math::approxCeil( *p );
729 if ( fInt < 0.0 || fInt > 170.0 )
730 THROW_IAE;
731 sal_Int32 n = static_cast< sal_Int32 >( fInt );
732 if( n > 0 )
733 {
734 nZ += n;
735 fN *= Fak( n );
736 }
737 }
738
739 if( nZ > 170 )
740 THROW_IAE;
741
742 double fRet = Fak( nZ ) / fN;
743 RETURN_FINITE( fRet );
744 }
745
746
getSeriessum(double fX,double fN,double fM,const SEQSEQ (double)& aCoeffList)747 double SAL_CALL AnalysisAddIn::getSeriessum( double fX, double fN, double fM, const SEQSEQ( double )& aCoeffList ) THROWDEF_RTE_IAE
748 {
749 double fRet = 0.0;
750
751 // #i32269# 0^0 is undefined, Excel returns #NUM! error
752 if( fX == 0.0 && fN == 0 )
753 THROW_RTE;
754
755 if( fX != 0.0 )
756 {
757 sal_Int32 n1, n2;
758 sal_Int32 nE1 = aCoeffList.getLength();
759 sal_Int32 nE2;
760 //sal_Int32 nZ = 0;
761
762 for( n1 = 0 ; n1 < nE1 ; n1++ )
763 {
764 const SEQ( double )& rList = aCoeffList[ n1 ];
765 nE2 = rList.getLength();
766 const double* pList = rList.getConstArray();
767
768 for( n2 = 0 ; n2 < nE2 ; n2++ )
769 {
770 fRet += pList[ n2 ] * pow( fX, fN );
771
772 fN += fM;
773 }
774 }
775 }
776
777 RETURN_FINITE( fRet );
778 }
779
780
getQuotient(double fNum,double fDenom)781 double SAL_CALL AnalysisAddIn::getQuotient( double fNum, double fDenom ) THROWDEF_RTE_IAE
782 {
783 double fRet;
784 if( (fNum < 0) != (fDenom < 0) )
785 fRet = ::rtl::math::approxCeil( fNum / fDenom );
786 else
787 fRet = ::rtl::math::approxFloor( fNum / fDenom );
788 RETURN_FINITE( fRet );
789 }
790
791
getMround(double fNum,double fMult)792 double SAL_CALL AnalysisAddIn::getMround( double fNum, double fMult ) THROWDEF_RTE_IAE
793 {
794 if( fMult == 0.0 )
795 return fMult;
796
797 double fRet = fMult * ::rtl::math::round( fNum / fMult );
798 RETURN_FINITE( fRet );
799 }
800
801
getSqrtpi(double fNum)802 double SAL_CALL AnalysisAddIn::getSqrtpi( double fNum ) THROWDEF_RTE_IAE
803 {
804 double fRet = sqrt( fNum * PI );
805 RETURN_FINITE( fRet );
806 }
807
808
getRandbetween(double fMin,double fMax)809 double SAL_CALL AnalysisAddIn::getRandbetween( double fMin, double fMax ) THROWDEF_RTE_IAE
810 {
811 static sal_Int32 nScRandomIx = 0, nScRandomIy = 0, nScRandomIz = 0, nScRandomIt = 0;
812 static rtlRandomPool aPool = rtl_random_createPool();
813 double fScRandomW;
814
815 fMin = ::rtl::math::round( fMin, 0, rtl_math_RoundingMode_Up );
816 fMax = ::rtl::math::round( fMax, 0, rtl_math_RoundingMode_Up );
817 if( fMin > fMax )
818 THROW_IAE;
819
820 // Seeding for the PRNG: should be good enough but we
821 // monitor the values to keep things under control.
822 if (nScRandomIx <= 0)
823 rtl_random_getBytes(aPool, &nScRandomIx, sizeof(nScRandomIx));
824 if (nScRandomIy <= 0)
825 rtl_random_getBytes(aPool, &nScRandomIy, sizeof(nScRandomIy));
826 if (nScRandomIz <= 0)
827 rtl_random_getBytes(aPool, &nScRandomIz, sizeof(nScRandomIz));
828 if (nScRandomIt <= 0)
829 rtl_random_getBytes(aPool, &nScRandomIt, sizeof(nScRandomIt));
830
831 // Basically unmodified algorithm from
832 // Wichman and Hill, "Generating good pseudo-random numbers",
833 // December 5, 2005.
834
835 nScRandomIx = 11600L * (nScRandomIx % 185127L) - 10379L * (nScRandomIx / 185127L);
836 nScRandomIy = 47003L * (nScRandomIy % 45688L) - 10479L * (nScRandomIy / 45688L);
837 nScRandomIz = 23000L * (nScRandomIz % 93368L) - 19423L * (nScRandomIz / 93368L);
838 nScRandomIt = 33000L * (nScRandomIt % 65075L) - 8123L * (nScRandomIt / 65075L);
839 if (nScRandomIx < 0)
840 nScRandomIx += 2147483579L;
841 if (nScRandomIy < 0)
842 nScRandomIy += 2147483543L;
843 if (nScRandomIz < 0)
844 nScRandomIz += 2147483123L;
845 if (nScRandomIt < 0)
846 nScRandomIt += 2147483123L;
847
848 fScRandomW = (double)nScRandomIx*0.0000000004656613022670 +
849 (double)nScRandomIy*0.0000000004656613100760 +
850 (double)nScRandomIz*0.0000000004656613360968 +
851 (double)nScRandomIt*0.0000000004656614011490;
852
853
854 // fMax -> range
855 double fRet = fMax - fMin + 1.0;
856 fRet *= fScRandomW - (sal_Int32)fScRandomW ;
857 fRet += fMin;
858 fRet = floor( fRet ); // simple floor is sufficient here
859 RETURN_FINITE( fRet );
860 }
861
862
getGcd(constREFXPS & xOpt,const SEQSEQ (double)& aVLst,const SEQ (uno::Any)& aOptVLst)863 double SAL_CALL AnalysisAddIn::getGcd( constREFXPS& xOpt, const SEQSEQ( double )& aVLst, const SEQ( uno::Any )& aOptVLst ) THROWDEF_RTE_IAE
864 {
865 ScaDoubleListGT0 aValList;
866
867 aValList.Append( aVLst );
868 aValList.Append( aAnyConv, xOpt, aOptVLst );
869
870 if( aValList.Count() == 0 )
871 return 0.0;
872
873 const double* p = aValList.First();
874 double f = *p;
875
876 p = aValList.Next();
877
878 while( p )
879 {
880 f = GetGcd( *p, f );
881 p = aValList.Next();
882 }
883
884 RETURN_FINITE( f );
885 }
886
887
getLcm(constREFXPS & xOpt,const SEQSEQ (double)& aVLst,const SEQ (uno::Any)& aOptVLst)888 double SAL_CALL AnalysisAddIn::getLcm( constREFXPS& xOpt, const SEQSEQ( double )& aVLst, const SEQ( uno::Any )& aOptVLst ) THROWDEF_RTE_IAE
889 {
890 ScaDoubleListGE0 aValList;
891
892 aValList.Append( aVLst );
893 aValList.Append( aAnyConv, xOpt, aOptVLst );
894
895 if( aValList.Count() == 0 )
896 return 0.0;
897
898 const double* p = aValList.First();
899 double f = *p;
900
901 if( f == 0.0 )
902 return f;
903
904 p = aValList.Next();
905
906 while( p )
907 {
908 double fTmp = *p;
909 if( f == 0.0 )
910 return f;
911 else
912 f = fTmp * f / GetGcd( fTmp, f );
913 p = aValList.Next();
914 }
915
916 RETURN_FINITE( f );
917 }
918
919
getBesseli(double fNum,sal_Int32 nOrder)920 double SAL_CALL AnalysisAddIn::getBesseli( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
921 {
922 double fRet = sca::analysis::BesselI( fNum, nOrder );
923 RETURN_FINITE( fRet );
924 }
925
926
getBesselj(double fNum,sal_Int32 nOrder)927 double SAL_CALL AnalysisAddIn::getBesselj( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
928 {
929 double fRet = sca::analysis::BesselJ( fNum, nOrder );
930 RETURN_FINITE( fRet );
931 }
932
933
getBesselk(double fNum,sal_Int32 nOrder)934 double SAL_CALL AnalysisAddIn::getBesselk( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
935 {
936 if( nOrder < 0 || fNum <= 0.0 )
937 THROW_IAE;
938
939 double fRet = sca::analysis::BesselK( fNum, nOrder );
940 RETURN_FINITE( fRet );
941 }
942
943
getBessely(double fNum,sal_Int32 nOrder)944 double SAL_CALL AnalysisAddIn::getBessely( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
945 {
946 if( nOrder < 0 || fNum <= 0.0 )
947 THROW_IAE;
948
949 // return yn( nOrder, fNum );
950 double fRet = sca::analysis::BesselY( fNum, nOrder );
951 RETURN_FINITE( fRet );
952 }
953
954
955 const double SCA_MAX2 = 511.0; // min. val for binary numbers (9 bits + sign)
956 const double SCA_MIN2 = -SCA_MAX2-1.0; // min. val for binary numbers (9 bits + sign)
957 const double SCA_MAX8 = 536870911.0; // max. val for octal numbers (29 bits + sign)
958 const double SCA_MIN8 = -SCA_MAX8-1.0; // min. val for octal numbers (29 bits + sign)
959 const double SCA_MAX16 = 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
960 const double SCA_MIN16 = -SCA_MAX16-1.0; // min. val for hexadecimal numbers (39 bits + sign)
961 const sal_Int32 SCA_MAXPLACES = 10; // max. number of places
962
963
getBin2Oct(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)964 STRING SAL_CALL AnalysisAddIn::getBin2Oct( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
965 {
966 double fVal = ConvertToDec( aNum, 2, SCA_MAXPLACES );
967 sal_Int32 nPlaces = 0;
968 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
969 return ConvertFromDec( fVal, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
970 }
971
972
getBin2Dec(const STRING & aNum)973 double SAL_CALL AnalysisAddIn::getBin2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
974 {
975 double fRet = ConvertToDec( aNum, 2, SCA_MAXPLACES );
976 RETURN_FINITE( fRet );
977 }
978
979
getBin2Hex(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)980 STRING SAL_CALL AnalysisAddIn::getBin2Hex( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
981 {
982 double fVal = ConvertToDec( aNum, 2, SCA_MAXPLACES );
983 sal_Int32 nPlaces = 0;
984 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
985 return ConvertFromDec( fVal, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
986 }
987
988
getOct2Bin(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)989 STRING SAL_CALL AnalysisAddIn::getOct2Bin( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
990 {
991 double fVal = ConvertToDec( aNum, 8, SCA_MAXPLACES );
992 sal_Int32 nPlaces = 0;
993 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
994 return ConvertFromDec( fVal, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
995 }
996
997
getOct2Dec(const STRING & aNum)998 double SAL_CALL AnalysisAddIn::getOct2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
999 {
1000 double fRet = ConvertToDec( aNum, 8, SCA_MAXPLACES );
1001 RETURN_FINITE( fRet );
1002 }
1003
1004
getOct2Hex(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)1005 STRING SAL_CALL AnalysisAddIn::getOct2Hex( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1006 {
1007 double fVal = ConvertToDec( aNum, 8, SCA_MAXPLACES );
1008 sal_Int32 nPlaces = 0;
1009 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1010 return ConvertFromDec( fVal, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
1011 }
1012
1013
getDec2Bin(constREFXPS & xOpt,sal_Int32 nNum,const ANY & rPlaces)1014 STRING SAL_CALL AnalysisAddIn::getDec2Bin( constREFXPS& xOpt, sal_Int32 nNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1015 {
1016 sal_Int32 nPlaces = 0;
1017 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1018 return ConvertFromDec( nNum, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
1019 }
1020
1021
getDec2Oct(constREFXPS & xOpt,sal_Int32 nNum,const ANY & rPlaces)1022 STRING SAL_CALL AnalysisAddIn::getDec2Oct( constREFXPS& xOpt, sal_Int32 nNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1023 {
1024 sal_Int32 nPlaces = 0;
1025 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1026 return ConvertFromDec( nNum, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
1027 }
1028
1029
getDec2Hex(constREFXPS & xOpt,double fNum,const ANY & rPlaces)1030 STRING SAL_CALL AnalysisAddIn::getDec2Hex( constREFXPS& xOpt, double fNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1031 {
1032 sal_Int32 nPlaces = 0;
1033 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1034 return ConvertFromDec( fNum, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
1035 }
1036
1037
getHex2Bin(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)1038 STRING SAL_CALL AnalysisAddIn::getHex2Bin( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1039 {
1040 double fVal = ConvertToDec( aNum, 16, SCA_MAXPLACES );
1041 sal_Int32 nPlaces = 0;
1042 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1043 return ConvertFromDec( fVal, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
1044 }
1045
1046
getHex2Dec(const STRING & aNum)1047 double SAL_CALL AnalysisAddIn::getHex2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
1048 {
1049 double fRet = ConvertToDec( aNum, 16, SCA_MAXPLACES );
1050 RETURN_FINITE( fRet );
1051 }
1052
1053
getHex2Oct(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)1054 STRING SAL_CALL AnalysisAddIn::getHex2Oct( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1055 {
1056 double fVal = ConvertToDec( aNum, 16, SCA_MAXPLACES );
1057 sal_Int32 nPlaces = 0;
1058 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1059 return ConvertFromDec( fVal, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
1060 }
1061
1062
getDelta(constREFXPS & xOpt,double fNum1,const ANY & rNum2)1063 sal_Int32 SAL_CALL AnalysisAddIn::getDelta( constREFXPS& xOpt, double fNum1, const ANY& rNum2 ) THROWDEF_RTE_IAE
1064 {
1065 return fNum1 == aAnyConv.getDouble( xOpt, rNum2, 0.0 );
1066 }
1067
1068
getErf(constREFXPS & xOpt,double fLL,const ANY & rUL)1069 double SAL_CALL AnalysisAddIn::getErf( constREFXPS& xOpt, double fLL, const ANY& rUL ) THROWDEF_RTE_IAE
1070 {
1071 double fUL, fRet;
1072 sal_Bool bContainsValue = aAnyConv.getDouble( fUL, xOpt, rUL );
1073
1074 fRet = bContainsValue ? (Erf( fUL ) - Erf( fLL )) : Erf( fLL );
1075 RETURN_FINITE( fRet );
1076 }
1077
1078
getErfc(double f)1079 double SAL_CALL AnalysisAddIn::getErfc( double f ) THROWDEF_RTE_IAE
1080 {
1081 double fRet = Erfc( f );
1082 RETURN_FINITE( fRet );
1083 }
1084
1085
getGestep(constREFXPS & xOpt,double fNum,const ANY & rStep)1086 sal_Int32 SAL_CALL AnalysisAddIn::getGestep( constREFXPS& xOpt, double fNum, const ANY& rStep ) THROWDEF_RTE_IAE
1087 {
1088 return fNum >= aAnyConv.getDouble( xOpt, rStep, 0.0 );
1089 }
1090
1091
getFactdouble(sal_Int32 nNum)1092 double SAL_CALL AnalysisAddIn::getFactdouble( sal_Int32 nNum ) THROWDEF_RTE_IAE
1093 {
1094 double fRet = FactDouble( nNum );
1095 RETURN_FINITE( fRet );
1096 }
1097
1098
getImabs(const STRING & aNum)1099 double SAL_CALL AnalysisAddIn::getImabs( const STRING& aNum ) THROWDEF_RTE_IAE
1100 {
1101 double fRet = Complex( aNum ).Abs();
1102 RETURN_FINITE( fRet );
1103 }
1104
1105
getImaginary(const STRING & aNum)1106 double SAL_CALL AnalysisAddIn::getImaginary( const STRING& aNum ) THROWDEF_RTE_IAE
1107 {
1108 double fRet = Complex( aNum ).Imag();
1109 RETURN_FINITE( fRet );
1110 }
1111
1112
getImpower(const STRING & aNum,double f)1113 STRING SAL_CALL AnalysisAddIn::getImpower( const STRING& aNum, double f ) THROWDEF_RTE_IAE
1114 {
1115 Complex z( aNum );
1116
1117 z.Power( f );
1118
1119 return z.GetString();
1120 }
1121
1122
getImargument(const STRING & aNum)1123 double SAL_CALL AnalysisAddIn::getImargument( const STRING& aNum ) THROWDEF_RTE_IAE
1124 {
1125 double fRet = Complex( aNum ).Arg();
1126 RETURN_FINITE( fRet );
1127 }
1128
1129
getImcos(const STRING & aNum)1130 STRING SAL_CALL AnalysisAddIn::getImcos( const STRING& aNum ) THROWDEF_RTE_IAE
1131 {
1132 Complex z( aNum );
1133
1134 z.Cos();
1135
1136 return z.GetString();
1137 }
1138
1139
getImdiv(const STRING & aDivid,const STRING & aDivis)1140 STRING SAL_CALL AnalysisAddIn::getImdiv( const STRING& aDivid, const STRING& aDivis ) THROWDEF_RTE_IAE
1141 {
1142 Complex z( aDivid );
1143
1144 z.Div( Complex( aDivis ) );
1145
1146 return z.GetString();
1147 }
1148
1149
getImexp(const STRING & aNum)1150 STRING SAL_CALL AnalysisAddIn::getImexp( const STRING& aNum ) THROWDEF_RTE_IAE
1151 {
1152 Complex z( aNum );
1153
1154 z.Exp();
1155
1156 return z.GetString();
1157 }
1158
1159
getImconjugate(const STRING & aNum)1160 STRING SAL_CALL AnalysisAddIn::getImconjugate( const STRING& aNum ) THROWDEF_RTE_IAE
1161 {
1162 Complex z( aNum );
1163
1164 z.Conjugate();
1165
1166 return z.GetString();
1167 }
1168
1169
getImln(const STRING & aNum)1170 STRING SAL_CALL AnalysisAddIn::getImln( const STRING& aNum ) THROWDEF_RTE_IAE
1171 {
1172 Complex z( aNum );
1173
1174 z.Ln();
1175
1176 return z.GetString();
1177 }
1178
1179
getImlog10(const STRING & aNum)1180 STRING SAL_CALL AnalysisAddIn::getImlog10( const STRING& aNum ) THROWDEF_RTE_IAE
1181 {
1182 Complex z( aNum );
1183
1184 z.Log10();
1185
1186 return z.GetString();
1187 }
1188
1189
getImlog2(const STRING & aNum)1190 STRING SAL_CALL AnalysisAddIn::getImlog2( const STRING& aNum ) THROWDEF_RTE_IAE
1191 {
1192 Complex z( aNum );
1193
1194 z.Log2();
1195
1196 return z.GetString();
1197 }
1198
1199
getImproduct(constREFXPS &,const SEQSEQ (STRING)& aNum1,const SEQ (uno::Any)& aNL)1200 STRING SAL_CALL AnalysisAddIn::getImproduct( constREFXPS&, const SEQSEQ( STRING )& aNum1, const SEQ( uno::Any )& aNL ) THROWDEF_RTE_IAE
1201 {
1202 ComplexList z_list;
1203
1204 z_list.Append( aNum1, AH_IgnoreEmpty );
1205 z_list.Append( aNL, AH_IgnoreEmpty );
1206
1207 const Complex* p = z_list.First();
1208
1209 if( !p )
1210 return Complex( 0 ).GetString();
1211
1212 Complex z( *p );
1213
1214 for( p = z_list.Next() ; p ; p = z_list.Next() )
1215 z.Mult( *p );
1216
1217 return z.GetString();
1218 }
1219
1220
getImreal(const STRING & aNum)1221 double SAL_CALL AnalysisAddIn::getImreal( const STRING& aNum ) THROWDEF_RTE_IAE
1222 {
1223 double fRet = Complex( aNum ).Real();
1224 RETURN_FINITE( fRet );
1225 }
1226
1227
getImsin(const STRING & aNum)1228 STRING SAL_CALL AnalysisAddIn::getImsin( const STRING& aNum ) THROWDEF_RTE_IAE
1229 {
1230 Complex z( aNum );
1231
1232 z.Sin();
1233
1234 return z.GetString();
1235 }
1236
1237
getImsub(const STRING & aNum1,const STRING & aNum2)1238 STRING SAL_CALL AnalysisAddIn::getImsub( const STRING& aNum1, const STRING& aNum2 ) THROWDEF_RTE_IAE
1239 {
1240 Complex z( aNum1 );
1241
1242 z.Sub( Complex( aNum2 ) );
1243
1244 return z.GetString();
1245 }
1246
1247
getImsum(constREFXPS &,const SEQSEQ (STRING)& aNum1,const SEQ (CSS::uno::Any)& aFollowingPars)1248 STRING SAL_CALL AnalysisAddIn::getImsum( constREFXPS&, const SEQSEQ( STRING )& aNum1, const SEQ( CSS::uno::Any )& aFollowingPars ) THROWDEF_RTE_IAE
1249 {
1250 ComplexList z_list;
1251
1252 z_list.Append( aNum1, AH_IgnoreEmpty );
1253 z_list.Append( aFollowingPars, AH_IgnoreEmpty );
1254
1255 const Complex* p = z_list.First();
1256
1257 if( !p )
1258 return Complex( 0 ).GetString();
1259
1260 Complex z( *p );
1261
1262 for( p = z_list.Next() ; p ; p = z_list.Next() )
1263 z.Add( *p );
1264
1265 return z.GetString();
1266 }
1267
1268
getImsqrt(const STRING & aNum)1269 STRING SAL_CALL AnalysisAddIn::getImsqrt( const STRING& aNum ) THROWDEF_RTE_IAE
1270 {
1271 Complex z( aNum );
1272
1273 // z.Power( 0.5 );
1274 z.Sqrt();
1275
1276 return z.GetString();
1277 }
1278
1279
getImtan(const STRING & aNum)1280 STRING SAL_CALL AnalysisAddIn::getImtan( const STRING& aNum ) THROWDEF_RTE_IAE
1281 {
1282 Complex z( aNum );
1283
1284 z.Tan();
1285
1286 return z.GetString();
1287 }
1288
1289
getImsec(const STRING & aNum)1290 STRING SAL_CALL AnalysisAddIn::getImsec( const STRING& aNum ) THROWDEF_RTE_IAE
1291 {
1292 Complex z( aNum );
1293
1294 z.Sec();
1295
1296 return z.GetString();
1297 }
1298
1299
getImcsc(const STRING & aNum)1300 STRING SAL_CALL AnalysisAddIn::getImcsc( const STRING& aNum ) THROWDEF_RTE_IAE
1301 {
1302 Complex z( aNum );
1303
1304 z.Csc();
1305
1306 return z.GetString();
1307 }
1308
1309
getImcot(const STRING & aNum)1310 STRING SAL_CALL AnalysisAddIn::getImcot( const STRING& aNum ) THROWDEF_RTE_IAE
1311 {
1312 Complex z( aNum );
1313
1314 z.Cot();
1315
1316 return z.GetString();
1317 }
1318
1319
getImsinh(const STRING & aNum)1320 STRING SAL_CALL AnalysisAddIn::getImsinh( const STRING& aNum ) THROWDEF_RTE_IAE
1321 {
1322 Complex z( aNum );
1323
1324 z.Sinh();
1325
1326 return z.GetString();
1327 }
1328
1329
getImcosh(const STRING & aNum)1330 STRING SAL_CALL AnalysisAddIn::getImcosh( const STRING& aNum ) THROWDEF_RTE_IAE
1331 {
1332 Complex z( aNum );
1333
1334 z.Cosh();
1335
1336 return z.GetString();
1337 }
1338
1339
getImsech(const STRING & aNum)1340 STRING SAL_CALL AnalysisAddIn::getImsech( const STRING& aNum ) THROWDEF_RTE_IAE
1341 {
1342 Complex z( aNum );
1343
1344 z.Sech();
1345
1346 return z.GetString();
1347 }
1348
1349
getImcsch(const STRING & aNum)1350 STRING SAL_CALL AnalysisAddIn::getImcsch( const STRING& aNum ) THROWDEF_RTE_IAE
1351 {
1352 Complex z( aNum );
1353
1354 z.Csch();
1355
1356 return z.GetString();
1357 }
1358
1359
getComplex(double fR,double fI,const ANY & rSuff)1360 STRING SAL_CALL AnalysisAddIn::getComplex( double fR, double fI, const ANY& rSuff ) THROWDEF_RTE_IAE
1361 {
1362 sal_Bool bi;
1363
1364 switch( rSuff.getValueTypeClass() )
1365 {
1366 case uno::TypeClass_VOID:
1367 bi = sal_True;
1368 break;
1369 case uno::TypeClass_STRING:
1370 {
1371 const STRING* pSuff = ( const STRING* ) rSuff.getValue();
1372 bi = pSuff->compareToAscii( "i" ) == 0 || pSuff->getLength() == 0;
1373 if( !bi && pSuff->compareToAscii( "j" ) != 0 )
1374 THROW_IAE;
1375 }
1376 break;
1377 default:
1378 THROW_IAE;
1379 }
1380
1381 return Complex( fR, fI, bi ? 'i' : 'j' ).GetString();
1382 }
1383
1384
getConvert(double f,const STRING & aFU,const STRING & aTU)1385 double SAL_CALL AnalysisAddIn::getConvert( double f, const STRING& aFU, const STRING& aTU ) THROWDEF_RTE_IAE
1386 {
1387 if( !pCDL )
1388 pCDL = new ConvertDataList();
1389
1390 double fRet = pCDL->Convert( f, aFU, aTU );
1391 RETURN_FINITE( fRet );
1392 }
1393
1394
1395