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