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