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 SAL_DLLPUBLIC_EXPORT 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 SAL_DLLPUBLIC_EXPORT 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 #define SCRANDOMQ_SIZE 4
809
getRandbetween(double fMin,double fMax)810 double SAL_CALL AnalysisAddIn::getRandbetween( double fMin, double fMax ) THROWDEF_RTE_IAE
811 {
812 static sal_uInt32 nScRandomSeed[SCRANDOMQ_SIZE];
813 static sal_Bool SqSeeded = sal_False;
814 static rtlRandomPool aPool = rtl_random_createPool();
815 sal_uInt64 nScRandomt, nScRandoma = 698769069LL;
816 double fScRandomW;
817
818 fMin = ::rtl::math::round( fMin, 0, rtl_math_RoundingMode_Up );
819 fMax = ::rtl::math::round( fMax, 0, rtl_math_RoundingMode_Up );
820 if( fMin > fMax )
821 THROW_IAE;
822
823 // Seeding for the PRNG: should be pretty good.
824 if (SqSeeded == sal_False) {
825 rtl_random_getBytes(aPool, &nScRandomSeed, SCRANDOMQ_SIZE * sizeof(nScRandomSeed[0]));
826 SqSeeded = sal_True;
827 }
828
829 // Use George Marsaglia's 1998 KISS PRNG algorithm.
830 nScRandomSeed[0] = 69069 * nScRandomSeed[0] + 12345;
831 nScRandomSeed[1] ^= (nScRandomSeed[1] << 13);
832 nScRandomSeed[1] ^= (nScRandomSeed[1] >> 17);
833 nScRandomSeed[1] ^= (nScRandomSeed[1] << 5);
834 nScRandomt = nScRandoma * nScRandomSeed[2] + nScRandomSeed[3];
835 nScRandomSeed[1] = (nScRandomt >> 32);
836
837 fScRandomW = (nScRandomSeed[0] + nScRandomSeed[1] + (nScRandomSeed[3] = nScRandomt));
838
839 // fMax -> range
840 double fRet = fMax - fMin + 1.0;
841 fRet *= fScRandomW / SAL_MAX_UINT32 ;
842 fRet += fMin;
843 fRet = floor( fRet ); // simple floor is sufficient here
844 RETURN_FINITE( fRet );
845 }
846
847
getGcd(constREFXPS & xOpt,const SEQSEQ (double)& aVLst,const SEQ (uno::Any)& aOptVLst)848 double SAL_CALL AnalysisAddIn::getGcd( constREFXPS& xOpt, const SEQSEQ( double )& aVLst, const SEQ( uno::Any )& aOptVLst ) THROWDEF_RTE_IAE
849 {
850 ScaDoubleListGT0 aValList;
851
852 aValList.Append( aVLst );
853 aValList.Append( aAnyConv, xOpt, aOptVLst );
854
855 if( aValList.Count() == 0 )
856 return 0.0;
857
858 const double* p = aValList.First();
859 double f = *p;
860
861 p = aValList.Next();
862
863 while( p )
864 {
865 f = GetGcd( *p, f );
866 p = aValList.Next();
867 }
868
869 RETURN_FINITE( f );
870 }
871
872
getLcm(constREFXPS & xOpt,const SEQSEQ (double)& aVLst,const SEQ (uno::Any)& aOptVLst)873 double SAL_CALL AnalysisAddIn::getLcm( constREFXPS& xOpt, const SEQSEQ( double )& aVLst, const SEQ( uno::Any )& aOptVLst ) THROWDEF_RTE_IAE
874 {
875 ScaDoubleListGE0 aValList;
876
877 aValList.Append( aVLst );
878 aValList.Append( aAnyConv, xOpt, aOptVLst );
879
880 if( aValList.Count() == 0 )
881 return 0.0;
882
883 const double* p = aValList.First();
884 double f = *p;
885
886 if( f == 0.0 )
887 return f;
888
889 p = aValList.Next();
890
891 while( p )
892 {
893 double fTmp = *p;
894 if( f == 0.0 )
895 return f;
896 else
897 f = fTmp * f / GetGcd( fTmp, f );
898 p = aValList.Next();
899 }
900
901 RETURN_FINITE( f );
902 }
903
904
getBesseli(double fNum,sal_Int32 nOrder)905 double SAL_CALL AnalysisAddIn::getBesseli( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
906 {
907 double fRet = sca::analysis::BesselI( fNum, nOrder );
908 RETURN_FINITE( fRet );
909 }
910
911
getBesselj(double fNum,sal_Int32 nOrder)912 double SAL_CALL AnalysisAddIn::getBesselj( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
913 {
914 double fRet = sca::analysis::BesselJ( fNum, nOrder );
915 RETURN_FINITE( fRet );
916 }
917
918
getBesselk(double fNum,sal_Int32 nOrder)919 double SAL_CALL AnalysisAddIn::getBesselk( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
920 {
921 if( nOrder < 0 || fNum <= 0.0 )
922 THROW_IAE;
923
924 double fRet = sca::analysis::BesselK( fNum, nOrder );
925 RETURN_FINITE( fRet );
926 }
927
928
getBessely(double fNum,sal_Int32 nOrder)929 double SAL_CALL AnalysisAddIn::getBessely( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE
930 {
931 if( nOrder < 0 || fNum <= 0.0 )
932 THROW_IAE;
933
934 // return yn( nOrder, fNum );
935 double fRet = sca::analysis::BesselY( fNum, nOrder );
936 RETURN_FINITE( fRet );
937 }
938
939
940 const double SCA_MAX2 = 511.0; // min. val for binary numbers (9 bits + sign)
941 const double SCA_MIN2 = -SCA_MAX2-1.0; // min. val for binary numbers (9 bits + sign)
942 const double SCA_MAX8 = 536870911.0; // max. val for octal numbers (29 bits + sign)
943 const double SCA_MIN8 = -SCA_MAX8-1.0; // min. val for octal numbers (29 bits + sign)
944 const double SCA_MAX16 = 549755813888.0; // max. val for hexadecimal numbers (39 bits + sign)
945 const double SCA_MIN16 = -SCA_MAX16-1.0; // min. val for hexadecimal numbers (39 bits + sign)
946 const sal_Int32 SCA_MAXPLACES = 10; // max. number of places
947
948
getBin2Oct(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)949 STRING SAL_CALL AnalysisAddIn::getBin2Oct( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
950 {
951 double fVal = ConvertToDec( aNum, 2, SCA_MAXPLACES );
952 sal_Int32 nPlaces = 0;
953 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
954 return ConvertFromDec( fVal, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
955 }
956
957
getBin2Dec(const STRING & aNum)958 double SAL_CALL AnalysisAddIn::getBin2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
959 {
960 double fRet = ConvertToDec( aNum, 2, SCA_MAXPLACES );
961 RETURN_FINITE( fRet );
962 }
963
964
getBin2Hex(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)965 STRING SAL_CALL AnalysisAddIn::getBin2Hex( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
966 {
967 double fVal = ConvertToDec( aNum, 2, SCA_MAXPLACES );
968 sal_Int32 nPlaces = 0;
969 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
970 return ConvertFromDec( fVal, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
971 }
972
973
getOct2Bin(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)974 STRING SAL_CALL AnalysisAddIn::getOct2Bin( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
975 {
976 double fVal = ConvertToDec( aNum, 8, SCA_MAXPLACES );
977 sal_Int32 nPlaces = 0;
978 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
979 return ConvertFromDec( fVal, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
980 }
981
982
getOct2Dec(const STRING & aNum)983 double SAL_CALL AnalysisAddIn::getOct2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
984 {
985 double fRet = ConvertToDec( aNum, 8, SCA_MAXPLACES );
986 RETURN_FINITE( fRet );
987 }
988
989
getOct2Hex(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)990 STRING SAL_CALL AnalysisAddIn::getOct2Hex( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
991 {
992 double fVal = ConvertToDec( aNum, 8, SCA_MAXPLACES );
993 sal_Int32 nPlaces = 0;
994 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
995 return ConvertFromDec( fVal, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
996 }
997
998
getDec2Bin(constREFXPS & xOpt,sal_Int32 nNum,const ANY & rPlaces)999 STRING SAL_CALL AnalysisAddIn::getDec2Bin( constREFXPS& xOpt, sal_Int32 nNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1000 {
1001 sal_Int32 nPlaces = 0;
1002 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1003 return ConvertFromDec( nNum, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
1004 }
1005
1006
getDec2Oct(constREFXPS & xOpt,sal_Int32 nNum,const ANY & rPlaces)1007 STRING SAL_CALL AnalysisAddIn::getDec2Oct( constREFXPS& xOpt, sal_Int32 nNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1008 {
1009 sal_Int32 nPlaces = 0;
1010 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1011 return ConvertFromDec( nNum, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
1012 }
1013
1014
getDec2Hex(constREFXPS & xOpt,double fNum,const ANY & rPlaces)1015 STRING SAL_CALL AnalysisAddIn::getDec2Hex( constREFXPS& xOpt, double fNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1016 {
1017 sal_Int32 nPlaces = 0;
1018 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1019 return ConvertFromDec( fNum, SCA_MIN16, SCA_MAX16, 16, nPlaces, SCA_MAXPLACES, bUsePlaces );
1020 }
1021
1022
getHex2Bin(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)1023 STRING SAL_CALL AnalysisAddIn::getHex2Bin( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1024 {
1025 double fVal = ConvertToDec( aNum, 16, SCA_MAXPLACES );
1026 sal_Int32 nPlaces = 0;
1027 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1028 return ConvertFromDec( fVal, SCA_MIN2, SCA_MAX2, 2, nPlaces, SCA_MAXPLACES, bUsePlaces );
1029 }
1030
1031
getHex2Dec(const STRING & aNum)1032 double SAL_CALL AnalysisAddIn::getHex2Dec( const STRING& aNum ) THROWDEF_RTE_IAE
1033 {
1034 double fRet = ConvertToDec( aNum, 16, SCA_MAXPLACES );
1035 RETURN_FINITE( fRet );
1036 }
1037
1038
getHex2Oct(constREFXPS & xOpt,const STRING & aNum,const ANY & rPlaces)1039 STRING SAL_CALL AnalysisAddIn::getHex2Oct( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE
1040 {
1041 double fVal = ConvertToDec( aNum, 16, SCA_MAXPLACES );
1042 sal_Int32 nPlaces = 0;
1043 sal_Bool bUsePlaces = aAnyConv.getInt32( nPlaces, xOpt, rPlaces );
1044 return ConvertFromDec( fVal, SCA_MIN8, SCA_MAX8, 8, nPlaces, SCA_MAXPLACES, bUsePlaces );
1045 }
1046
1047
getDelta(constREFXPS & xOpt,double fNum1,const ANY & rNum2)1048 sal_Int32 SAL_CALL AnalysisAddIn::getDelta( constREFXPS& xOpt, double fNum1, const ANY& rNum2 ) THROWDEF_RTE_IAE
1049 {
1050 return fNum1 == aAnyConv.getDouble( xOpt, rNum2, 0.0 );
1051 }
1052
1053
getErf(constREFXPS & xOpt,double fLL,const ANY & rUL)1054 double SAL_CALL AnalysisAddIn::getErf( constREFXPS& xOpt, double fLL, const ANY& rUL ) THROWDEF_RTE_IAE
1055 {
1056 double fUL, fRet;
1057 sal_Bool bContainsValue = aAnyConv.getDouble( fUL, xOpt, rUL );
1058
1059 fRet = bContainsValue ? (Erf( fUL ) - Erf( fLL )) : Erf( fLL );
1060 RETURN_FINITE( fRet );
1061 }
1062
1063
getErfc(double f)1064 double SAL_CALL AnalysisAddIn::getErfc( double f ) THROWDEF_RTE_IAE
1065 {
1066 double fRet = Erfc( f );
1067 RETURN_FINITE( fRet );
1068 }
1069
1070
getGestep(constREFXPS & xOpt,double fNum,const ANY & rStep)1071 sal_Int32 SAL_CALL AnalysisAddIn::getGestep( constREFXPS& xOpt, double fNum, const ANY& rStep ) THROWDEF_RTE_IAE
1072 {
1073 return fNum >= aAnyConv.getDouble( xOpt, rStep, 0.0 );
1074 }
1075
1076
getFactdouble(sal_Int32 nNum)1077 double SAL_CALL AnalysisAddIn::getFactdouble( sal_Int32 nNum ) THROWDEF_RTE_IAE
1078 {
1079 double fRet = FactDouble( nNum );
1080 RETURN_FINITE( fRet );
1081 }
1082
1083
getImabs(const STRING & aNum)1084 double SAL_CALL AnalysisAddIn::getImabs( const STRING& aNum ) THROWDEF_RTE_IAE
1085 {
1086 double fRet = Complex( aNum ).Abs();
1087 RETURN_FINITE( fRet );
1088 }
1089
1090
getImaginary(const STRING & aNum)1091 double SAL_CALL AnalysisAddIn::getImaginary( const STRING& aNum ) THROWDEF_RTE_IAE
1092 {
1093 double fRet = Complex( aNum ).Imag();
1094 RETURN_FINITE( fRet );
1095 }
1096
1097
getImpower(const STRING & aNum,double f)1098 STRING SAL_CALL AnalysisAddIn::getImpower( const STRING& aNum, double f ) THROWDEF_RTE_IAE
1099 {
1100 Complex z( aNum );
1101
1102 z.Power( f );
1103
1104 return z.GetString();
1105 }
1106
1107
getImargument(const STRING & aNum)1108 double SAL_CALL AnalysisAddIn::getImargument( const STRING& aNum ) THROWDEF_RTE_IAE
1109 {
1110 double fRet = Complex( aNum ).Arg();
1111 RETURN_FINITE( fRet );
1112 }
1113
1114
getImcos(const STRING & aNum)1115 STRING SAL_CALL AnalysisAddIn::getImcos( const STRING& aNum ) THROWDEF_RTE_IAE
1116 {
1117 Complex z( aNum );
1118
1119 z.Cos();
1120
1121 return z.GetString();
1122 }
1123
1124
getImdiv(const STRING & aDivid,const STRING & aDivis)1125 STRING SAL_CALL AnalysisAddIn::getImdiv( const STRING& aDivid, const STRING& aDivis ) THROWDEF_RTE_IAE
1126 {
1127 Complex z( aDivid );
1128
1129 z.Div( Complex( aDivis ) );
1130
1131 return z.GetString();
1132 }
1133
1134
getImexp(const STRING & aNum)1135 STRING SAL_CALL AnalysisAddIn::getImexp( const STRING& aNum ) THROWDEF_RTE_IAE
1136 {
1137 Complex z( aNum );
1138
1139 z.Exp();
1140
1141 return z.GetString();
1142 }
1143
1144
getImconjugate(const STRING & aNum)1145 STRING SAL_CALL AnalysisAddIn::getImconjugate( const STRING& aNum ) THROWDEF_RTE_IAE
1146 {
1147 Complex z( aNum );
1148
1149 z.Conjugate();
1150
1151 return z.GetString();
1152 }
1153
1154
getImln(const STRING & aNum)1155 STRING SAL_CALL AnalysisAddIn::getImln( const STRING& aNum ) THROWDEF_RTE_IAE
1156 {
1157 Complex z( aNum );
1158
1159 z.Ln();
1160
1161 return z.GetString();
1162 }
1163
1164
getImlog10(const STRING & aNum)1165 STRING SAL_CALL AnalysisAddIn::getImlog10( const STRING& aNum ) THROWDEF_RTE_IAE
1166 {
1167 Complex z( aNum );
1168
1169 z.Log10();
1170
1171 return z.GetString();
1172 }
1173
1174
getImlog2(const STRING & aNum)1175 STRING SAL_CALL AnalysisAddIn::getImlog2( const STRING& aNum ) THROWDEF_RTE_IAE
1176 {
1177 Complex z( aNum );
1178
1179 z.Log2();
1180
1181 return z.GetString();
1182 }
1183
1184
getImproduct(constREFXPS &,const SEQSEQ (STRING)& aNum1,const SEQ (uno::Any)& aNL)1185 STRING SAL_CALL AnalysisAddIn::getImproduct( constREFXPS&, const SEQSEQ( STRING )& aNum1, const SEQ( uno::Any )& aNL ) THROWDEF_RTE_IAE
1186 {
1187 ComplexList z_list;
1188
1189 z_list.Append( aNum1, AH_IgnoreEmpty );
1190 z_list.Append( aNL, AH_IgnoreEmpty );
1191
1192 const Complex* p = z_list.First();
1193
1194 if( !p )
1195 return Complex( 0 ).GetString();
1196
1197 Complex z( *p );
1198
1199 for( p = z_list.Next() ; p ; p = z_list.Next() )
1200 z.Mult( *p );
1201
1202 return z.GetString();
1203 }
1204
1205
getImreal(const STRING & aNum)1206 double SAL_CALL AnalysisAddIn::getImreal( const STRING& aNum ) THROWDEF_RTE_IAE
1207 {
1208 double fRet = Complex( aNum ).Real();
1209 RETURN_FINITE( fRet );
1210 }
1211
1212
getImsin(const STRING & aNum)1213 STRING SAL_CALL AnalysisAddIn::getImsin( const STRING& aNum ) THROWDEF_RTE_IAE
1214 {
1215 Complex z( aNum );
1216
1217 z.Sin();
1218
1219 return z.GetString();
1220 }
1221
1222
getImsub(const STRING & aNum1,const STRING & aNum2)1223 STRING SAL_CALL AnalysisAddIn::getImsub( const STRING& aNum1, const STRING& aNum2 ) THROWDEF_RTE_IAE
1224 {
1225 Complex z( aNum1 );
1226
1227 z.Sub( Complex( aNum2 ) );
1228
1229 return z.GetString();
1230 }
1231
1232
getImsum(constREFXPS &,const SEQSEQ (STRING)& aNum1,const SEQ (CSS::uno::Any)& aFollowingPars)1233 STRING SAL_CALL AnalysisAddIn::getImsum( constREFXPS&, const SEQSEQ( STRING )& aNum1, const SEQ( CSS::uno::Any )& aFollowingPars ) THROWDEF_RTE_IAE
1234 {
1235 ComplexList z_list;
1236
1237 z_list.Append( aNum1, AH_IgnoreEmpty );
1238 z_list.Append( aFollowingPars, AH_IgnoreEmpty );
1239
1240 const Complex* p = z_list.First();
1241
1242 if( !p )
1243 return Complex( 0 ).GetString();
1244
1245 Complex z( *p );
1246
1247 for( p = z_list.Next() ; p ; p = z_list.Next() )
1248 z.Add( *p );
1249
1250 return z.GetString();
1251 }
1252
1253
getImsqrt(const STRING & aNum)1254 STRING SAL_CALL AnalysisAddIn::getImsqrt( const STRING& aNum ) THROWDEF_RTE_IAE
1255 {
1256 Complex z( aNum );
1257
1258 // z.Power( 0.5 );
1259 z.Sqrt();
1260
1261 return z.GetString();
1262 }
1263
1264
getImtan(const STRING & aNum)1265 STRING SAL_CALL AnalysisAddIn::getImtan( const STRING& aNum ) THROWDEF_RTE_IAE
1266 {
1267 Complex z( aNum );
1268
1269 z.Tan();
1270
1271 return z.GetString();
1272 }
1273
1274
getImsec(const STRING & aNum)1275 STRING SAL_CALL AnalysisAddIn::getImsec( const STRING& aNum ) THROWDEF_RTE_IAE
1276 {
1277 Complex z( aNum );
1278
1279 z.Sec();
1280
1281 return z.GetString();
1282 }
1283
1284
getImcsc(const STRING & aNum)1285 STRING SAL_CALL AnalysisAddIn::getImcsc( const STRING& aNum ) THROWDEF_RTE_IAE
1286 {
1287 Complex z( aNum );
1288
1289 z.Csc();
1290
1291 return z.GetString();
1292 }
1293
1294
getImcot(const STRING & aNum)1295 STRING SAL_CALL AnalysisAddIn::getImcot( const STRING& aNum ) THROWDEF_RTE_IAE
1296 {
1297 Complex z( aNum );
1298
1299 z.Cot();
1300
1301 return z.GetString();
1302 }
1303
1304
getImsinh(const STRING & aNum)1305 STRING SAL_CALL AnalysisAddIn::getImsinh( const STRING& aNum ) THROWDEF_RTE_IAE
1306 {
1307 Complex z( aNum );
1308
1309 z.Sinh();
1310
1311 return z.GetString();
1312 }
1313
1314
getImcosh(const STRING & aNum)1315 STRING SAL_CALL AnalysisAddIn::getImcosh( const STRING& aNum ) THROWDEF_RTE_IAE
1316 {
1317 Complex z( aNum );
1318
1319 z.Cosh();
1320
1321 return z.GetString();
1322 }
1323
1324
getImsech(const STRING & aNum)1325 STRING SAL_CALL AnalysisAddIn::getImsech( const STRING& aNum ) THROWDEF_RTE_IAE
1326 {
1327 Complex z( aNum );
1328
1329 z.Sech();
1330
1331 return z.GetString();
1332 }
1333
1334
getImcsch(const STRING & aNum)1335 STRING SAL_CALL AnalysisAddIn::getImcsch( const STRING& aNum ) THROWDEF_RTE_IAE
1336 {
1337 Complex z( aNum );
1338
1339 z.Csch();
1340
1341 return z.GetString();
1342 }
1343
1344
getComplex(double fR,double fI,const ANY & rSuff)1345 STRING SAL_CALL AnalysisAddIn::getComplex( double fR, double fI, const ANY& rSuff ) THROWDEF_RTE_IAE
1346 {
1347 sal_Bool bi;
1348
1349 switch( rSuff.getValueTypeClass() )
1350 {
1351 case uno::TypeClass_VOID:
1352 bi = sal_True;
1353 break;
1354 case uno::TypeClass_STRING:
1355 {
1356 const STRING* pSuff = ( const STRING* ) rSuff.getValue();
1357 bi = pSuff->compareToAscii( "i" ) == 0 || pSuff->getLength() == 0;
1358 if( !bi && pSuff->compareToAscii( "j" ) != 0 )
1359 THROW_IAE;
1360 }
1361 break;
1362 default:
1363 THROW_IAE;
1364 }
1365
1366 return Complex( fR, fI, bi ? 'i' : 'j' ).GetString();
1367 }
1368
1369
getConvert(double f,const STRING & aFU,const STRING & aTU)1370 double SAL_CALL AnalysisAddIn::getConvert( double f, const STRING& aFU, const STRING& aTU ) THROWDEF_RTE_IAE
1371 {
1372 if( !pCDL )
1373 pCDL = new ConvertDataList();
1374
1375 double fRet = pCDL->Convert( f, aFU, aTU );
1376 RETURN_FINITE( fRet );
1377 }
1378
1379
1380