1a06b8d1bSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3a06b8d1bSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4a06b8d1bSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5a06b8d1bSAndrew Rist  * distributed with this work for additional information
6a06b8d1bSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7a06b8d1bSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8a06b8d1bSAndrew Rist  * "License"); you may not use this file except in compliance
9a06b8d1bSAndrew Rist  * with the License.  You may obtain a copy of the License at
10a06b8d1bSAndrew Rist  *
11a06b8d1bSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12a06b8d1bSAndrew Rist  *
13a06b8d1bSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14a06b8d1bSAndrew Rist  * software distributed under the License is distributed on an
15a06b8d1bSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16a06b8d1bSAndrew Rist  * KIND, either express or implied.  See the License for the
17a06b8d1bSAndrew Rist  * specific language governing permissions and limitations
18a06b8d1bSAndrew Rist  * under the License.
19a06b8d1bSAndrew Rist  *
20a06b8d1bSAndrew Rist  *************************************************************/
21a06b8d1bSAndrew Rist 
22a06b8d1bSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatTypes.hpp>
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <string.h>
27cdf0e10cSrcweir #include <stdio.h>
28cdf0e10cSrcweir #include <tools/resary.hxx>
29cdf0e10cSrcweir #include <rtl/math.hxx>
30cdf0e10cSrcweir #include "analysishelper.hxx"
31cdf0e10cSrcweir #include "analysis.hrc"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir using namespace                 ::rtl;
34cdf0e10cSrcweir using namespace                 ::com::sun::star;
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #define UNIQUE              sal_False   // function name does not exist in Calc
37cdf0e10cSrcweir #define DOUBLE              sal_True    // function name exists in Calc
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #define STDPAR              sal_False   // all parameters are described
40cdf0e10cSrcweir #define INTPAR              sal_True    // first parameter is internal
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #define FUNCDATA( FUNCNAME, DBL, OPT, NUMOFPAR, CAT ) \
43cdf0e10cSrcweir     { "get" #FUNCNAME, ANALYSIS_FUNCNAME_##FUNCNAME, ANALYSIS_##FUNCNAME, DBL, OPT, ANALYSIS_DEFFUNCNAME_##FUNCNAME, NUMOFPAR, CAT }
44cdf0e10cSrcweir 
45cdf0e10cSrcweir const FuncDataBase pFuncDatas[] =
46cdf0e10cSrcweir {
47cdf0e10cSrcweir     //                          UNIQUE or   INTPAR or
48cdf0e10cSrcweir     //         function name     DOUBLE      STDPAR     # of param  category
49cdf0e10cSrcweir     FUNCDATA( Workday,          UNIQUE,     INTPAR,     3,          FDCat_DateTime ),
50cdf0e10cSrcweir     FUNCDATA( Yearfrac,         UNIQUE,     INTPAR,     3,          FDCat_DateTime ),
51cdf0e10cSrcweir     FUNCDATA( Edate,            UNIQUE,     INTPAR,     2,          FDCat_DateTime ),
52cdf0e10cSrcweir     FUNCDATA( Weeknum,          DOUBLE,     INTPAR,     2,          FDCat_DateTime ),
53cdf0e10cSrcweir     FUNCDATA( Eomonth,          UNIQUE,     INTPAR,     2,          FDCat_DateTime ),
54cdf0e10cSrcweir     FUNCDATA( Networkdays,      UNIQUE,     INTPAR,     3,          FDCat_DateTime ),
55cdf0e10cSrcweir     FUNCDATA( Iseven,           DOUBLE,     STDPAR,     1,          FDCat_Inf ),
56cdf0e10cSrcweir     FUNCDATA( Isodd,            DOUBLE,     STDPAR,     1,          FDCat_Inf ),
57cdf0e10cSrcweir     FUNCDATA( Multinomial,      UNIQUE,     STDPAR,     1,          FDCat_Math ),
58cdf0e10cSrcweir     FUNCDATA( Seriessum,        UNIQUE,     STDPAR,     4,          FDCat_Math ),
59cdf0e10cSrcweir     FUNCDATA( Quotient,         UNIQUE,     STDPAR,     2,          FDCat_Math ),
60cdf0e10cSrcweir     FUNCDATA( Mround,           UNIQUE,     STDPAR,     2,          FDCat_Math ),
61cdf0e10cSrcweir     FUNCDATA( Sqrtpi,           UNIQUE,     STDPAR,     1,          FDCat_Math ),
62cdf0e10cSrcweir     FUNCDATA( Randbetween,      UNIQUE,     STDPAR,     2,          FDCat_Math ),
63cdf0e10cSrcweir     FUNCDATA( Gcd,              DOUBLE,     INTPAR,     1,          FDCat_Math ),
64cdf0e10cSrcweir     FUNCDATA( Lcm,              DOUBLE,     INTPAR,     1,          FDCat_Math ),
65cdf0e10cSrcweir     FUNCDATA( Besseli,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
66cdf0e10cSrcweir     FUNCDATA( Besselj,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
67cdf0e10cSrcweir     FUNCDATA( Besselk,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
68cdf0e10cSrcweir     FUNCDATA( Bessely,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
69cdf0e10cSrcweir     FUNCDATA( Bin2Oct,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
70cdf0e10cSrcweir     FUNCDATA( Bin2Dec,          UNIQUE,     STDPAR,     1,          FDCat_Tech ),
71cdf0e10cSrcweir     FUNCDATA( Bin2Hex,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
72cdf0e10cSrcweir     FUNCDATA( Oct2Bin,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
73cdf0e10cSrcweir     FUNCDATA( Oct2Dec,          UNIQUE,     STDPAR,     1,          FDCat_Tech ),
74cdf0e10cSrcweir     FUNCDATA( Oct2Hex,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
75cdf0e10cSrcweir     FUNCDATA( Dec2Bin,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
76cdf0e10cSrcweir     FUNCDATA( Dec2Hex,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
77cdf0e10cSrcweir     FUNCDATA( Dec2Oct,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
78cdf0e10cSrcweir     FUNCDATA( Hex2Bin,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
79cdf0e10cSrcweir     FUNCDATA( Hex2Dec,          UNIQUE,     STDPAR,     1,          FDCat_Tech ),
80cdf0e10cSrcweir     FUNCDATA( Hex2Oct,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
81cdf0e10cSrcweir     FUNCDATA( Delta,            UNIQUE,     INTPAR,     2,          FDCat_Tech ),
82cdf0e10cSrcweir     FUNCDATA( Erf,              UNIQUE,     INTPAR,     2,          FDCat_Tech ),
83cdf0e10cSrcweir     FUNCDATA( Erfc,             UNIQUE,     STDPAR,     1,          FDCat_Tech ),
84cdf0e10cSrcweir     FUNCDATA( Gestep,           UNIQUE,     INTPAR,     2,          FDCat_Tech ),
85cdf0e10cSrcweir     FUNCDATA( Factdouble,       UNIQUE,     STDPAR,     1,          FDCat_Tech ),
86cdf0e10cSrcweir     FUNCDATA( Imabs,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
87cdf0e10cSrcweir     FUNCDATA( Imaginary,        UNIQUE,     STDPAR,     1,          FDCat_Tech ),
88cdf0e10cSrcweir     FUNCDATA( Impower,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
89cdf0e10cSrcweir     FUNCDATA( Imargument,       UNIQUE,     STDPAR,     1,          FDCat_Tech ),
90cdf0e10cSrcweir     FUNCDATA( Imcos,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
91cdf0e10cSrcweir     FUNCDATA( Imdiv,            UNIQUE,     STDPAR,     2,          FDCat_Tech ),
92cdf0e10cSrcweir     FUNCDATA( Imexp,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
93cdf0e10cSrcweir     FUNCDATA( Imconjugate,      UNIQUE,     STDPAR,     1,          FDCat_Tech ),
94cdf0e10cSrcweir     FUNCDATA( Imln,             UNIQUE,     STDPAR,     1,          FDCat_Tech ),
95cdf0e10cSrcweir     FUNCDATA( Imlog10,          UNIQUE,     STDPAR,     1,          FDCat_Tech ),
96cdf0e10cSrcweir     FUNCDATA( Imlog2,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
97cdf0e10cSrcweir     FUNCDATA( Improduct,        UNIQUE,     INTPAR,     2,          FDCat_Tech ),
98cdf0e10cSrcweir     FUNCDATA( Imreal,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
99cdf0e10cSrcweir     FUNCDATA( Imsin,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
100cdf0e10cSrcweir     FUNCDATA( Imsub,            UNIQUE,     STDPAR,     2,          FDCat_Tech ),
101cdf0e10cSrcweir     FUNCDATA( Imsqrt,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
102cdf0e10cSrcweir     FUNCDATA( Imsum,            UNIQUE,     INTPAR,     1,          FDCat_Tech ),
103feb8f109SRegina Henschel     FUNCDATA( Imtan,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
104feb8f109SRegina Henschel     FUNCDATA( Imsec,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
105feb8f109SRegina Henschel     FUNCDATA( Imcsc,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
106feb8f109SRegina Henschel     FUNCDATA( Imcot,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
107feb8f109SRegina Henschel     FUNCDATA( Imsinh,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
108feb8f109SRegina Henschel     FUNCDATA( Imcosh,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
109feb8f109SRegina Henschel     FUNCDATA( Imsech,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
110feb8f109SRegina Henschel     FUNCDATA( Imcsch,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
111cdf0e10cSrcweir     FUNCDATA( Complex,          UNIQUE,     STDPAR,     3,          FDCat_Tech ),
112cdf0e10cSrcweir     FUNCDATA( Convert,          DOUBLE,     STDPAR,     3,          FDCat_Tech ),
113cdf0e10cSrcweir     FUNCDATA( Amordegrc,        UNIQUE,     INTPAR,     7,          FDCat_Finance ),
114cdf0e10cSrcweir     FUNCDATA( Amorlinc,         UNIQUE,     INTPAR,     7,          FDCat_Finance ),
115cdf0e10cSrcweir     FUNCDATA( Accrint,          UNIQUE,     INTPAR,     7,          FDCat_Finance ),
116cdf0e10cSrcweir     FUNCDATA( Accrintm,         UNIQUE,     INTPAR,     5,          FDCat_Finance ),
117cdf0e10cSrcweir     FUNCDATA( Received,         UNIQUE,     INTPAR,     5,          FDCat_Finance ),
118cdf0e10cSrcweir     FUNCDATA( Disc,             UNIQUE,     INTPAR,     5,          FDCat_Finance ),
119cdf0e10cSrcweir     FUNCDATA( Duration,         DOUBLE,     INTPAR,     6,          FDCat_Finance ),
120cdf0e10cSrcweir     FUNCDATA( Effect,           DOUBLE,     STDPAR,     2,          FDCat_Finance ),
121cdf0e10cSrcweir     FUNCDATA( Cumprinc,         DOUBLE,     STDPAR,     6,          FDCat_Finance ),
122cdf0e10cSrcweir     FUNCDATA( Cumipmt,          DOUBLE,     STDPAR,     6,          FDCat_Finance ),
123cdf0e10cSrcweir     FUNCDATA( Price,            UNIQUE,     INTPAR,     7,          FDCat_Finance ),
124cdf0e10cSrcweir     FUNCDATA( Pricedisc,        UNIQUE,     INTPAR,     5,          FDCat_Finance ),
125cdf0e10cSrcweir     FUNCDATA( Pricemat,         UNIQUE,     INTPAR,     6,          FDCat_Finance ),
126cdf0e10cSrcweir     FUNCDATA( Mduration,        UNIQUE,     INTPAR,     6,          FDCat_Finance ),
127cdf0e10cSrcweir     FUNCDATA( Nominal,          DOUBLE,     STDPAR,     2,          FDCat_Finance ),
128cdf0e10cSrcweir     FUNCDATA( Dollarfr,         UNIQUE,     STDPAR,     2,          FDCat_Finance ),
129cdf0e10cSrcweir     FUNCDATA( Dollarde,         UNIQUE,     STDPAR,     2,          FDCat_Finance ),
130cdf0e10cSrcweir     FUNCDATA( Yield,            UNIQUE,     INTPAR,     7,          FDCat_Finance ),
131cdf0e10cSrcweir     FUNCDATA( Yielddisc,        UNIQUE,     INTPAR,     5,          FDCat_Finance ),
132cdf0e10cSrcweir     FUNCDATA( Yieldmat,         UNIQUE,     INTPAR,     6,          FDCat_Finance ),
133cdf0e10cSrcweir     FUNCDATA( Tbilleq,          UNIQUE,     INTPAR,     3,          FDCat_Finance ),
134cdf0e10cSrcweir     FUNCDATA( Tbillprice,       UNIQUE,     INTPAR,     3,          FDCat_Finance ),
135cdf0e10cSrcweir     FUNCDATA( Tbillyield,       UNIQUE,     INTPAR,     3,          FDCat_Finance ),
136cdf0e10cSrcweir     FUNCDATA( Oddfprice,        UNIQUE,     INTPAR,     9,          FDCat_Finance ),
137cdf0e10cSrcweir     FUNCDATA( Oddfyield,        UNIQUE,     INTPAR,     9,          FDCat_Finance ),
138cdf0e10cSrcweir     FUNCDATA( Oddlprice,        UNIQUE,     INTPAR,     8,          FDCat_Finance ),
139cdf0e10cSrcweir     FUNCDATA( Oddlyield,        UNIQUE,     INTPAR,     8,          FDCat_Finance ),
140cdf0e10cSrcweir     FUNCDATA( Xirr,             UNIQUE,     INTPAR,     3,          FDCat_Finance ),
141cdf0e10cSrcweir     FUNCDATA( Xnpv,             UNIQUE,     STDPAR,     3,          FDCat_Finance ),
142cdf0e10cSrcweir     FUNCDATA( Intrate,          UNIQUE,     INTPAR,     5,          FDCat_Finance ),
143cdf0e10cSrcweir     FUNCDATA( Coupncd,          UNIQUE,     INTPAR,     4,          FDCat_Finance ),
144cdf0e10cSrcweir     FUNCDATA( Coupdays,         UNIQUE,     INTPAR,     4,          FDCat_Finance ),
145cdf0e10cSrcweir     FUNCDATA( Coupdaysnc,       UNIQUE,     INTPAR,     4,          FDCat_Finance ),
146cdf0e10cSrcweir     FUNCDATA( Coupdaybs,        UNIQUE,     INTPAR,     4,          FDCat_Finance ),
147cdf0e10cSrcweir     FUNCDATA( Couppcd,          UNIQUE,     INTPAR,     4,          FDCat_Finance ),
148cdf0e10cSrcweir     FUNCDATA( Coupnum,          UNIQUE,     INTPAR,     4,          FDCat_Finance ),
149cdf0e10cSrcweir     FUNCDATA( Fvschedule,       UNIQUE,     STDPAR,     2,          FDCat_Finance )
150cdf0e10cSrcweir };
151cdf0e10cSrcweir #undef FUNCDATA
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 
DaysInMonth(sal_uInt16 nMonth,sal_uInt16 nYear)154cdf0e10cSrcweir sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
155cdf0e10cSrcweir {
156cdf0e10cSrcweir     if( (nMonth == 2) && IsLeapYear( nYear ) )
157cdf0e10cSrcweir         return 29;
158cdf0e10cSrcweir     static const sal_uInt16 aDaysInMonth[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
159cdf0e10cSrcweir     return aDaysInMonth[ nMonth ];
160cdf0e10cSrcweir }
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 
163cdf0e10cSrcweir /**
164cdf0e10cSrcweir  * Convert a date to a count of days starting from 01/01/0001
165cdf0e10cSrcweir  *
166cdf0e10cSrcweir  * The internal representation of a Date used in this Addin
167cdf0e10cSrcweir  * is the number of days between 01/01/0001 and the date
168cdf0e10cSrcweir  * this function converts a Day , Month, Year representation
169cdf0e10cSrcweir  * to this internal Date value.
170cdf0e10cSrcweir  *
171cdf0e10cSrcweir  */
172cdf0e10cSrcweir 
DateToDays(sal_uInt16 nDay,sal_uInt16 nMonth,sal_uInt16 nYear)173cdf0e10cSrcweir sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
174cdf0e10cSrcweir {
175cdf0e10cSrcweir     sal_Int32 nDays = ((sal_Int32)nYear-1) * 365;
176cdf0e10cSrcweir     nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
177cdf0e10cSrcweir 
178cdf0e10cSrcweir     for( sal_uInt16 i = 1; i < nMonth; i++ )
179cdf0e10cSrcweir         nDays += DaysInMonth(i,nYear);
180cdf0e10cSrcweir     nDays += nDay;
181cdf0e10cSrcweir 
182cdf0e10cSrcweir     return nDays;
183cdf0e10cSrcweir }
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 
186cdf0e10cSrcweir /**
187cdf0e10cSrcweir  * Convert a count of days starting from 01/01/0001 to a date
188cdf0e10cSrcweir  *
189cdf0e10cSrcweir  * The internal representation of a Date used in this Addin
190cdf0e10cSrcweir  * is the number of days between 01/01/0001 and the date
191cdf0e10cSrcweir  * this function converts this internal Date value
192cdf0e10cSrcweir  * to a Day , Month, Year representation of a Date.
193cdf0e10cSrcweir  *
194cdf0e10cSrcweir  */
195cdf0e10cSrcweir 
DaysToDate(sal_Int32 nDays,sal_uInt16 & rDay,sal_uInt16 & rMonth,sal_uInt16 & rYear)196cdf0e10cSrcweir void DaysToDate( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear )
197cdf0e10cSrcweir     throw( lang::IllegalArgumentException )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir     if( nDays < 0 )
200cdf0e10cSrcweir         throw lang::IllegalArgumentException();
201cdf0e10cSrcweir 
202cdf0e10cSrcweir     sal_Int32	nTempDays;
203cdf0e10cSrcweir     sal_Int32	i = 0;
204cdf0e10cSrcweir     sal_Bool	bCalc;
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     do
207cdf0e10cSrcweir     {
208cdf0e10cSrcweir         nTempDays = nDays;
209cdf0e10cSrcweir         rYear = (sal_uInt16)((nTempDays / 365) - i);
210cdf0e10cSrcweir         nTempDays -= ((sal_Int32) rYear -1) * 365;
211cdf0e10cSrcweir         nTempDays -= (( rYear -1) / 4) - (( rYear -1) / 100) + ((rYear -1) / 400);
212cdf0e10cSrcweir         bCalc = sal_False;
213cdf0e10cSrcweir         if ( nTempDays < 1 )
214cdf0e10cSrcweir         {
215cdf0e10cSrcweir             i++;
216cdf0e10cSrcweir             bCalc = sal_True;
217cdf0e10cSrcweir         }
218cdf0e10cSrcweir         else
219cdf0e10cSrcweir         {
220cdf0e10cSrcweir             if ( nTempDays > 365 )
221cdf0e10cSrcweir             {
222cdf0e10cSrcweir                 if ( (nTempDays != 366) || !IsLeapYear( rYear ) )
223cdf0e10cSrcweir                 {
224cdf0e10cSrcweir                     i--;
225cdf0e10cSrcweir                     bCalc = sal_True;
226cdf0e10cSrcweir                 }
227cdf0e10cSrcweir             }
228cdf0e10cSrcweir         }
229cdf0e10cSrcweir     }
230cdf0e10cSrcweir     while ( bCalc );
231cdf0e10cSrcweir 
232cdf0e10cSrcweir     rMonth = 1;
233cdf0e10cSrcweir     while ( (sal_Int32)nTempDays > DaysInMonth( rMonth, rYear ) )
234cdf0e10cSrcweir     {
235cdf0e10cSrcweir         nTempDays -= DaysInMonth( rMonth, rYear );
236cdf0e10cSrcweir         rMonth++;
237cdf0e10cSrcweir     }
238cdf0e10cSrcweir     rDay = (sal_uInt16)nTempDays;
239cdf0e10cSrcweir }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 
242cdf0e10cSrcweir /**
243cdf0e10cSrcweir  * Get the null date used by the spreadsheet document
244cdf0e10cSrcweir  *
245cdf0e10cSrcweir  * The internal representation of a Date used in this Addin
246cdf0e10cSrcweir  * is the number of days between 01/01/0001 and the date
247cdf0e10cSrcweir  * this function returns this internal Date value for the document null date
248cdf0e10cSrcweir  *
249cdf0e10cSrcweir  */
250cdf0e10cSrcweir 
GetNullDate(constREFXPS & xOpt)251cdf0e10cSrcweir sal_Int32 GetNullDate( constREFXPS& xOpt ) THROWDEF_RTE
252cdf0e10cSrcweir {
253cdf0e10cSrcweir 	if( xOpt.is() )
254cdf0e10cSrcweir 	{
255cdf0e10cSrcweir 		try
256cdf0e10cSrcweir 		{
257cdf0e10cSrcweir 			ANY	aAny = xOpt->getPropertyValue( STRFROMASCII( "NullDate" ) );
258cdf0e10cSrcweir 			util::Date	aDate;
259cdf0e10cSrcweir 			if( aAny >>= aDate )
260cdf0e10cSrcweir 				return DateToDays( aDate.Day, aDate.Month, aDate.Year );
261cdf0e10cSrcweir 		}
262cdf0e10cSrcweir 		catch( uno::Exception& )
263cdf0e10cSrcweir 		{
264cdf0e10cSrcweir 		}
265cdf0e10cSrcweir 	}
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 	// no null date available -> no calculations possible
268cdf0e10cSrcweir 	throw uno::RuntimeException();
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 
GetDiffDate360(sal_uInt16 nDay1,sal_uInt16 nMonth1,sal_uInt16 nYear1,sal_Bool bLeapYear1,sal_uInt16 nDay2,sal_uInt16 nMonth2,sal_uInt16 nYear2,sal_Bool bUSAMethod)272cdf0e10cSrcweir sal_Int32 GetDiffDate360(
273cdf0e10cSrcweir 				sal_uInt16 nDay1, sal_uInt16 nMonth1, sal_uInt16 nYear1, sal_Bool bLeapYear1,
274cdf0e10cSrcweir 				sal_uInt16 nDay2, sal_uInt16 nMonth2, sal_uInt16 nYear2,
275cdf0e10cSrcweir 				sal_Bool bUSAMethod )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir 	if( nDay1 == 31 )
278cdf0e10cSrcweir 		nDay1--;
279cdf0e10cSrcweir 	else if( bUSAMethod && ( nMonth1 == 2 && ( nDay1 == 29 || ( nDay1 == 28 && !bLeapYear1 ) ) ) )
280cdf0e10cSrcweir 			nDay1 = 30;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 	if( nDay2 == 31 )
283cdf0e10cSrcweir 	{
284cdf0e10cSrcweir 		if( bUSAMethod && nDay1 != 30 )
285cdf0e10cSrcweir 		{
286cdf0e10cSrcweir 			//aDate2 += 1;		-> 1.xx.yyyy
287cdf0e10cSrcweir 			nDay2 = 1;
288cdf0e10cSrcweir 			if( nMonth2 == 12 )
289cdf0e10cSrcweir 			{
290cdf0e10cSrcweir 				nYear2++;
291cdf0e10cSrcweir 				nMonth2 = 1;
292cdf0e10cSrcweir 			}
293cdf0e10cSrcweir 			else
294cdf0e10cSrcweir 				nMonth2++;
295cdf0e10cSrcweir 		}
296cdf0e10cSrcweir 		else
297cdf0e10cSrcweir 			nDay2 = 30;
298cdf0e10cSrcweir 	}
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 	return nDay2 + nMonth2 * 30 + nYear2 * 360 - nDay1 - nMonth1 * 30 - nYear1 * 360;
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir 
GetDiffDate360(sal_Int32 nNullDate,sal_Int32 nDate1,sal_Int32 nDate2,sal_Bool bUSAMethod)304cdf0e10cSrcweir sal_Int32 GetDiffDate360( sal_Int32 nNullDate, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod )
305cdf0e10cSrcweir {
306cdf0e10cSrcweir 	nDate1 += nNullDate;
307cdf0e10cSrcweir 	nDate2 += nNullDate;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 	sal_uInt16 nDay1, nMonth1, nYear1, nDay2, nMonth2, nYear2;
310cdf0e10cSrcweir 
311cdf0e10cSrcweir 	DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
312cdf0e10cSrcweir 	DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 	return GetDiffDate360( nDay1, nMonth1, nYear1, IsLeapYear( nYear1 ), nDay2, nMonth2, nYear2, bUSAMethod );
315cdf0e10cSrcweir }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 
GetDaysInYears(sal_uInt16 nYear1,sal_uInt16 nYear2)318cdf0e10cSrcweir sal_Int32 GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 )
319cdf0e10cSrcweir {
320cdf0e10cSrcweir 	sal_uInt16	nLeaps = 0;
321cdf0e10cSrcweir 	for( sal_uInt16 n = nYear1 ; n <= nYear2 ; n++ )
322cdf0e10cSrcweir 	{
323cdf0e10cSrcweir 		if( IsLeapYear( n ) )
324cdf0e10cSrcweir 			nLeaps++;
325cdf0e10cSrcweir 	}
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 	sal_uInt32	nSum = 1;
328cdf0e10cSrcweir 	nSum += nYear2;
329cdf0e10cSrcweir 	nSum -= nYear1;
330cdf0e10cSrcweir 	nSum *= 365;
331cdf0e10cSrcweir 	nSum += nLeaps;
332cdf0e10cSrcweir 
333cdf0e10cSrcweir 	return nSum;
334cdf0e10cSrcweir }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 
GetDiffParam(sal_Int32 nNullDate,sal_Int32 nStartDate,sal_Int32 nEndDate,sal_Int32 nMode,sal_uInt16 & rYears,sal_Int32 & rDayDiffPart,sal_Int32 & rDaysInYear)337cdf0e10cSrcweir void GetDiffParam( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
338cdf0e10cSrcweir 	sal_uInt16& rYears, sal_Int32& rDayDiffPart, sal_Int32& rDaysInYear ) THROWDEF_RTE_IAE
339cdf0e10cSrcweir {
340cdf0e10cSrcweir 	if( nStartDate > nEndDate )
341cdf0e10cSrcweir 	{
342cdf0e10cSrcweir 		sal_Int32	n = nEndDate;
343cdf0e10cSrcweir 		nEndDate = nStartDate;
344cdf0e10cSrcweir 		nStartDate = n;
345cdf0e10cSrcweir 	}
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 	sal_Int32	nDate1 = nStartDate + nNullDate;
348cdf0e10cSrcweir 	sal_Int32	nDate2 = nEndDate + nNullDate;
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 	sal_uInt16	nDay1, nDay2;
351cdf0e10cSrcweir 	sal_uInt16	nMonth1, nMonth2;
352cdf0e10cSrcweir 	sal_uInt16	nYear1, nYear2;
353cdf0e10cSrcweir 
354cdf0e10cSrcweir 	DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
355cdf0e10cSrcweir 	DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
356cdf0e10cSrcweir 
357cdf0e10cSrcweir 	sal_uInt16	nYears;
358cdf0e10cSrcweir 
359cdf0e10cSrcweir 	sal_Int32	nDayDiff, nDaysInYear;
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 	switch( nMode )
362cdf0e10cSrcweir 	{
363cdf0e10cSrcweir 		case 0:			// 0=USA (NASD) 30/360
364cdf0e10cSrcweir 		case 4:			// 4=Europe 30/360
365cdf0e10cSrcweir 			nDaysInYear = 360;
366cdf0e10cSrcweir 			nYears = nYear2 - nYear1;
367cdf0e10cSrcweir 			nDayDiff = GetDiffDate360( nDay1, nMonth1, nYear1, IsLeapYear( nYear1 ),
368cdf0e10cSrcweir 										nDay2, nMonth2, nYear2, nMode == 0 ) - nYears * nDaysInYear;
369cdf0e10cSrcweir 			break;
370cdf0e10cSrcweir 		case 1:			// 1=exact/exact
371cdf0e10cSrcweir 			nYears = nYear2 - nYear1;
372cdf0e10cSrcweir 
373cdf0e10cSrcweir 			nDaysInYear = IsLeapYear( nYear1 )? 366 : 365;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 			if( nYears && ( nMonth1 > nMonth2 || ( nMonth1 == nMonth2 && nDay1 > nDay2 ) ) )
376cdf0e10cSrcweir 				nYears--;
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 			if( nYears )
379cdf0e10cSrcweir 				nDayDiff = nDate2 - DateToDays( nDay1, nMonth1, nYear2 );
380cdf0e10cSrcweir 			else
381cdf0e10cSrcweir 				nDayDiff = nDate2 - nDate1;
382cdf0e10cSrcweir 
383cdf0e10cSrcweir             if( nDayDiff < 0 )
384cdf0e10cSrcweir                 nDayDiff += nDaysInYear;
385cdf0e10cSrcweir 
386cdf0e10cSrcweir 			break;
387cdf0e10cSrcweir 		case 2:			// 2=exact/360
388cdf0e10cSrcweir 			nDaysInYear = 360;
389cdf0e10cSrcweir 			nYears = sal_uInt16( ( nDate2 - nDate1 ) / nDaysInYear );
390cdf0e10cSrcweir 			nDayDiff = nDate2 - nDate1;
391cdf0e10cSrcweir 			nDayDiff %= nDaysInYear;
392cdf0e10cSrcweir 			break;
393cdf0e10cSrcweir 		case 3:			//3=exact/365
394cdf0e10cSrcweir 			nDaysInYear = 365;
395cdf0e10cSrcweir 			nYears = sal_uInt16( ( nDate2 - nDate1 ) / nDaysInYear );
396cdf0e10cSrcweir 			nDayDiff = nDate2 - nDate1;
397cdf0e10cSrcweir 			nDayDiff %= nDaysInYear;
398cdf0e10cSrcweir 			break;
399cdf0e10cSrcweir 		default:
400cdf0e10cSrcweir 			THROW_IAE;
401cdf0e10cSrcweir 	}
402cdf0e10cSrcweir 
403cdf0e10cSrcweir 	rYears = nYears;
404cdf0e10cSrcweir 	rDayDiffPart = nDayDiff;
405cdf0e10cSrcweir 	rDaysInYear = nDaysInYear;
406cdf0e10cSrcweir }
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 
GetDiffDate(sal_Int32 nNullDate,sal_Int32 nStartDate,sal_Int32 nEndDate,sal_Int32 nMode,sal_Int32 * pOptDaysIn1stYear)409cdf0e10cSrcweir sal_Int32 GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
410cdf0e10cSrcweir 	sal_Int32* pOptDaysIn1stYear ) THROWDEF_RTE_IAE
411cdf0e10cSrcweir {
412cdf0e10cSrcweir 	sal_Bool	bNeg = nStartDate > nEndDate;
413cdf0e10cSrcweir 
414cdf0e10cSrcweir 	if( bNeg )
415cdf0e10cSrcweir 	{
416cdf0e10cSrcweir 		sal_Int32	n = nEndDate;
417cdf0e10cSrcweir 		nEndDate = nStartDate;
418cdf0e10cSrcweir 		nStartDate = n;
419cdf0e10cSrcweir 	}
420cdf0e10cSrcweir 
421cdf0e10cSrcweir 	sal_Int32		nRet;
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 	switch( nMode )
424cdf0e10cSrcweir 	{
425cdf0e10cSrcweir 		case 0:			// 0=USA (NASD) 30/360
426cdf0e10cSrcweir 		case 4:			// 4=Europe 30/360
427cdf0e10cSrcweir 			{
428cdf0e10cSrcweir 			sal_uInt16		nD1, nM1, nY1, nD2, nM2, nY2;
429cdf0e10cSrcweir 
430cdf0e10cSrcweir 			nStartDate += nNullDate;
431cdf0e10cSrcweir 			nEndDate += nNullDate;
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 			DaysToDate( nStartDate, nD1, nM1, nY1 );
434cdf0e10cSrcweir 			DaysToDate( nEndDate, nD2, nM2, nY2 );
435cdf0e10cSrcweir 
436cdf0e10cSrcweir 			sal_Bool		bLeap = IsLeapYear( nY1 );
437cdf0e10cSrcweir 			sal_Int32		nDays, nMonths/*, nYears*/;
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 			nMonths = nM2 - nM1;
440cdf0e10cSrcweir 			nDays = nD2 - nD1;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 			nMonths += ( nY2 - nY1 ) * 12;
443cdf0e10cSrcweir 
444cdf0e10cSrcweir 			nRet = nMonths * 30 + nDays;
445cdf0e10cSrcweir 			if( nMode == 0 && nM1 == 2 && nM2 != 2 && nY1 == nY2 )
446cdf0e10cSrcweir 				nRet -= bLeap? 1 : 2;
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 			if( pOptDaysIn1stYear )
449cdf0e10cSrcweir 				*pOptDaysIn1stYear = 360;
450cdf0e10cSrcweir 			}
451cdf0e10cSrcweir 			break;
452cdf0e10cSrcweir 		case 1:			// 1=exact/exact
453cdf0e10cSrcweir 			if( pOptDaysIn1stYear )
454cdf0e10cSrcweir 			{
455cdf0e10cSrcweir 				sal_uInt16		nD, nM, nY;
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 				DaysToDate( nStartDate + nNullDate, nD, nM, nY );
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 				*pOptDaysIn1stYear = IsLeapYear( nY )? 366 : 365;
460cdf0e10cSrcweir 			}
461cdf0e10cSrcweir 			nRet = nEndDate - nStartDate;
462cdf0e10cSrcweir 			break;
463cdf0e10cSrcweir 		case 2:			// 2=exact/360
464cdf0e10cSrcweir 			nRet = nEndDate - nStartDate;
465cdf0e10cSrcweir 			if( pOptDaysIn1stYear )
466cdf0e10cSrcweir 				*pOptDaysIn1stYear = 360;
467cdf0e10cSrcweir 			break;
468cdf0e10cSrcweir 		case 3:			//3=exact/365
469cdf0e10cSrcweir 			nRet = nEndDate - nStartDate;
470cdf0e10cSrcweir 			if( pOptDaysIn1stYear )
471cdf0e10cSrcweir 				*pOptDaysIn1stYear = 365;
472cdf0e10cSrcweir 			break;
473cdf0e10cSrcweir 		default:
474cdf0e10cSrcweir 			THROW_IAE;
475cdf0e10cSrcweir 	}
476cdf0e10cSrcweir 
477cdf0e10cSrcweir 	return bNeg? -nRet : nRet;
478cdf0e10cSrcweir }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir 
GetYearDiff(sal_Int32 nNullDate,sal_Int32 nStartDate,sal_Int32 nEndDate,sal_Int32 nMode)481cdf0e10cSrcweir double GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
482cdf0e10cSrcweir {
483cdf0e10cSrcweir 	sal_Int32	nDays1stYear;
484cdf0e10cSrcweir 	sal_Int32	nTotalDays = GetDiffDate( nNullDate, nStartDate, nEndDate, nMode, &nDays1stYear );
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 	return double( nTotalDays ) / double( nDays1stYear );
487cdf0e10cSrcweir }
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 
GetDaysInYear(sal_Int32 nNullDate,sal_Int32 nDate,sal_Int32 nMode)490cdf0e10cSrcweir sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
491cdf0e10cSrcweir {
492cdf0e10cSrcweir 	switch( nMode )
493cdf0e10cSrcweir 	{
494cdf0e10cSrcweir 		case 0:			// 0=USA (NASD) 30/360
495cdf0e10cSrcweir 		case 2:			// 2=exact/360
496cdf0e10cSrcweir 		case 4:			// 4=Europe 30/360
497cdf0e10cSrcweir 			return 360;
498cdf0e10cSrcweir 		case 1:			// 1=exact/exact
499cdf0e10cSrcweir 			{
500cdf0e10cSrcweir 			sal_uInt16	nD, nM, nY;
501cdf0e10cSrcweir 			nDate += nNullDate;
502cdf0e10cSrcweir 			DaysToDate( nDate, nD, nM, nY );
503cdf0e10cSrcweir 			return IsLeapYear( nY )? 366 : 365;
504cdf0e10cSrcweir 			}
505cdf0e10cSrcweir 		case 3:			//3=exact/365
506cdf0e10cSrcweir 			return 365;
507cdf0e10cSrcweir 		default:
508cdf0e10cSrcweir 			THROW_IAE;
509cdf0e10cSrcweir 	}
510cdf0e10cSrcweir }
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 
GetYearFrac(sal_Int32 nNullDate,sal_Int32 nStartDate,sal_Int32 nEndDate,sal_Int32 nMode)513cdf0e10cSrcweir double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
514cdf0e10cSrcweir {
515cdf0e10cSrcweir 	if( nStartDate == nEndDate )
516cdf0e10cSrcweir 		return 0.0;		// nothing to do...
517cdf0e10cSrcweir 
518cdf0e10cSrcweir 	sal_uInt16	nYears;
519cdf0e10cSrcweir 	sal_Int32	nDayDiff, nDaysInYear;
520cdf0e10cSrcweir 
521cdf0e10cSrcweir 	GetDiffParam( nNullDate, nStartDate, nEndDate, nMode, nYears, nDayDiff, nDaysInYear );
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 	return double( nYears ) + double( nDayDiff ) / double( nDaysInYear );
524cdf0e10cSrcweir }
525cdf0e10cSrcweir 
526cdf0e10cSrcweir 
Fak(sal_Int32 n)527cdf0e10cSrcweir double Fak( sal_Int32 n )
528cdf0e10cSrcweir {
529cdf0e10cSrcweir 	if( n > 0 )
530cdf0e10cSrcweir 	{
531cdf0e10cSrcweir 		double	fRet = n;
532cdf0e10cSrcweir 		double	f = n - 1;
533cdf0e10cSrcweir 
534cdf0e10cSrcweir 		while( f >= 2.0 )
535cdf0e10cSrcweir 		{
536cdf0e10cSrcweir 			fRet *= f;
537cdf0e10cSrcweir 			f--;
538cdf0e10cSrcweir 		}
539cdf0e10cSrcweir 
540cdf0e10cSrcweir 		return fRet;
541cdf0e10cSrcweir 	}
542cdf0e10cSrcweir 	else if( !n )
543cdf0e10cSrcweir 		return 1.0;
544cdf0e10cSrcweir 	else
545cdf0e10cSrcweir 		return 0.0;
546cdf0e10cSrcweir }
547cdf0e10cSrcweir 
548cdf0e10cSrcweir 
GetGcd(double f1,double f2)549cdf0e10cSrcweir double GetGcd( double f1, double f2 )
550cdf0e10cSrcweir {
551cdf0e10cSrcweir 	double	f = fmod( f1, f2 );
552cdf0e10cSrcweir 	while( f > 0.0 )
553cdf0e10cSrcweir 	{
554cdf0e10cSrcweir 		f1 = f2;
555cdf0e10cSrcweir 		f2 = f;
556cdf0e10cSrcweir 		f = fmod( f1, f2 );
557cdf0e10cSrcweir 	}
558cdf0e10cSrcweir 
559cdf0e10cSrcweir 	return f2;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir 
562cdf0e10cSrcweir 
ConvertToDec(const STRING & aStr,sal_uInt16 nBase,sal_uInt16 nCharLim)563cdf0e10cSrcweir double ConvertToDec( const STRING& aStr, sal_uInt16 nBase, sal_uInt16 nCharLim ) THROWDEF_RTE_IAE
564cdf0e10cSrcweir {
565cdf0e10cSrcweir 	if ( nBase < 2 || nBase > 36 )
566cdf0e10cSrcweir 		THROW_IAE;
567cdf0e10cSrcweir 
568cdf0e10cSrcweir 	sal_uInt32		nStrLen = aStr.getLength();
569cdf0e10cSrcweir 	if( nStrLen > nCharLim )
570cdf0e10cSrcweir 		THROW_IAE;
571cdf0e10cSrcweir 	else if( !nStrLen )
572cdf0e10cSrcweir 		return 0.0;
573cdf0e10cSrcweir 
574cdf0e10cSrcweir 	double			fVal = 0.0;
575cdf0e10cSrcweir 
576cdf0e10cSrcweir 	register const sal_Unicode*	p = aStr.getStr();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 	sal_uInt16			nFirstDig = 0;
579cdf0e10cSrcweir 	sal_Bool			bFirstDig = sal_True;
580cdf0e10cSrcweir 	double				fBase = nBase;
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 	while ( *p )
583cdf0e10cSrcweir 	{
584cdf0e10cSrcweir 		sal_uInt16		n;
585cdf0e10cSrcweir 
586cdf0e10cSrcweir 		if( '0' <= *p && *p <= '9' )
587cdf0e10cSrcweir 			n = *p - '0';
588cdf0e10cSrcweir 		else if( 'A' <= *p && *p <= 'Z' )
589cdf0e10cSrcweir 			n = 10 + ( *p - 'A' );
590cdf0e10cSrcweir 		else if ( 'a' <= *p && *p <= 'z' )
591cdf0e10cSrcweir 			n = 10 + ( *p - 'a' );
592cdf0e10cSrcweir 		else
593cdf0e10cSrcweir 			n = nBase;
594cdf0e10cSrcweir 
595cdf0e10cSrcweir 		if( n < nBase )
596cdf0e10cSrcweir 		{
597cdf0e10cSrcweir 			if( bFirstDig )
598cdf0e10cSrcweir 			{
599cdf0e10cSrcweir 				bFirstDig = sal_False;
600cdf0e10cSrcweir 				nFirstDig = n;
601cdf0e10cSrcweir 			}
602cdf0e10cSrcweir 			fVal = fVal * fBase + double( n );
603cdf0e10cSrcweir 		}
604cdf0e10cSrcweir 		else
605cdf0e10cSrcweir 			// illegal char!
606cdf0e10cSrcweir 			THROW_IAE;
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 		p++;
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 	}
611cdf0e10cSrcweir 
612cdf0e10cSrcweir     if( nStrLen == nCharLim && !bFirstDig && (nFirstDig >= nBase / 2) )
613cdf0e10cSrcweir 	{	// handling negativ values
614cdf0e10cSrcweir 		fVal = ( pow( double( nBase ), double( nCharLim ) ) - fVal );	// complement
615cdf0e10cSrcweir 		fVal *= -1.0;
616cdf0e10cSrcweir 	}
617cdf0e10cSrcweir 
618cdf0e10cSrcweir 	return fVal;
619cdf0e10cSrcweir }
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 
GetMaxChar(sal_uInt16 nBase)622cdf0e10cSrcweir static inline sal_Char GetMaxChar( sal_uInt16 nBase )
623cdf0e10cSrcweir {
624cdf0e10cSrcweir 	const sal_Char*	c = "--123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
625cdf0e10cSrcweir 	return c[ nBase ];
626cdf0e10cSrcweir }
627cdf0e10cSrcweir 
628cdf0e10cSrcweir 
ConvertFromDec(double fNum,double fMin,double fMax,sal_uInt16 nBase,sal_Int32 nPlaces,sal_Int32 nMaxPlaces,sal_Bool bUsePlaces)629cdf0e10cSrcweir STRING ConvertFromDec( double fNum, double fMin, double fMax, sal_uInt16 nBase,
630cdf0e10cSrcweir     sal_Int32 nPlaces, sal_Int32 nMaxPlaces, sal_Bool bUsePlaces ) THROWDEF_RTE_IAE
631cdf0e10cSrcweir {
632cdf0e10cSrcweir     fNum = ::rtl::math::approxFloor( fNum );
633cdf0e10cSrcweir     fMin = ::rtl::math::approxFloor( fMin );
634cdf0e10cSrcweir     fMax = ::rtl::math::approxFloor( fMax );
635cdf0e10cSrcweir 
636cdf0e10cSrcweir     if( fNum < fMin || fNum > fMax || ( bUsePlaces && ( nPlaces <= 0 || nPlaces > nMaxPlaces ) ) )
637cdf0e10cSrcweir 		THROW_IAE;
638cdf0e10cSrcweir 
639cdf0e10cSrcweir     sal_Int64 nNum = static_cast< sal_Int64 >( fNum );
640cdf0e10cSrcweir 	sal_Bool		bNeg = nNum < 0;
641cdf0e10cSrcweir 	if( bNeg )
642cdf0e10cSrcweir 		nNum = sal_Int64( pow( double( nBase ), double( nMaxPlaces ) ) ) + nNum;
643cdf0e10cSrcweir 
644cdf0e10cSrcweir 	STRING			aRet( STRING::valueOf( nNum, nBase ).toAsciiUpperCase() );
645cdf0e10cSrcweir 
646cdf0e10cSrcweir 
647cdf0e10cSrcweir 	if( bUsePlaces )
648cdf0e10cSrcweir 	{
649cdf0e10cSrcweir         sal_Int32 nLen = aRet.getLength();
650cdf0e10cSrcweir 		if( !bNeg && nLen > nPlaces )
651cdf0e10cSrcweir         {
652cdf0e10cSrcweir 			THROW_IAE;
653cdf0e10cSrcweir         }
654cdf0e10cSrcweir 		else if( ( bNeg && nLen < nMaxPlaces ) || ( !bNeg && nLen < nPlaces ) )
655cdf0e10cSrcweir 		{
656cdf0e10cSrcweir             sal_Int32   nLeft = nPlaces - nLen;
657cdf0e10cSrcweir 			sal_Char*	p = new sal_Char[ nLeft + 1 ];
658cdf0e10cSrcweir 			memset( p, bNeg? GetMaxChar( nBase ) : '0', nLeft );
659cdf0e10cSrcweir 			p[ nLeft ] = 0x00;
660cdf0e10cSrcweir 			STRING	aTmp( p, nLeft, RTL_TEXTENCODING_MS_1252 );
661cdf0e10cSrcweir 			aTmp += aRet;
662cdf0e10cSrcweir 			aRet = aTmp;
663cdf0e10cSrcweir 
664cdf0e10cSrcweir 			delete[] p;
665cdf0e10cSrcweir 		}
666cdf0e10cSrcweir 	}
667cdf0e10cSrcweir 
668cdf0e10cSrcweir 	return aRet;
669cdf0e10cSrcweir }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir // implementation moved to module sal, see #i97091#
Erf(double x)672cdf0e10cSrcweir double Erf( double x )
673cdf0e10cSrcweir {
674cdf0e10cSrcweir     return ::rtl::math::erf(x);
675cdf0e10cSrcweir }
676cdf0e10cSrcweir 
677cdf0e10cSrcweir // implementation moved to module sal, see #i97091#
Erfc(double x)678cdf0e10cSrcweir double Erfc( double x )
679cdf0e10cSrcweir {
680cdf0e10cSrcweir     return ::rtl::math::erfc(x);
681cdf0e10cSrcweir }
682cdf0e10cSrcweir 
IsNum(sal_Unicode c)683cdf0e10cSrcweir inline sal_Bool IsNum( sal_Unicode c )
684cdf0e10cSrcweir {
685cdf0e10cSrcweir 	return c >= '0' && c <= '9';
686cdf0e10cSrcweir }
687cdf0e10cSrcweir 
688cdf0e10cSrcweir 
IsComma(sal_Unicode c)689cdf0e10cSrcweir inline sal_Bool IsComma( sal_Unicode c )
690cdf0e10cSrcweir {
691cdf0e10cSrcweir 	return c == '.' || c == ',';
692cdf0e10cSrcweir }
693cdf0e10cSrcweir 
694cdf0e10cSrcweir 
IsExpStart(sal_Unicode c)695cdf0e10cSrcweir inline sal_Bool IsExpStart( sal_Unicode c )
696cdf0e10cSrcweir {
697cdf0e10cSrcweir 	return c == 'e' || c == 'E';
698cdf0e10cSrcweir }
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 
IsImagUnit(sal_Unicode c)701cdf0e10cSrcweir inline sal_Bool IsImagUnit( sal_Unicode c )
702cdf0e10cSrcweir {
703cdf0e10cSrcweir 	return c == 'i' || c == 'j';
704cdf0e10cSrcweir }
705cdf0e10cSrcweir 
706cdf0e10cSrcweir 
GetVal(sal_Unicode c)707cdf0e10cSrcweir inline sal_uInt16 GetVal( sal_Unicode c )
708cdf0e10cSrcweir {
709cdf0e10cSrcweir 	return sal_uInt16( c - '0' );
710cdf0e10cSrcweir }
711cdf0e10cSrcweir 
712cdf0e10cSrcweir 
ParseDouble(const sal_Unicode * & rp,double & rRet)713cdf0e10cSrcweir sal_Bool ParseDouble( const sal_Unicode*& rp, double& rRet )
714cdf0e10cSrcweir {
715cdf0e10cSrcweir 	double				fInt = 0.0;
716cdf0e10cSrcweir 	double				fFrac = 0.0;
717cdf0e10cSrcweir 	double				fMult = 0.1;	// multiplier to multiply digits with, when adding fractional ones
718cdf0e10cSrcweir 	sal_Int32			nExp = 0;
719cdf0e10cSrcweir 	sal_Int32			nMaxExp = 307;
720cdf0e10cSrcweir 	sal_uInt16			nDigCnt = 18;	// max. number of digits to read in, rest doesn't matter
721cdf0e10cSrcweir 
722cdf0e10cSrcweir 	enum State	{ S_End = 0, S_Sign, S_IntStart, S_Int, S_IgnoreIntDigs, S_Frac, S_IgnoreFracDigs, S_ExpSign, S_Exp };
723cdf0e10cSrcweir 
724cdf0e10cSrcweir 	State			eS = S_Sign;
725cdf0e10cSrcweir 
726cdf0e10cSrcweir 	sal_Bool			bNegNum = sal_False;
727cdf0e10cSrcweir 	sal_Bool			bNegExp = sal_False;
728cdf0e10cSrcweir 
729cdf0e10cSrcweir 	const sal_Unicode*	p = rp;
730cdf0e10cSrcweir 	sal_Unicode			c;
731cdf0e10cSrcweir 
732cdf0e10cSrcweir 	while( eS )
733cdf0e10cSrcweir 	{
734cdf0e10cSrcweir 		c = *p;
735cdf0e10cSrcweir 		switch( eS )
736cdf0e10cSrcweir 		{
737cdf0e10cSrcweir 			case S_Sign:
738cdf0e10cSrcweir 				if( IsNum( c ) )
739cdf0e10cSrcweir 				{
740cdf0e10cSrcweir 					fInt = GetVal( c );
741cdf0e10cSrcweir 					nDigCnt--;
742cdf0e10cSrcweir 					eS = S_Int;
743cdf0e10cSrcweir 				}
744cdf0e10cSrcweir 				else if( c == '-' )
745cdf0e10cSrcweir 				{
746cdf0e10cSrcweir 					bNegNum = sal_True;
747cdf0e10cSrcweir 					eS = S_IntStart;
748cdf0e10cSrcweir 				}
749cdf0e10cSrcweir 				else if( c == '+' )
750cdf0e10cSrcweir 					eS = S_IntStart;
751cdf0e10cSrcweir 				else if( IsComma( c ) )
752cdf0e10cSrcweir 					eS = S_Frac;
753cdf0e10cSrcweir 				else
754cdf0e10cSrcweir 					return sal_False;
755cdf0e10cSrcweir 				break;
756cdf0e10cSrcweir 			case S_IntStart:
757cdf0e10cSrcweir 				if( IsNum( c ) )
758cdf0e10cSrcweir 				{
759cdf0e10cSrcweir 					fInt = GetVal( c );
760cdf0e10cSrcweir 					nDigCnt--;
761cdf0e10cSrcweir 					eS = S_Int;
762cdf0e10cSrcweir 				}
763cdf0e10cSrcweir 				else if( IsComma( c ) )
764cdf0e10cSrcweir 					eS = S_Frac;
765cdf0e10cSrcweir 				else if( IsImagUnit( c ) )
766cdf0e10cSrcweir 				{
767cdf0e10cSrcweir 					rRet = 0.0;
768cdf0e10cSrcweir 					return sal_True;
769cdf0e10cSrcweir 				}
770cdf0e10cSrcweir 				else
771cdf0e10cSrcweir 					return sal_False;
772cdf0e10cSrcweir 				break;
773cdf0e10cSrcweir 			case S_Int:
774cdf0e10cSrcweir 				if( IsNum( c ) )
775cdf0e10cSrcweir 				{
776cdf0e10cSrcweir 					fInt *= 10.0;
777cdf0e10cSrcweir 					fInt += double( GetVal( c ) );
778cdf0e10cSrcweir 					nDigCnt--;
779cdf0e10cSrcweir 					if( !nDigCnt )
780cdf0e10cSrcweir 						eS = S_IgnoreIntDigs;
781cdf0e10cSrcweir 				}
782cdf0e10cSrcweir 				else if( IsComma( c ) )
783cdf0e10cSrcweir 					eS = S_Frac;
784cdf0e10cSrcweir 				else if( IsExpStart( c ) )
785cdf0e10cSrcweir 					eS = S_ExpSign;
786cdf0e10cSrcweir 				else
787cdf0e10cSrcweir 					eS = S_End;
788cdf0e10cSrcweir 				break;
789cdf0e10cSrcweir 			case S_IgnoreIntDigs:
790cdf0e10cSrcweir 				if( IsNum( c ) )
791cdf0e10cSrcweir 					nExp++;			// just multiply num with 10... ;-)
792cdf0e10cSrcweir 				else if( IsComma( c ) )
793cdf0e10cSrcweir 					eS = S_Frac;
794cdf0e10cSrcweir 				else if( IsExpStart( c ) )
795cdf0e10cSrcweir 					eS = S_ExpSign;
796cdf0e10cSrcweir 				else
797cdf0e10cSrcweir 					eS = S_End;
798cdf0e10cSrcweir 				break;
799cdf0e10cSrcweir 			case S_Frac:
800cdf0e10cSrcweir 				if( IsNum( c ) )
801cdf0e10cSrcweir 				{
802cdf0e10cSrcweir 					fFrac += double( GetVal( c ) ) * fMult;
803cdf0e10cSrcweir 					nDigCnt--;
804cdf0e10cSrcweir 					if( nDigCnt )
805cdf0e10cSrcweir 						fMult *= 0.1;
806cdf0e10cSrcweir 					else
807cdf0e10cSrcweir 						eS = S_IgnoreFracDigs;
808cdf0e10cSrcweir 				}
809cdf0e10cSrcweir 				else if( IsExpStart( c ) )
810cdf0e10cSrcweir 					eS = S_ExpSign;
811cdf0e10cSrcweir 				else
812cdf0e10cSrcweir 					eS = S_End;
813cdf0e10cSrcweir 				break;
814cdf0e10cSrcweir 			case S_IgnoreFracDigs:
815cdf0e10cSrcweir 				if( IsExpStart( c ) )
816cdf0e10cSrcweir 					eS = S_ExpSign;
817cdf0e10cSrcweir 				else if( !IsNum( c ) )
818cdf0e10cSrcweir 					eS = S_End;
819cdf0e10cSrcweir 				break;
820cdf0e10cSrcweir 			case S_ExpSign:
821cdf0e10cSrcweir 				if( IsNum( c ) )
822cdf0e10cSrcweir 				{
823cdf0e10cSrcweir 					nExp = GetVal( c );
824cdf0e10cSrcweir 					eS = S_Exp;
825cdf0e10cSrcweir 				}
826cdf0e10cSrcweir 				else if( c == '-' )
827cdf0e10cSrcweir 				{
828cdf0e10cSrcweir 					bNegExp = sal_True;
829cdf0e10cSrcweir 					eS = S_Exp;
830cdf0e10cSrcweir 				}
831cdf0e10cSrcweir 				else if( c != '+' )
832cdf0e10cSrcweir 					eS = S_End;
833cdf0e10cSrcweir 				break;
834cdf0e10cSrcweir 			case S_Exp:
835cdf0e10cSrcweir 				if( IsNum( c ) )
836cdf0e10cSrcweir 				{
837cdf0e10cSrcweir 					nExp *= 10;
838cdf0e10cSrcweir 					nExp += GetVal( c );
839cdf0e10cSrcweir 					if( nExp > nMaxExp )
840cdf0e10cSrcweir 						return sal_False;
841cdf0e10cSrcweir 				}
842cdf0e10cSrcweir 				else
843cdf0e10cSrcweir 					eS = S_End;
844cdf0e10cSrcweir 				break;
845cdf0e10cSrcweir             case S_End:     // to avoid compiler warning
846cdf0e10cSrcweir                 break;      // loop exits anyway
847cdf0e10cSrcweir 		}
848cdf0e10cSrcweir 
849cdf0e10cSrcweir 		p++;
850cdf0e10cSrcweir 	}
851cdf0e10cSrcweir 
852cdf0e10cSrcweir 	p--;		// set pointer back to last
853cdf0e10cSrcweir 	rp = p;
854cdf0e10cSrcweir 
855cdf0e10cSrcweir 	fInt += fFrac;
856cdf0e10cSrcweir 	sal_Int32	nLog10 = sal_Int32( log10( fInt ) );
857cdf0e10cSrcweir 
858cdf0e10cSrcweir 	if( bNegExp )
859cdf0e10cSrcweir 		nExp = -nExp;
860cdf0e10cSrcweir 
861cdf0e10cSrcweir 	if( nLog10 + nExp > nMaxExp )
862cdf0e10cSrcweir 		return sal_False;
863cdf0e10cSrcweir 
864cdf0e10cSrcweir     fInt = ::rtl::math::pow10Exp( fInt, nExp );
865cdf0e10cSrcweir 
866cdf0e10cSrcweir 	if( bNegNum )
867cdf0e10cSrcweir 		fInt = -fInt;
868cdf0e10cSrcweir 
869cdf0e10cSrcweir 	rRet = fInt;
870cdf0e10cSrcweir 
871cdf0e10cSrcweir 	return sal_True;
872cdf0e10cSrcweir }
873cdf0e10cSrcweir 
874cdf0e10cSrcweir 
GetString(double f,sal_Bool bLeadingSign,sal_uInt16 nMaxDig)875cdf0e10cSrcweir STRING GetString( double f, sal_Bool bLeadingSign, sal_uInt16 nMaxDig )
876cdf0e10cSrcweir {
877cdf0e10cSrcweir 	const int		nBuff = 256;
878cdf0e10cSrcweir 	sal_Char		aBuff[ nBuff + 1 ];
879cdf0e10cSrcweir 	const char*		pFormStr = bLeadingSign? "%+.*g" : "%.*g";
880cdf0e10cSrcweir     int             nLen = snprintf( aBuff, nBuff, pFormStr, int( nMaxDig ), f );
881cdf0e10cSrcweir                     // you never know which underlying implementation you get ...
882cdf0e10cSrcweir                     aBuff[nBuff] = 0;
883cdf0e10cSrcweir                     if ( nLen < 0 || nLen > nBuff )
884cdf0e10cSrcweir                         nLen = strlen( aBuff );
885cdf0e10cSrcweir 
886cdf0e10cSrcweir 	STRING			aRet( aBuff, nLen, RTL_TEXTENCODING_MS_1252 );
887cdf0e10cSrcweir 
888cdf0e10cSrcweir 	return aRet;
889cdf0e10cSrcweir }
890cdf0e10cSrcweir 
891cdf0e10cSrcweir 
GetAmordegrc(sal_Int32 nNullDate,double fCost,sal_Int32 nDate,sal_Int32 nFirstPer,double fRestVal,double fPer,double fRate,sal_Int32 nBase)892cdf0e10cSrcweir double GetAmordegrc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
893cdf0e10cSrcweir 	double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE
894cdf0e10cSrcweir {
895cdf0e10cSrcweir 	if( nBase == 2 )
896cdf0e10cSrcweir 		THROW_IAE;
897cdf0e10cSrcweir 
898cdf0e10cSrcweir 	sal_uInt32	nPer = sal_uInt32( fPer );
899cdf0e10cSrcweir 	double		fUsePer = 1.0 / fRate;
900cdf0e10cSrcweir 	double		fAmorCoeff;
901cdf0e10cSrcweir 
902cdf0e10cSrcweir 	if( fUsePer < 3.0 )
903cdf0e10cSrcweir 		fAmorCoeff = 1.0;
904cdf0e10cSrcweir 	else if( fUsePer < 5.0 )
905cdf0e10cSrcweir 		fAmorCoeff = 1.5;
906cdf0e10cSrcweir 	else if( fUsePer <= 6.0 )
907cdf0e10cSrcweir 		fAmorCoeff = 2.0;
908cdf0e10cSrcweir 	else
909cdf0e10cSrcweir 		fAmorCoeff = 2.5;
910cdf0e10cSrcweir 
911cdf0e10cSrcweir 	fRate *= fAmorCoeff;
912cdf0e10cSrcweir 	double		fNRate = ::rtl::math::round( GetYearFrac( nNullDate, nDate, nFirstPer, nBase ) * fRate * fCost, 0 );
913cdf0e10cSrcweir 	fCost -= fNRate;
914cdf0e10cSrcweir 	double		fRest = fCost - fRestVal;	// Anschaffungskosten - Restwert - Summe aller Abschreibungen
915cdf0e10cSrcweir 
916cdf0e10cSrcweir 	for( sal_uInt32 n = 0 ; n < nPer ; n++ )
917cdf0e10cSrcweir 	{
918cdf0e10cSrcweir 		fNRate = ::rtl::math::round( fRate * fCost, 0 );
919cdf0e10cSrcweir 		fRest -= fNRate;
920cdf0e10cSrcweir 
921cdf0e10cSrcweir 		if( fRest < 0.0 )
922cdf0e10cSrcweir 		{
923cdf0e10cSrcweir 			switch( nPer - n )
924cdf0e10cSrcweir 			{
925cdf0e10cSrcweir 				case 0:
926cdf0e10cSrcweir 				case 1:
927cdf0e10cSrcweir 					return ::rtl::math::round( fCost * 0.5, 0 );
928cdf0e10cSrcweir 				default:
929cdf0e10cSrcweir 					return 0.0;
930cdf0e10cSrcweir 			}
931cdf0e10cSrcweir 		}
932cdf0e10cSrcweir 
933cdf0e10cSrcweir 		fCost -= fNRate;
934cdf0e10cSrcweir 	}
935cdf0e10cSrcweir 
936cdf0e10cSrcweir 	return fNRate;
937cdf0e10cSrcweir }
938cdf0e10cSrcweir 
939cdf0e10cSrcweir 
GetAmorlinc(sal_Int32 nNullDate,double fCost,sal_Int32 nDate,sal_Int32 nFirstPer,double fRestVal,double fPer,double fRate,sal_Int32 nBase)940cdf0e10cSrcweir double GetAmorlinc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
941cdf0e10cSrcweir 	double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE
942cdf0e10cSrcweir {
943cdf0e10cSrcweir 	if( nBase == 2 )
944cdf0e10cSrcweir 		THROW_IAE;
945cdf0e10cSrcweir 
946cdf0e10cSrcweir 	sal_uInt32	nPer = sal_uInt32( fPer );
947cdf0e10cSrcweir 	double		fOneRate = fCost * fRate;
948cdf0e10cSrcweir 	double		fCostDelta = fCost - fRestVal;
949cdf0e10cSrcweir 	double		f0Rate = GetYearFrac( nNullDate, nDate, nFirstPer, nBase ) * fRate * fCost;
950cdf0e10cSrcweir 	sal_uInt32	nNumOfFullPeriods = sal_uInt32( ( fCost - fRestVal - f0Rate) / fOneRate );
951cdf0e10cSrcweir 
952cdf0e10cSrcweir 	if( nPer == 0 )
953cdf0e10cSrcweir 		return f0Rate;
954cdf0e10cSrcweir 	else if( nPer <= nNumOfFullPeriods )
955cdf0e10cSrcweir 		return fOneRate;
956cdf0e10cSrcweir 	else if( nPer == nNumOfFullPeriods + 1 )
957cdf0e10cSrcweir 		return fCostDelta - fOneRate * nNumOfFullPeriods - f0Rate;
958cdf0e10cSrcweir 	else
959cdf0e10cSrcweir 		return 0.0;
960cdf0e10cSrcweir }
961cdf0e10cSrcweir 
962cdf0e10cSrcweir 
GetDuration(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,double fCoup,double fYield,sal_Int32 nFreq,sal_Int32 nBase)963cdf0e10cSrcweir double GetDuration( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup,
964cdf0e10cSrcweir 	double fYield, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
965cdf0e10cSrcweir {
966cdf0e10cSrcweir 	double			fYearfrac = GetYearFrac( nNullDate, nSettle, nMat, nBase );
967cdf0e10cSrcweir 	double			fNumOfCoups = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase );
968cdf0e10cSrcweir 	double			fDur = 0.0;
969cdf0e10cSrcweir 	const double	f100 = 100.0;
970cdf0e10cSrcweir 	fCoup *= f100 / double( nFreq );	// fCoup is used as cash flow
971cdf0e10cSrcweir 	fYield /= nFreq;
972cdf0e10cSrcweir 	fYield += 1.0;
973cdf0e10cSrcweir 
974cdf0e10cSrcweir     double nDiff = fYearfrac * nFreq - fNumOfCoups;
975cdf0e10cSrcweir 
976cdf0e10cSrcweir 	double			t;
977cdf0e10cSrcweir 
978cdf0e10cSrcweir 	for( t = 1.0 ; t < fNumOfCoups ; t++ )
979cdf0e10cSrcweir         fDur += ( t + nDiff ) * ( fCoup ) / pow( fYield, t + nDiff );
980cdf0e10cSrcweir 
981cdf0e10cSrcweir     fDur += ( fNumOfCoups + nDiff ) * ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );
982cdf0e10cSrcweir 
983cdf0e10cSrcweir     double          p = 0.0;
984cdf0e10cSrcweir     for( t = 1.0 ; t < fNumOfCoups ; t++ )
985cdf0e10cSrcweir         p += fCoup / pow( fYield, t + nDiff );
986cdf0e10cSrcweir 
987cdf0e10cSrcweir     p += ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );
988cdf0e10cSrcweir 
989cdf0e10cSrcweir     fDur /= p;
990cdf0e10cSrcweir     fDur /= double( nFreq );
991cdf0e10cSrcweir 
992cdf0e10cSrcweir     return fDur;
993cdf0e10cSrcweir }
994cdf0e10cSrcweir 
995cdf0e10cSrcweir 
GetYieldmat(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nIssue,double fRate,double fPrice,sal_Int32 nBase)996cdf0e10cSrcweir double GetYieldmat( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
997cdf0e10cSrcweir 	double fRate, double fPrice, sal_Int32 nBase ) THROWDEF_RTE_IAE
998cdf0e10cSrcweir {
999cdf0e10cSrcweir 	double		fIssMat = GetYearFrac( nNullDate, nIssue, nMat, nBase );
1000cdf0e10cSrcweir 	double		fIssSet = GetYearFrac( nNullDate, nIssue, nSettle, nBase );
1001cdf0e10cSrcweir 	double		fSetMat = GetYearFrac( nNullDate, nSettle, nMat, nBase );
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir 	double		y = 1.0 + fIssMat * fRate;
1004cdf0e10cSrcweir 	y /= fPrice / 100.0 + fIssSet * fRate;
1005cdf0e10cSrcweir 	y--;
1006cdf0e10cSrcweir 	y /= fSetMat;
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir 	return y;
1009cdf0e10cSrcweir }
1010cdf0e10cSrcweir 
1011cdf0e10cSrcweir 
GetOddfprice(sal_Int32,sal_Int32,sal_Int32,sal_Int32,sal_Int32,double,double,double,sal_Int32,sal_Int32)1012cdf0e10cSrcweir double GetOddfprice( sal_Int32 /*nNullDate*/, sal_Int32 /*nSettle*/, sal_Int32 /*nMat*/, sal_Int32 /*nIssue*/,
1013cdf0e10cSrcweir 	sal_Int32 /*nFirstCoup*/, double /*fRate*/, double /*fYield*/, double /*fRedemp*/, sal_Int32 /*nFreq*/,
1014cdf0e10cSrcweir 	sal_Int32 /*nBase*/ ) THROWDEF_RTE_IAE
1015cdf0e10cSrcweir {
1016cdf0e10cSrcweir     THROW_RTE;  // #87380#
1017cdf0e10cSrcweir /*
1018cdf0e10cSrcweir 	double		fN = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase ) - 1.0;
1019cdf0e10cSrcweir 	double		fNq = GetCoupnum( nNullDate, nSettle, nFirstCoup, nFreq, nBase ) - 1.0;
1020cdf0e10cSrcweir 	double		fDSC = GetCoupdaysnc( nNullDate, nSettle, nFirstCoup, nFreq, nBase );
1021cdf0e10cSrcweir 	double		fDSC_E = fDSC / GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase );
1022cdf0e10cSrcweir 	double		fNC = GetCoupnum( nNullDate, nIssue, nFirstCoup, nFreq, nBase );
1023cdf0e10cSrcweir 	sal_uInt32	nNC = sal_uInt32( fNC );
1024cdf0e10cSrcweir 	sal_uInt16	nMonthDelta = 12 / sal_uInt16( nFreq );
1025cdf0e10cSrcweir 
1026cdf0e10cSrcweir 	sal_uInt32	i;
1027cdf0e10cSrcweir 	double		f1YieldFreq = 1.0 + fYield / double( nFreq );
1028cdf0e10cSrcweir 	double		f100RateFreq = 100.0 * fRate / double( nFreq );
1029cdf0e10cSrcweir 
1030cdf0e10cSrcweir 	double*		pDC = new double[ nNC + 1 ];
1031cdf0e10cSrcweir 	double*		pNL = new double[ nNC + 1 ];
1032cdf0e10cSrcweir 	double*		pA = new double[ nNC + 1 ];
1033cdf0e10cSrcweir 
1034cdf0e10cSrcweir 	pDC[ 0 ] = pNL[ 0 ] = pA[ 0 ] = 1.0;
1035cdf0e10cSrcweir 
1036cdf0e10cSrcweir     ScaDate aStartDate( nNullDate, nSettle, nBase );
1037cdf0e10cSrcweir     ScaDate aNextCoup( nNullDate, nFirstCoup, nBase );
1038cdf0e10cSrcweir 	if( nNC )
1039cdf0e10cSrcweir 	{
1040cdf0e10cSrcweir         pDC[ 1 ] = ScaDate::GetDiff( aStartDate, aNextCoup );
1041cdf0e10cSrcweir 		pNL[ 1 ] = GetCoupdays( nNullDate, nSettle, nFirstCoup, nFreq, nBase );
1042cdf0e10cSrcweir 		pA[ 1 ] = pDC[ 1 ];
1043cdf0e10cSrcweir         ScaDate aPre;
1044cdf0e10cSrcweir 		for( i = 1 ; i <= nNC ; i++ )
1045cdf0e10cSrcweir 		{
1046cdf0e10cSrcweir 			aPre = aStartDate;
1047cdf0e10cSrcweir             aStartDate.addMonths( nMonthDelta );
1048cdf0e10cSrcweir             aNextCoup.addMonths( nMonthDelta );
1049cdf0e10cSrcweir             pDC[ i ] = ScaDate::GetDiff( aPre, aStartDate );
1050cdf0e10cSrcweir 			pNL[ i ] = GetCoupdays( nNullDate, aStartDate.GetDate( nNullDate ), aNextCoup.GetDate( nNullDate ),
1051cdf0e10cSrcweir 										nFreq, nBase );
1052cdf0e10cSrcweir             pA[ i ] = ScaDate::GetDiff( aStartDate, aNextCoup );
1053cdf0e10cSrcweir 		}
1054cdf0e10cSrcweir 	}
1055cdf0e10cSrcweir 
1056cdf0e10cSrcweir 	double		fT1 = fRedemp / pow( f1YieldFreq, fN + fNq + fDSC_E );
1057cdf0e10cSrcweir 
1058cdf0e10cSrcweir 	double		fT2 = 0.0;
1059cdf0e10cSrcweir 	for( i = 1 ; i <= nNC ; i++ )
1060cdf0e10cSrcweir 		fT2 += pDC[ i ] / pNL[ i ];
1061cdf0e10cSrcweir 	fT2 *= f100RateFreq / pow( f1YieldFreq, fNq + fDSC_E );
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 	double		fT3 = 0.0;
1064cdf0e10cSrcweir 	for( double k = 2.0 ; k <= fN ; k++ )
1065cdf0e10cSrcweir 		fT3 += 1.0 / pow( f1YieldFreq, k - fNq + fDSC_E );
1066cdf0e10cSrcweir 	fT3 *= f100RateFreq;
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir 	double		fT4 = 0.0;
1069cdf0e10cSrcweir 	for( i = 1 ; i <= nNC ; i++ )
1070cdf0e10cSrcweir 		fT4 += pA[ i ] / pNL[ i ];
1071cdf0e10cSrcweir 	fT4 *= f100RateFreq;
1072cdf0e10cSrcweir 
1073cdf0e10cSrcweir 	if( nNC )
1074cdf0e10cSrcweir 	{
1075cdf0e10cSrcweir 		delete pDC;
1076cdf0e10cSrcweir 		delete pNL;
1077cdf0e10cSrcweir 		delete pA;
1078cdf0e10cSrcweir 	}
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir 	return fT1 + fT2 + fT3 - fT4;
1081cdf0e10cSrcweir */
1082cdf0e10cSrcweir }
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir 
getYield_(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,double fCoup,double fPrice,double fRedemp,sal_Int32 nFreq,sal_Int32 nBase)1085cdf0e10cSrcweir double getYield_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice,
1086cdf0e10cSrcweir 					double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
1087cdf0e10cSrcweir {
1088cdf0e10cSrcweir 	double		fRate = fCoup;
1089cdf0e10cSrcweir 	double		fPriceN = 0.0;
1090cdf0e10cSrcweir 	double		fYield1 = 0.0;
1091cdf0e10cSrcweir 	double		fYield2 = 1.0;
1092cdf0e10cSrcweir 	double		fPrice1 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield1, fRedemp, nFreq, nBase );
1093cdf0e10cSrcweir 	double		fPrice2 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield2, fRedemp, nFreq, nBase );
1094cdf0e10cSrcweir 	double		fYieldN = ( fYield2 - fYield1 ) * 0.5;
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir 	for( sal_uInt32 nIter = 0 ; nIter < 100 && fPriceN != fPrice ; nIter++ )
1097cdf0e10cSrcweir 	{
1098cdf0e10cSrcweir 		fPriceN = getPrice_( nNullDate, nSettle, nMat, fRate, fYieldN, fRedemp, nFreq, nBase );
1099cdf0e10cSrcweir 
1100cdf0e10cSrcweir 		if( fPrice == fPrice1 )
1101cdf0e10cSrcweir 			return fYield1;
1102cdf0e10cSrcweir 		else if( fPrice == fPrice2 )
1103cdf0e10cSrcweir 			return fYield2;
1104cdf0e10cSrcweir 		else if( fPrice == fPriceN )
1105cdf0e10cSrcweir 			return fYieldN;
1106cdf0e10cSrcweir 		else if( fPrice < fPrice2 )
1107cdf0e10cSrcweir 		{
1108cdf0e10cSrcweir 			fYield2 *= 2.0;
1109cdf0e10cSrcweir 			fPrice2 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield2, fRedemp, nFreq, nBase );
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir 			fYieldN = ( fYield2 - fYield1 ) * 0.5;
1112cdf0e10cSrcweir 		}
1113cdf0e10cSrcweir 		else
1114cdf0e10cSrcweir 		{
1115cdf0e10cSrcweir 			if( fPrice < fPriceN )
1116cdf0e10cSrcweir 			{
1117cdf0e10cSrcweir 				fYield1 = fYieldN;
1118cdf0e10cSrcweir 				fPrice1 = fPriceN;
1119cdf0e10cSrcweir 			}
1120cdf0e10cSrcweir 			else
1121cdf0e10cSrcweir 			{
1122cdf0e10cSrcweir 				fYield2 = fYieldN;
1123cdf0e10cSrcweir 				fPrice2 = fPriceN;
1124cdf0e10cSrcweir 			}
1125cdf0e10cSrcweir 
1126cdf0e10cSrcweir 			fYieldN = fYield2 - ( fYield2 - fYield1 ) * ( ( fPrice - fPrice2 ) / ( fPrice1 - fPrice2 ) );
1127cdf0e10cSrcweir 		}
1128cdf0e10cSrcweir 	}
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir 	if( fabs( fPrice - fPriceN ) > fPrice / 100.0 )
1131cdf0e10cSrcweir 		THROW_IAE;		// result not precise enough
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir 	return fYieldN;
1134cdf0e10cSrcweir }
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir 
getPrice_(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,double fRate,double fYield,double fRedemp,sal_Int32 nFreq,sal_Int32 nBase)1137cdf0e10cSrcweir double getPrice_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield,
1138cdf0e10cSrcweir 					double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
1139cdf0e10cSrcweir {
1140cdf0e10cSrcweir 	double		fFreq = nFreq;
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir 	double		fE = GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase );
1143cdf0e10cSrcweir 	double		fDSC_E = GetCoupdaysnc( nNullDate, nSettle, nMat, nFreq, nBase ) / fE;
1144cdf0e10cSrcweir 	double		fN = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase );
1145cdf0e10cSrcweir     double      fA = GetCoupdaybs( nNullDate, nSettle, nMat, nFreq, nBase );
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir 	double		fRet = fRedemp / ( pow( 1.0 + fYield / fFreq, fN - 1.0 + fDSC_E ) );
1148cdf0e10cSrcweir 	fRet -= 100.0 * fRate / fFreq * fA / fE;
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir 	double		fT1 = 100.0 * fRate / fFreq;
1151cdf0e10cSrcweir 	double		fT2 = 1.0 + fYield / fFreq;
1152cdf0e10cSrcweir 
1153cdf0e10cSrcweir 	for( double fK = 0.0 ; fK < fN ; fK++ )
1154cdf0e10cSrcweir 		fRet += fT1 / pow( fT2, fK + fDSC_E );
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir 	return fRet;
1157cdf0e10cSrcweir }
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir 
GetOddfyield(sal_Int32,sal_Int32,sal_Int32,sal_Int32,sal_Int32,double,double,double,sal_Int32,sal_Int32)1160cdf0e10cSrcweir double GetOddfyield( sal_Int32 /*nNullDate*/, sal_Int32 /*nSettle*/, sal_Int32 /*nMat*/, sal_Int32 /*nIssue*/,
1161cdf0e10cSrcweir 	sal_Int32 /*nFirstCoup*/, double /*fRate*/, double /*fPrice*/, double /*fRedemp*/, sal_Int32 /*nFreq*/,
1162cdf0e10cSrcweir 	sal_Int32 /*nBase*/ ) THROWDEF_RTE_IAE
1163cdf0e10cSrcweir {
1164cdf0e10cSrcweir     THROW_RTE;  // #87380#
1165cdf0e10cSrcweir /*
1166cdf0e10cSrcweir 	//GetOddfprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
1167cdf0e10cSrcweir 	//sal_Int32 nFirstCoup, double fRate, double fYield, double fRedemp, sal_Int32 nFreq,
1168cdf0e10cSrcweir 	//sal_Int32 nBase )
1169cdf0e10cSrcweir 	double		fPriceN = 0.0;
1170cdf0e10cSrcweir 	double		fYield1 = 0.0;
1171cdf0e10cSrcweir 	double		fYield2 = 1.0;
1172cdf0e10cSrcweir 	double		fPrice1 = GetOddfprice( nNullDate, nSettle, nMat, nIssue, nFirstCoup, fRate, fYield1, fRedemp, nFreq, nBase );
1173cdf0e10cSrcweir 	double		fPrice2 = GetOddfprice( nNullDate, nSettle, nMat, nIssue, nFirstCoup, fRate, fYield2, fRedemp, nFreq, nBase );
1174cdf0e10cSrcweir 	double		fYieldN = ( fYield2 - fYield1 ) * 0.5;
1175cdf0e10cSrcweir 
1176cdf0e10cSrcweir 	for( sal_uInt32 nIter = 0 ; nIter < 100 && fPriceN != fPrice ; nIter++ )
1177cdf0e10cSrcweir 	{
1178cdf0e10cSrcweir 		fPriceN = GetOddfprice( nNullDate, nSettle, nMat, nIssue, nFirstCoup, fRate, fYieldN, fRedemp, nFreq, nBase );
1179cdf0e10cSrcweir 
1180cdf0e10cSrcweir 		if( fPrice == fPrice1 )
1181cdf0e10cSrcweir 			return fYield1;
1182cdf0e10cSrcweir 		else if( fPrice == fPrice2 )
1183cdf0e10cSrcweir 			return fYield2;
1184cdf0e10cSrcweir 		else if( fPrice == fPriceN )
1185cdf0e10cSrcweir 			return fYieldN;
1186cdf0e10cSrcweir 		else if( fPrice < fPrice2 )
1187cdf0e10cSrcweir 		{
1188cdf0e10cSrcweir 			fYield2 *= 2.0;
1189cdf0e10cSrcweir 			fPrice2 = GetOddfprice( nNullDate, nSettle, nMat, nIssue, nFirstCoup, fRate, fYield2, fRedemp, nFreq, nBase );
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir 			fYieldN = ( fYield2 - fYield1 ) * 0.5;
1192cdf0e10cSrcweir 		}
1193cdf0e10cSrcweir 		else
1194cdf0e10cSrcweir 		{
1195cdf0e10cSrcweir 			if( fPrice < fPriceN )
1196cdf0e10cSrcweir 			{
1197cdf0e10cSrcweir 				fYield1 = fYieldN;
1198cdf0e10cSrcweir 				fPrice1 = fPriceN;
1199cdf0e10cSrcweir 			}
1200cdf0e10cSrcweir 			else
1201cdf0e10cSrcweir 			{
1202cdf0e10cSrcweir 				fYield2 = fYieldN;
1203cdf0e10cSrcweir 				fPrice2 = fPriceN;
1204cdf0e10cSrcweir 			}
1205cdf0e10cSrcweir 
1206cdf0e10cSrcweir 			fYieldN = fYield2 - ( fYield2 - fYield1 ) * ( ( fPrice - fPrice2 ) / ( fPrice1 - fPrice2 ) );
1207cdf0e10cSrcweir 		}
1208cdf0e10cSrcweir 	}
1209cdf0e10cSrcweir 
1210cdf0e10cSrcweir 	if( fabs( fPrice - fPriceN ) > fPrice / 100.0 )
1211cdf0e10cSrcweir 		THROW_IAE;		// result not precise enough
1212cdf0e10cSrcweir 
1213cdf0e10cSrcweir 	return fYieldN;
1214cdf0e10cSrcweir */
1215cdf0e10cSrcweir }
1216cdf0e10cSrcweir 
1217cdf0e10cSrcweir 
GetOddlprice(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nLastCoup,double fRate,double fYield,double fRedemp,sal_Int32 nFreq,sal_Int32 nBase)1218cdf0e10cSrcweir double GetOddlprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastCoup,
1219cdf0e10cSrcweir 	double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
1220cdf0e10cSrcweir {
1221cdf0e10cSrcweir 	double		fFreq = double( nFreq );
1222cdf0e10cSrcweir 	double		fDCi = GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;
1223cdf0e10cSrcweir 	double		fDSCi = GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;
1224cdf0e10cSrcweir 	double		fAi = GetYearFrac( nNullDate, nLastCoup, nSettle, nBase ) * fFreq;
1225cdf0e10cSrcweir 
1226cdf0e10cSrcweir 	double		p = fRedemp + fDCi * 100.0 * fRate / fFreq;
1227cdf0e10cSrcweir 	p /= fDSCi * fYield / fFreq + 1.0;
1228cdf0e10cSrcweir 	p -= fAi * 100.0 * fRate / fFreq;
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir 	return p;
1231cdf0e10cSrcweir }
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir 
GetOddlyield(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nLastCoup,double fRate,double fPrice,double fRedemp,sal_Int32 nFreq,sal_Int32 nBase)1234cdf0e10cSrcweir double GetOddlyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastCoup,
1235cdf0e10cSrcweir 	double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
1236cdf0e10cSrcweir {
1237cdf0e10cSrcweir 	double		fFreq = double( nFreq );
1238cdf0e10cSrcweir 	double		fDCi = GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;
1239cdf0e10cSrcweir 	double		fDSCi = GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;
1240cdf0e10cSrcweir 	double		fAi = GetYearFrac( nNullDate, nLastCoup, nSettle, nBase ) * fFreq;
1241cdf0e10cSrcweir 
1242cdf0e10cSrcweir 	double		y = fRedemp + fDCi * 100.0 * fRate / fFreq;
1243cdf0e10cSrcweir 	y /= fPrice + fAi * 100.0 * fRate / fFreq;
1244cdf0e10cSrcweir 	y--;
1245cdf0e10cSrcweir 	y *= fFreq / fDSCi;
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir 	return y;
1248cdf0e10cSrcweir }
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir 
GetRmz(double fZins,double fZzr,double fBw,double fZw,sal_Int32 nF)1251cdf0e10cSrcweir double GetRmz( double fZins, double fZzr, double fBw, double fZw, sal_Int32 nF )
1252cdf0e10cSrcweir {
1253cdf0e10cSrcweir 	double		fRmz;
1254cdf0e10cSrcweir 	if( fZins == 0.0 )
1255cdf0e10cSrcweir 		fRmz = ( fBw + fZw ) / fZzr;
1256cdf0e10cSrcweir 	else
1257cdf0e10cSrcweir 	{
1258cdf0e10cSrcweir 		double	fTerm = pow( 1.0 + fZins, fZzr );
1259cdf0e10cSrcweir 		if( nF > 0 )
1260cdf0e10cSrcweir 			fRmz = ( fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins / ( 1.0 - 1.0 / fTerm ) ) / ( 1.0 + fZins );
1261cdf0e10cSrcweir 		else
1262cdf0e10cSrcweir 			fRmz = fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins / ( 1.0 - 1.0 / fTerm );
1263cdf0e10cSrcweir 	}
1264cdf0e10cSrcweir 
1265cdf0e10cSrcweir 	return -fRmz;
1266cdf0e10cSrcweir }
1267cdf0e10cSrcweir 
1268cdf0e10cSrcweir 
GetZw(double fZins,double fZzr,double fRmz,double fBw,sal_Int32 nF)1269cdf0e10cSrcweir double GetZw( double fZins, double fZzr, double fRmz, double fBw, sal_Int32 nF )
1270cdf0e10cSrcweir {
1271cdf0e10cSrcweir 	double		fZw;
1272cdf0e10cSrcweir 	if( fZins == 0.0 )
1273cdf0e10cSrcweir 		fZw = fBw + fRmz * fZzr;
1274cdf0e10cSrcweir 	else
1275cdf0e10cSrcweir 	{
1276cdf0e10cSrcweir 		double	fTerm = pow( 1.0 + fZins, fZzr );
1277cdf0e10cSrcweir 		if( nF > 0 )
1278cdf0e10cSrcweir 			fZw = fBw * fTerm + fRmz * ( 1.0 + fZins ) * ( fTerm - 1.0 ) / fZins;
1279cdf0e10cSrcweir 		else
1280cdf0e10cSrcweir 			fZw = fBw * fTerm + fRmz * ( fTerm - 1.0 ) / fZins;
1281cdf0e10cSrcweir 	}
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir 	return -fZw;
1284cdf0e10cSrcweir }
1285cdf0e10cSrcweir 
1286cdf0e10cSrcweir 
1287cdf0e10cSrcweir /*double TBillYield( constREFXPS& xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice ) THROWDEF_RTE_IAE
1288cdf0e10cSrcweir {
1289cdf0e10cSrcweir 	sal_Int32	nDiff = GetDiffDate360( xOpt, nSettle, nMat, sal_True );
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir 	if( fPrice <= 0.0 || nSettle >= nMat || nDiff > 360 )
1292cdf0e10cSrcweir 		THROW_IAE;
1293cdf0e10cSrcweir 
1294cdf0e10cSrcweir 	double		fRet = 100.0;
1295cdf0e10cSrcweir 	fRet /= fPrice;
1296cdf0e10cSrcweir 	fRet--;
1297cdf0e10cSrcweir 	fRet *= double( nDiff );
1298cdf0e10cSrcweir 	fRet /= 360.0;
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir 	return fRet;
1301cdf0e10cSrcweir }*/
1302cdf0e10cSrcweir 
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir //-----------------------------------------------------------------------------
1305cdf0e10cSrcweir // financial functions COUP***
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir 
1308cdf0e10cSrcweir //-------
1309cdf0e10cSrcweir // COUPPCD: find last coupon date before settlement (can be equal to settlement)
lcl_GetCouppcd(ScaDate & rDate,const ScaDate & rSettle,const ScaDate & rMat,sal_Int32 nFreq)1310cdf0e10cSrcweir void lcl_GetCouppcd( ScaDate& rDate, const ScaDate& rSettle, const ScaDate& rMat, sal_Int32 nFreq )
1311cdf0e10cSrcweir     throw( lang::IllegalArgumentException )
1312cdf0e10cSrcweir {
1313cdf0e10cSrcweir     rDate = rMat;
1314cdf0e10cSrcweir     rDate.setYear( rSettle.getYear() );
1315cdf0e10cSrcweir     if( rDate < rSettle )
1316cdf0e10cSrcweir         rDate.addYears( 1 );
1317cdf0e10cSrcweir     while( rDate > rSettle )
1318cdf0e10cSrcweir         rDate.addMonths( -12 / nFreq );
1319cdf0e10cSrcweir }
1320cdf0e10cSrcweir 
GetCouppcd(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nFreq,sal_Int32 nBase)1321cdf0e10cSrcweir double GetCouppcd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1322cdf0e10cSrcweir 	THROWDEF_RTE_IAE
1323cdf0e10cSrcweir {
1324cdf0e10cSrcweir 	if( nSettle >= nMat || CHK_Freq )
1325cdf0e10cSrcweir 		THROW_IAE;
1326cdf0e10cSrcweir 
1327cdf0e10cSrcweir     ScaDate aDate;
1328cdf0e10cSrcweir     lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
1329cdf0e10cSrcweir     return aDate.getDate( nNullDate );
1330cdf0e10cSrcweir }
1331cdf0e10cSrcweir 
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir //-------
1334cdf0e10cSrcweir // COUPNCD: find first coupon date after settlement (is never equal to settlement)
lcl_GetCoupncd(ScaDate & rDate,const ScaDate & rSettle,const ScaDate & rMat,sal_Int32 nFreq)1335cdf0e10cSrcweir void lcl_GetCoupncd( ScaDate& rDate, const ScaDate& rSettle, const ScaDate& rMat, sal_Int32 nFreq )
1336cdf0e10cSrcweir     throw( lang::IllegalArgumentException )
1337cdf0e10cSrcweir {
1338cdf0e10cSrcweir     rDate = rMat;
1339cdf0e10cSrcweir     rDate.setYear( rSettle.getYear() );
1340cdf0e10cSrcweir     if( rDate > rSettle )
1341cdf0e10cSrcweir         rDate.addYears( -1 );
1342cdf0e10cSrcweir     while( rDate <= rSettle )
1343cdf0e10cSrcweir         rDate.addMonths( 12 / nFreq );
1344cdf0e10cSrcweir }
1345cdf0e10cSrcweir 
GetCoupncd(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nFreq,sal_Int32 nBase)1346cdf0e10cSrcweir double GetCoupncd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1347cdf0e10cSrcweir 	THROWDEF_RTE_IAE
1348cdf0e10cSrcweir {
1349cdf0e10cSrcweir 	if( nSettle >= nMat || CHK_Freq )
1350cdf0e10cSrcweir 		THROW_IAE;
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir     ScaDate aDate;
1353cdf0e10cSrcweir     lcl_GetCoupncd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
1354cdf0e10cSrcweir     return aDate.getDate( nNullDate );
1355cdf0e10cSrcweir }
1356cdf0e10cSrcweir 
1357cdf0e10cSrcweir 
1358cdf0e10cSrcweir //-------
1359cdf0e10cSrcweir // COUPDAYBS: get day count: coupon date before settlement <-> settlement
GetCoupdaybs(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nFreq,sal_Int32 nBase)1360cdf0e10cSrcweir double GetCoupdaybs( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1361cdf0e10cSrcweir 	THROWDEF_RTE_IAE
1362cdf0e10cSrcweir {
1363cdf0e10cSrcweir     if( nSettle >= nMat || CHK_Freq )
1364cdf0e10cSrcweir 		THROW_IAE;
1365cdf0e10cSrcweir 
1366cdf0e10cSrcweir     ScaDate aSettle( nNullDate, nSettle, nBase );
1367cdf0e10cSrcweir     ScaDate aDate;
1368cdf0e10cSrcweir     lcl_GetCouppcd( aDate, aSettle, ScaDate( nNullDate, nMat, nBase ), nFreq );
1369cdf0e10cSrcweir     return ScaDate::getDiff( aDate, aSettle );
1370cdf0e10cSrcweir }
1371cdf0e10cSrcweir 
1372cdf0e10cSrcweir 
1373cdf0e10cSrcweir //-------
1374cdf0e10cSrcweir // COUPDAYSNC: get day count: settlement <-> coupon date after settlement
GetCoupdaysnc(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nFreq,sal_Int32 nBase)1375cdf0e10cSrcweir double GetCoupdaysnc( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1376cdf0e10cSrcweir 	THROWDEF_RTE_IAE
1377cdf0e10cSrcweir {
1378cdf0e10cSrcweir 	if( nSettle >= nMat || CHK_Freq )
1379cdf0e10cSrcweir 		THROW_IAE;
1380cdf0e10cSrcweir 
1381cdf0e10cSrcweir     if( (nBase != 0) && (nBase != 4) )
1382cdf0e10cSrcweir     {
1383cdf0e10cSrcweir         ScaDate aSettle( nNullDate, nSettle, nBase );
1384cdf0e10cSrcweir         ScaDate aDate;
1385cdf0e10cSrcweir         lcl_GetCoupncd( aDate, aSettle, ScaDate( nNullDate, nMat, nBase ), nFreq );
1386cdf0e10cSrcweir         return ScaDate::getDiff( aSettle, aDate );
1387cdf0e10cSrcweir     }
1388cdf0e10cSrcweir     return GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase ) - GetCoupdaybs( nNullDate, nSettle, nMat, nFreq, nBase );
1389cdf0e10cSrcweir }
1390cdf0e10cSrcweir 
1391cdf0e10cSrcweir 
1392cdf0e10cSrcweir //-------
1393cdf0e10cSrcweir // COUPDAYS: get day count: coupon date before settlement <-> coupon date after settlement
GetCoupdays(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nFreq,sal_Int32 nBase)1394cdf0e10cSrcweir double GetCoupdays( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1395cdf0e10cSrcweir 	THROWDEF_RTE_IAE
1396cdf0e10cSrcweir {
1397cdf0e10cSrcweir 	if( nSettle >= nMat || CHK_Freq )
1398cdf0e10cSrcweir 		THROW_IAE;
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir     if( nBase == 1 )
1401cdf0e10cSrcweir     {
1402cdf0e10cSrcweir         ScaDate aDate;
1403cdf0e10cSrcweir         lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
1404cdf0e10cSrcweir         ScaDate aNextDate( aDate );
1405cdf0e10cSrcweir         aNextDate.addMonths( 12 / nFreq );
1406cdf0e10cSrcweir         return ScaDate::getDiff( aDate, aNextDate );
1407cdf0e10cSrcweir     }
1408cdf0e10cSrcweir     return static_cast< double >( GetDaysInYear( 0, 0, nBase ) ) / nFreq;
1409cdf0e10cSrcweir }
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir 
1412cdf0e10cSrcweir //-------
1413cdf0e10cSrcweir // COUPNUM: get count of coupon dates
GetCoupnum(sal_Int32 nNullDate,sal_Int32 nSettle,sal_Int32 nMat,sal_Int32 nFreq,sal_Int32 nBase)1414cdf0e10cSrcweir double GetCoupnum( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1415cdf0e10cSrcweir     THROWDEF_RTE_IAE
1416cdf0e10cSrcweir {
1417cdf0e10cSrcweir     if( nSettle >= nMat || CHK_Freq )
1418cdf0e10cSrcweir 		THROW_IAE;
1419cdf0e10cSrcweir 
1420cdf0e10cSrcweir     ScaDate aMat( nNullDate, nMat, nBase );
1421cdf0e10cSrcweir     ScaDate aDate;
1422cdf0e10cSrcweir     lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), aMat, nFreq );
1423cdf0e10cSrcweir     sal_uInt16 nMonths = (aMat.getYear() - aDate.getYear()) * 12 + aMat.getMonth() - aDate.getMonth();
1424cdf0e10cSrcweir     return static_cast< double >( nMonths * nFreq / 12 );
1425cdf0e10cSrcweir }
1426cdf0e10cSrcweir 
1427cdf0e10cSrcweir 
1428cdf0e10cSrcweir 
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir 
1431cdf0e10cSrcweir 
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir const sal_uInt32 MyList::nStartSize = 16;
1434cdf0e10cSrcweir const sal_uInt32 MyList::nIncrSize = 16;
1435cdf0e10cSrcweir 
1436cdf0e10cSrcweir 
_Grow(void)1437cdf0e10cSrcweir void MyList::_Grow( void )
1438cdf0e10cSrcweir {
1439cdf0e10cSrcweir 	nSize += nIncrSize;
1440cdf0e10cSrcweir 
1441cdf0e10cSrcweir 	void**			pNewData = new void*[ nSize ];
1442cdf0e10cSrcweir 	memcpy( pNewData, pData, nNew * sizeof( void* ) );
1443cdf0e10cSrcweir 
1444cdf0e10cSrcweir     delete[] pData;
1445cdf0e10cSrcweir 	pData = pNewData;
1446cdf0e10cSrcweir }
1447cdf0e10cSrcweir 
1448cdf0e10cSrcweir 
MyList(void)1449cdf0e10cSrcweir MyList::MyList( void )
1450cdf0e10cSrcweir {
1451cdf0e10cSrcweir 	nSize = nStartSize;
1452cdf0e10cSrcweir 	pData = new void*[ nSize ];
1453cdf0e10cSrcweir 	nNew = nAct = 0;
1454cdf0e10cSrcweir }
1455cdf0e10cSrcweir 
1456cdf0e10cSrcweir 
~MyList()1457cdf0e10cSrcweir MyList::~MyList()
1458cdf0e10cSrcweir {
1459cdf0e10cSrcweir     delete[] pData;
1460cdf0e10cSrcweir }
1461cdf0e10cSrcweir 
1462cdf0e10cSrcweir 
Insert(void * p,sal_uInt32 n)1463cdf0e10cSrcweir void MyList::Insert( void* p, sal_uInt32 n )
1464cdf0e10cSrcweir {
1465cdf0e10cSrcweir 	if( n >= nNew )
1466cdf0e10cSrcweir 		Append( p );
1467cdf0e10cSrcweir 	else
1468cdf0e10cSrcweir 	{
1469cdf0e10cSrcweir 		Grow();
1470cdf0e10cSrcweir 
1471cdf0e10cSrcweir 		void**		pIns = pData + n;
1472cdf0e10cSrcweir 		memmove( pIns + 1, pIns, ( nNew - n ) * sizeof( void* ) );
1473cdf0e10cSrcweir 
1474cdf0e10cSrcweir 		*pIns = p;
1475cdf0e10cSrcweir 
1476cdf0e10cSrcweir 		nNew++;
1477cdf0e10cSrcweir 	}
1478cdf0e10cSrcweir }
1479cdf0e10cSrcweir 
1480cdf0e10cSrcweir 
1481cdf0e10cSrcweir 
1482cdf0e10cSrcweir 
~StringList()1483cdf0e10cSrcweir StringList::~StringList()
1484cdf0e10cSrcweir {
1485cdf0e10cSrcweir 	for( STRING* p = ( STRING* ) First() ; p ; p = ( STRING* ) Next() )
1486cdf0e10cSrcweir 		delete p;
1487cdf0e10cSrcweir }
1488cdf0e10cSrcweir 
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir class AnalysisRscStrArrLoader : public Resource
1491cdf0e10cSrcweir {
1492cdf0e10cSrcweir private:
1493cdf0e10cSrcweir 	ResStringArray			aStrArray;
1494cdf0e10cSrcweir public:
AnalysisRscStrArrLoader(sal_uInt16 nRsc,sal_uInt16 nArrayId,ResMgr & rResMgr)1495cdf0e10cSrcweir 							AnalysisRscStrArrLoader( sal_uInt16 nRsc, sal_uInt16 nArrayId, ResMgr& rResMgr ) :
1496cdf0e10cSrcweir 								Resource( AnalysisResId( nRsc, rResMgr ) ),
1497cdf0e10cSrcweir 								aStrArray( AnalysisResId( nArrayId, rResMgr ) )
1498cdf0e10cSrcweir 							{
1499cdf0e10cSrcweir 								FreeResource();
1500cdf0e10cSrcweir 							}
1501cdf0e10cSrcweir 
GetStringArray() const1502cdf0e10cSrcweir 	const ResStringArray&	GetStringArray() const { return aStrArray; }
1503cdf0e10cSrcweir };
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir 
1506cdf0e10cSrcweir 
1507cdf0e10cSrcweir 
FuncData(const FuncDataBase & r,ResMgr & rResMgr)1508cdf0e10cSrcweir FuncData::FuncData( const FuncDataBase& r, ResMgr& rResMgr ) :
1509cdf0e10cSrcweir 	aIntName( OUString::createFromAscii( r.pIntName ) ),
1510cdf0e10cSrcweir 	nUINameID( r.nUINameID ),
1511cdf0e10cSrcweir 	nDescrID( r.nDescrID ),
1512cdf0e10cSrcweir 	bDouble( r.bDouble ),
1513cdf0e10cSrcweir 	bWithOpt( r.bWithOpt ),
1514cdf0e10cSrcweir 	nParam( r.nNumOfParams ),
1515cdf0e10cSrcweir 	nCompID( r.nCompListID ),
1516cdf0e10cSrcweir 	eCat( r.eCat )
1517cdf0e10cSrcweir {
1518cdf0e10cSrcweir 	AnalysisRscStrArrLoader	aArrLoader( RID_ANALYSIS_DEFFUNCTION_NAMES, nCompID, rResMgr );
1519cdf0e10cSrcweir //	ResStringArray		aDefFuncNameArray( AnalysisResId( nCompID, rResMgr ) );
1520cdf0e10cSrcweir 	const ResStringArray&	rArr = aArrLoader.GetStringArray();
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir 	sal_uInt16				nCount = sal::static_int_cast<sal_uInt16>( rArr.Count() );
1523cdf0e10cSrcweir 	sal_uInt16				n;
1524cdf0e10cSrcweir 
1525cdf0e10cSrcweir 	for( n = 0 ; n < nCount ; n++ )
1526cdf0e10cSrcweir 		aCompList.Append( rArr.GetString( n ) );
1527cdf0e10cSrcweir }
1528cdf0e10cSrcweir 
1529cdf0e10cSrcweir 
~FuncData()1530cdf0e10cSrcweir FuncData::~FuncData()
1531cdf0e10cSrcweir {
1532cdf0e10cSrcweir }
1533cdf0e10cSrcweir 
1534cdf0e10cSrcweir 
GetStrIndex(sal_uInt16 nParamNum) const1535cdf0e10cSrcweir sal_uInt16 FuncData::GetStrIndex( sal_uInt16 nParamNum ) const
1536cdf0e10cSrcweir {
1537cdf0e10cSrcweir 	if( !bWithOpt )
1538cdf0e10cSrcweir 		nParamNum++;
1539cdf0e10cSrcweir 
1540cdf0e10cSrcweir 	if( nParamNum > nParam )
1541cdf0e10cSrcweir 		return nParam * 2;
1542cdf0e10cSrcweir 	else
1543cdf0e10cSrcweir 		return nParamNum * 2;
1544cdf0e10cSrcweir }
1545cdf0e10cSrcweir 
1546cdf0e10cSrcweir 
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir 
FuncDataList(ResMgr & rResMgr)1549cdf0e10cSrcweir FuncDataList::FuncDataList( ResMgr& rResMgr )
1550cdf0e10cSrcweir {
1551cdf0e10cSrcweir 	const sal_uInt32	nNum = sizeof( pFuncDatas ) / sizeof( FuncDataBase );
1552cdf0e10cSrcweir 
1553cdf0e10cSrcweir 	for( sal_uInt16 n = 0 ; n < nNum ; n++ )
1554cdf0e10cSrcweir 		Append( new FuncData( pFuncDatas[ n ], rResMgr ) );
1555cdf0e10cSrcweir }
1556cdf0e10cSrcweir 
1557cdf0e10cSrcweir 
~FuncDataList()1558cdf0e10cSrcweir FuncDataList::~FuncDataList()
1559cdf0e10cSrcweir {
1560cdf0e10cSrcweir 	for( FuncData* p = ( FuncData* ) First() ; p ; p = ( FuncData* ) Next() )
1561cdf0e10cSrcweir 		delete p;
1562cdf0e10cSrcweir }
1563cdf0e10cSrcweir 
1564cdf0e10cSrcweir 
Get(const OUString & aProgrammaticName) const1565cdf0e10cSrcweir const FuncData* FuncDataList::Get(  const OUString& aProgrammaticName ) const
1566cdf0e10cSrcweir {
1567cdf0e10cSrcweir 	if( aLastName == aProgrammaticName )
1568cdf0e10cSrcweir 		return Get( nLast );
1569cdf0e10cSrcweir 
1570cdf0e10cSrcweir 	( ( FuncDataList* ) this )->aLastName = aProgrammaticName;
1571cdf0e10cSrcweir 
1572cdf0e10cSrcweir 	sal_uInt32	nE = Count();
1573cdf0e10cSrcweir 	for( sal_uInt32 n = 0 ; n < nE ; n++ )
1574cdf0e10cSrcweir 	{
1575cdf0e10cSrcweir 		const FuncData*	p = Get( n );
1576cdf0e10cSrcweir 		if( p->Is( aProgrammaticName ) )
1577cdf0e10cSrcweir 		{
1578cdf0e10cSrcweir 			( ( FuncDataList* ) this )->nLast = n;
1579cdf0e10cSrcweir 			return p;
1580cdf0e10cSrcweir 		}
1581cdf0e10cSrcweir 	}
1582cdf0e10cSrcweir 
1583cdf0e10cSrcweir 	( ( FuncDataList* ) this )->nLast = 0xFFFFFFFF;
1584cdf0e10cSrcweir 	return NULL;
1585cdf0e10cSrcweir }
1586cdf0e10cSrcweir 
1587cdf0e10cSrcweir 
AnalysisResId(sal_uInt16 nId,ResMgr & rResMgr)1588cdf0e10cSrcweir AnalysisResId::AnalysisResId( sal_uInt16 nId, ResMgr& rResMgr ) : ResId( nId, rResMgr )
1589cdf0e10cSrcweir {
1590cdf0e10cSrcweir }
1591cdf0e10cSrcweir 
1592cdf0e10cSrcweir 
1593cdf0e10cSrcweir 
1594cdf0e10cSrcweir 
SortedIndividualInt32List()1595cdf0e10cSrcweir SortedIndividualInt32List::SortedIndividualInt32List()
1596cdf0e10cSrcweir {
1597cdf0e10cSrcweir }
1598cdf0e10cSrcweir 
1599cdf0e10cSrcweir 
~SortedIndividualInt32List()1600cdf0e10cSrcweir SortedIndividualInt32List::~SortedIndividualInt32List()
1601cdf0e10cSrcweir {
1602cdf0e10cSrcweir }
1603cdf0e10cSrcweir 
1604cdf0e10cSrcweir 
Insert(sal_Int32 nDay)1605cdf0e10cSrcweir void SortedIndividualInt32List::Insert( sal_Int32 nDay )
1606cdf0e10cSrcweir {
1607cdf0e10cSrcweir     sal_uInt32 nIndex = Count();
1608cdf0e10cSrcweir     while( nIndex )
1609cdf0e10cSrcweir 	{
1610cdf0e10cSrcweir         nIndex--;
1611cdf0e10cSrcweir         sal_Int32 nRef = Get( nIndex );
1612cdf0e10cSrcweir         if( nDay == nRef )
1613cdf0e10cSrcweir 			return;
1614cdf0e10cSrcweir         else if( nDay > nRef )
1615cdf0e10cSrcweir 		{
1616cdf0e10cSrcweir             MyList::Insert( (void*) nDay, nIndex + 1 );
1617cdf0e10cSrcweir 			return;
1618cdf0e10cSrcweir 		}
1619cdf0e10cSrcweir 	}
1620cdf0e10cSrcweir     MyList::Insert( (void*) nDay, 0UL );
1621cdf0e10cSrcweir }
1622cdf0e10cSrcweir 
1623cdf0e10cSrcweir 
Insert(sal_Int32 nDay,sal_Int32 nNullDate,sal_Bool bInsertOnWeekend)1624cdf0e10cSrcweir void SortedIndividualInt32List::Insert( sal_Int32 nDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend )
1625cdf0e10cSrcweir {
1626cdf0e10cSrcweir     if( !nDay )
1627cdf0e10cSrcweir         return;
1628cdf0e10cSrcweir 
1629cdf0e10cSrcweir     nDay += nNullDate;
1630cdf0e10cSrcweir     if( bInsertOnWeekend || (GetDayOfWeek( nDay ) < 5) )
1631cdf0e10cSrcweir         Insert( nDay );
1632cdf0e10cSrcweir }
1633cdf0e10cSrcweir 
1634cdf0e10cSrcweir 
Insert(double fDay,sal_Int32 nNullDate,sal_Bool bInsertOnWeekend)1635cdf0e10cSrcweir void SortedIndividualInt32List::Insert(
1636cdf0e10cSrcweir         double fDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1637cdf0e10cSrcweir {
1638cdf0e10cSrcweir     if( (fDay < -2147483648.0) || (fDay > 2147483649.0) )
1639cdf0e10cSrcweir         throw lang::IllegalArgumentException();
1640cdf0e10cSrcweir     Insert( static_cast< sal_Int32 >( fDay ), nNullDate, bInsertOnWeekend );
1641cdf0e10cSrcweir }
1642cdf0e10cSrcweir 
1643cdf0e10cSrcweir 
Find(sal_Int32 nVal) const1644cdf0e10cSrcweir sal_Bool SortedIndividualInt32List::Find( sal_Int32 nVal ) const
1645cdf0e10cSrcweir {
1646cdf0e10cSrcweir 	sal_uInt32	nE = Count();
1647cdf0e10cSrcweir 
1648cdf0e10cSrcweir 	if( !nE || nVal < Get( 0 ) || nVal > Get( nE - 1 ) )
1649cdf0e10cSrcweir 		return sal_False;
1650cdf0e10cSrcweir 
1651cdf0e10cSrcweir 	// linear search
1652cdf0e10cSrcweir 
1653cdf0e10cSrcweir 	for( sal_uInt32 n = 0 ; n < nE ; n++ )
1654cdf0e10cSrcweir 	{
1655cdf0e10cSrcweir 		sal_Int32	nRef = Get( n );
1656cdf0e10cSrcweir 
1657cdf0e10cSrcweir 		if( nRef == nVal )
1658cdf0e10cSrcweir 			return sal_True;
1659cdf0e10cSrcweir 		else if( nRef > nVal )
1660cdf0e10cSrcweir 			return sal_False;
1661cdf0e10cSrcweir 	}
1662cdf0e10cSrcweir 	return sal_False;
1663cdf0e10cSrcweir }
1664cdf0e10cSrcweir 
1665cdf0e10cSrcweir 
InsertHolidayList(const ScaAnyConverter & rAnyConv,const uno::Any & rHolAny,sal_Int32 nNullDate,sal_Bool bInsertOnWeekend)1666cdf0e10cSrcweir void SortedIndividualInt32List::InsertHolidayList(
1667cdf0e10cSrcweir         const ScaAnyConverter& rAnyConv,
1668cdf0e10cSrcweir         const uno::Any& rHolAny,
1669cdf0e10cSrcweir         sal_Int32 nNullDate,
1670cdf0e10cSrcweir         sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1671cdf0e10cSrcweir {
1672cdf0e10cSrcweir     double fDay;
1673cdf0e10cSrcweir     if( rAnyConv.getDouble( fDay, rHolAny ) )
1674cdf0e10cSrcweir         Insert( fDay, nNullDate, bInsertOnWeekend );
1675cdf0e10cSrcweir }
1676cdf0e10cSrcweir 
1677cdf0e10cSrcweir 
InsertHolidayList(ScaAnyConverter & rAnyConv,const uno::Reference<beans::XPropertySet> & xOptions,const uno::Any & rHolAny,sal_Int32 nNullDate,sal_Bool bInsertOnWeekend)1678cdf0e10cSrcweir void SortedIndividualInt32List::InsertHolidayList(
1679cdf0e10cSrcweir         ScaAnyConverter& rAnyConv,
1680cdf0e10cSrcweir         const uno::Reference< beans::XPropertySet >& xOptions,
1681cdf0e10cSrcweir         const uno::Any& rHolAny,
1682cdf0e10cSrcweir         sal_Int32 nNullDate,
1683cdf0e10cSrcweir         sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1684cdf0e10cSrcweir {
1685cdf0e10cSrcweir     rAnyConv.init( xOptions );
1686cdf0e10cSrcweir     if( rHolAny.getValueTypeClass() == uno::TypeClass_SEQUENCE )
1687cdf0e10cSrcweir     {
1688cdf0e10cSrcweir         uno::Sequence< uno::Sequence< uno::Any > > aAnySeq;
1689cdf0e10cSrcweir         if( rHolAny >>= aAnySeq )
1690cdf0e10cSrcweir         {
1691cdf0e10cSrcweir             const uno::Sequence< uno::Any >* pSeqArray = aAnySeq.getConstArray();
1692cdf0e10cSrcweir             for( sal_Int32 nIndex1 = 0; nIndex1 < aAnySeq.getLength(); nIndex1++ )
1693cdf0e10cSrcweir             {
1694cdf0e10cSrcweir                 const uno::Sequence< uno::Any >& rSubSeq = pSeqArray[ nIndex1 ];
1695cdf0e10cSrcweir                 const uno::Any* pAnyArray = rSubSeq.getConstArray();
1696cdf0e10cSrcweir 
1697cdf0e10cSrcweir                 for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
1698cdf0e10cSrcweir                     InsertHolidayList( rAnyConv, pAnyArray[ nIndex2 ], nNullDate, bInsertOnWeekend );
1699cdf0e10cSrcweir             }
1700cdf0e10cSrcweir         }
1701cdf0e10cSrcweir         else
1702cdf0e10cSrcweir             throw lang::IllegalArgumentException();
1703cdf0e10cSrcweir     }
1704cdf0e10cSrcweir     else
1705cdf0e10cSrcweir         InsertHolidayList( rAnyConv, rHolAny, nNullDate, bInsertOnWeekend );
1706cdf0e10cSrcweir }
1707cdf0e10cSrcweir 
1708cdf0e10cSrcweir 
1709cdf0e10cSrcweir 
1710cdf0e10cSrcweir //-----------------------------------------------------------------------------
1711cdf0e10cSrcweir 
~ScaDoubleList()1712cdf0e10cSrcweir ScaDoubleList::~ScaDoubleList()
1713cdf0e10cSrcweir {
1714cdf0e10cSrcweir     for( double* pDbl = const_cast< double* >( First() ); pDbl; pDbl = const_cast< double* >( Next() ) )
1715cdf0e10cSrcweir         delete pDbl;
1716cdf0e10cSrcweir }
1717cdf0e10cSrcweir 
1718cdf0e10cSrcweir 
Append(const uno::Sequence<uno::Sequence<double>> & rValueSeq)1719cdf0e10cSrcweir void ScaDoubleList::Append(
1720cdf0e10cSrcweir         const uno::Sequence< uno::Sequence< double > >& rValueSeq ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1721cdf0e10cSrcweir {
1722cdf0e10cSrcweir     const uno::Sequence< double >* pSeqArray = rValueSeq.getConstArray();
1723cdf0e10cSrcweir     for( sal_Int32 nIndex1 = 0; nIndex1 < rValueSeq.getLength(); nIndex1++ )
1724cdf0e10cSrcweir 	{
1725cdf0e10cSrcweir         const uno::Sequence< double >& rSubSeq = pSeqArray[ nIndex1 ];
1726cdf0e10cSrcweir         const double* pArray = rSubSeq.getConstArray();
1727cdf0e10cSrcweir         for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
1728cdf0e10cSrcweir             Append( pArray[ nIndex2 ] );
1729cdf0e10cSrcweir 	}
1730cdf0e10cSrcweir }
1731cdf0e10cSrcweir 
1732cdf0e10cSrcweir 
Append(const uno::Sequence<uno::Sequence<sal_Int32>> & rValueSeq)1733cdf0e10cSrcweir void ScaDoubleList::Append(
1734cdf0e10cSrcweir         const uno::Sequence< uno::Sequence< sal_Int32 > >& rValueSeq ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1735cdf0e10cSrcweir {
1736cdf0e10cSrcweir     const uno::Sequence< sal_Int32 >* pSeqArray = rValueSeq.getConstArray();
1737cdf0e10cSrcweir     for( sal_Int32 nIndex1 = 0; nIndex1 < rValueSeq.getLength(); nIndex1++ )
1738cdf0e10cSrcweir 	{
1739cdf0e10cSrcweir         const uno::Sequence< sal_Int32 >& rSubSeq = pSeqArray[ nIndex1 ];
1740cdf0e10cSrcweir         const sal_Int32* pArray = rSubSeq.getConstArray();
1741cdf0e10cSrcweir         for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
1742cdf0e10cSrcweir             Append( pArray[ nIndex2 ] );
1743cdf0e10cSrcweir 	}
1744cdf0e10cSrcweir }
1745cdf0e10cSrcweir 
1746cdf0e10cSrcweir 
1747cdf0e10cSrcweir 
Append(const ScaAnyConverter & rAnyConv,const uno::Any & rAny,sal_Bool bIgnoreEmpty)1748cdf0e10cSrcweir void ScaDoubleList::Append(
1749cdf0e10cSrcweir         const ScaAnyConverter& rAnyConv,
1750cdf0e10cSrcweir         const uno::Any& rAny,
1751cdf0e10cSrcweir         sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1752cdf0e10cSrcweir {
1753cdf0e10cSrcweir     if( rAny.getValueTypeClass() == uno::TypeClass_SEQUENCE )
1754cdf0e10cSrcweir         Append( rAnyConv, *static_cast< const uno::Sequence< uno::Sequence< uno::Any > >* >( rAny.getValue() ), bIgnoreEmpty );
1755cdf0e10cSrcweir     else
1756cdf0e10cSrcweir     {
1757cdf0e10cSrcweir         double fValue;
1758cdf0e10cSrcweir         if( rAnyConv.getDouble( fValue, rAny ) )
1759cdf0e10cSrcweir             Append( fValue );
1760cdf0e10cSrcweir         else if( !bIgnoreEmpty )
1761cdf0e10cSrcweir             Append( 0.0 );
1762cdf0e10cSrcweir     }
1763cdf0e10cSrcweir }
1764cdf0e10cSrcweir 
1765cdf0e10cSrcweir 
Append(const ScaAnyConverter & rAnyConv,const uno::Sequence<uno::Any> & rAnySeq,sal_Bool bIgnoreEmpty)1766cdf0e10cSrcweir void ScaDoubleList::Append(
1767cdf0e10cSrcweir         const ScaAnyConverter& rAnyConv,
1768cdf0e10cSrcweir         const uno::Sequence< uno::Any >& rAnySeq,
1769cdf0e10cSrcweir         sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1770cdf0e10cSrcweir {
1771cdf0e10cSrcweir     const uno::Any* pArray = rAnySeq.getConstArray();
1772cdf0e10cSrcweir     for( sal_Int32 nIndex = 0; nIndex < rAnySeq.getLength(); nIndex++ )
1773cdf0e10cSrcweir         Append( rAnyConv, pArray[ nIndex ], bIgnoreEmpty );
1774cdf0e10cSrcweir }
1775cdf0e10cSrcweir 
1776cdf0e10cSrcweir 
Append(const ScaAnyConverter & rAnyConv,const uno::Sequence<uno::Sequence<uno::Any>> & rAnySeq,sal_Bool bIgnoreEmpty)1777cdf0e10cSrcweir void ScaDoubleList::Append(
1778cdf0e10cSrcweir         const ScaAnyConverter& rAnyConv,
1779cdf0e10cSrcweir         const uno::Sequence< uno::Sequence< uno::Any > >& rAnySeq,
1780cdf0e10cSrcweir         sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1781cdf0e10cSrcweir {
1782cdf0e10cSrcweir     const uno::Sequence< uno::Any >* pArray = rAnySeq.getConstArray();
1783cdf0e10cSrcweir     for( sal_Int32 nIndex = 0; nIndex < rAnySeq.getLength(); nIndex++ )
1784cdf0e10cSrcweir         Append( rAnyConv, pArray[ nIndex ], bIgnoreEmpty );
1785cdf0e10cSrcweir }
1786cdf0e10cSrcweir 
1787cdf0e10cSrcweir 
1788cdf0e10cSrcweir 
Append(ScaAnyConverter & rAnyConv,const uno::Reference<beans::XPropertySet> & xOpt,const uno::Sequence<uno::Any> & rAnySeq,sal_Bool bIgnoreEmpty)1789cdf0e10cSrcweir void ScaDoubleList::Append(
1790cdf0e10cSrcweir         ScaAnyConverter& rAnyConv,
1791cdf0e10cSrcweir         const uno::Reference< beans::XPropertySet >& xOpt,
1792cdf0e10cSrcweir         const uno::Sequence< uno::Any >& rAnySeq,
1793cdf0e10cSrcweir         sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1794cdf0e10cSrcweir {
1795cdf0e10cSrcweir     rAnyConv.init( xOpt );
1796cdf0e10cSrcweir     Append( rAnyConv, rAnySeq, bIgnoreEmpty );
1797cdf0e10cSrcweir }
1798cdf0e10cSrcweir 
1799cdf0e10cSrcweir 
CheckInsert(double) const1800cdf0e10cSrcweir sal_Bool ScaDoubleList::CheckInsert( double ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
1801cdf0e10cSrcweir {
1802cdf0e10cSrcweir 	return sal_True;
1803cdf0e10cSrcweir }
1804cdf0e10cSrcweir 
1805cdf0e10cSrcweir 
1806cdf0e10cSrcweir 
1807cdf0e10cSrcweir //-----------------------------------------------------------------------------
1808cdf0e10cSrcweir 
CheckInsert(double fValue) const1809cdf0e10cSrcweir sal_Bool ScaDoubleListGT0::CheckInsert( double fValue ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
1810cdf0e10cSrcweir {
1811cdf0e10cSrcweir     if( fValue < 0.0 )
1812cdf0e10cSrcweir         throw lang::IllegalArgumentException();
1813cdf0e10cSrcweir     return fValue > 0.0;
1814cdf0e10cSrcweir }
1815cdf0e10cSrcweir 
1816cdf0e10cSrcweir 
1817cdf0e10cSrcweir 
1818cdf0e10cSrcweir //-----------------------------------------------------------------------------
1819cdf0e10cSrcweir 
CheckInsert(double fValue) const1820cdf0e10cSrcweir sal_Bool ScaDoubleListGE0::CheckInsert( double fValue ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
1821cdf0e10cSrcweir {
1822cdf0e10cSrcweir     if( fValue < 0.0 )
1823cdf0e10cSrcweir         throw lang::IllegalArgumentException();
1824cdf0e10cSrcweir     return sal_True;
1825cdf0e10cSrcweir }
1826cdf0e10cSrcweir 
1827cdf0e10cSrcweir 
1828cdf0e10cSrcweir 
1829cdf0e10cSrcweir //-----------------------------------------------------------------------------
1830cdf0e10cSrcweir 
Complex(const STRING & rStr)1831cdf0e10cSrcweir Complex::Complex( const STRING& rStr ) THROWDEF_RTE_IAE
1832cdf0e10cSrcweir {
1833cdf0e10cSrcweir 	if( !ParseString( rStr, *this ) )
1834cdf0e10cSrcweir 		THROW_IAE;
1835cdf0e10cSrcweir }
1836cdf0e10cSrcweir 
1837cdf0e10cSrcweir 
IsImagUnit(sal_Unicode c)1838cdf0e10cSrcweir inline sal_Bool Complex::IsImagUnit( sal_Unicode c )
1839cdf0e10cSrcweir {
1840cdf0e10cSrcweir 	return c == 'i' || c == 'j';
1841cdf0e10cSrcweir }
1842cdf0e10cSrcweir 
ParseString(const STRING & rStr,Complex & rCompl)1843cdf0e10cSrcweir sal_Bool Complex::ParseString( const STRING& rStr, Complex& rCompl )
1844cdf0e10cSrcweir {
1845cdf0e10cSrcweir     rCompl.c = '\0';    // do not force a symbol, if only real part present
1846cdf0e10cSrcweir 
1847*24c56ab9SHerbert Dürr 	const sal_Unicode* pStr = rStr.getStr();
1848cdf0e10cSrcweir 
1849cdf0e10cSrcweir 	if( IsImagUnit( *pStr ) && rStr.getLength() == 1)
1850cdf0e10cSrcweir 	{
1851ee8f9847SPedro Giffuni 		rCompl.Num= double_complex ( 0.0, 1.0 );
1852cdf0e10cSrcweir 		rCompl.c = *pStr;
1853cdf0e10cSrcweir 		return sal_True;
1854cdf0e10cSrcweir 	}
1855cdf0e10cSrcweir 
1856cdf0e10cSrcweir 	double					f;
1857cdf0e10cSrcweir 
1858cdf0e10cSrcweir 	if( !ParseDouble( pStr, f ) )
1859cdf0e10cSrcweir 		return sal_False;
1860cdf0e10cSrcweir 
1861cdf0e10cSrcweir 	switch( *pStr )
1862cdf0e10cSrcweir 	{
1863cdf0e10cSrcweir 		case '-':	// imag part follows
1864cdf0e10cSrcweir 		case '+':
1865cdf0e10cSrcweir 			{
1866cdf0e10cSrcweir 			double		r = f;
1867cdf0e10cSrcweir 			if( IsImagUnit( pStr[ 1 ] ) )
1868cdf0e10cSrcweir 			{
1869cdf0e10cSrcweir 				rCompl.c = pStr[ 1 ];
1870cdf0e10cSrcweir 				if( pStr[ 2 ] == 0 )
1871cdf0e10cSrcweir 				{
1872ee8f9847SPedro Giffuni 					rCompl.Num = double_complex (f, ( *pStr == '+' )? 1.0 : -1.0 );
1873cdf0e10cSrcweir 					return sal_True;
1874cdf0e10cSrcweir 				}
1875cdf0e10cSrcweir 			}
1876cdf0e10cSrcweir 			else if( ParseDouble( pStr, f ) && IsImagUnit( *pStr ) )
1877cdf0e10cSrcweir 			{
1878cdf0e10cSrcweir 				rCompl.c = *pStr;
1879cdf0e10cSrcweir 				pStr++;
1880cdf0e10cSrcweir 				if( *pStr == 0 )
1881cdf0e10cSrcweir 				{
1882ee8f9847SPedro Giffuni 					rCompl.Num = double_complex (r, f);
1883cdf0e10cSrcweir 					return sal_True;
1884cdf0e10cSrcweir 				}
1885cdf0e10cSrcweir 			}
1886cdf0e10cSrcweir 			}
1887cdf0e10cSrcweir 			break;
1888cdf0e10cSrcweir 		case 'j':
1889cdf0e10cSrcweir 		case 'i':
1890cdf0e10cSrcweir 			rCompl.c = *pStr;
1891cdf0e10cSrcweir 			pStr++;
1892cdf0e10cSrcweir 			if( *pStr == 0 )
1893cdf0e10cSrcweir 			{
1894ee8f9847SPedro Giffuni 				rCompl.Num = double_complex (0.0, f);
1895cdf0e10cSrcweir 				return sal_True;
1896cdf0e10cSrcweir 			}
1897cdf0e10cSrcweir 			break;
1898cdf0e10cSrcweir 		case 0:		// only real-part
1899ee8f9847SPedro Giffuni 			rCompl.Num = double_complex (f, 0.0);
1900cdf0e10cSrcweir 			return sal_True;
1901cdf0e10cSrcweir 	}
1902cdf0e10cSrcweir 
1903cdf0e10cSrcweir 	return sal_False;
1904cdf0e10cSrcweir }
1905cdf0e10cSrcweir 
1906cdf0e10cSrcweir 
GetString() const1907cdf0e10cSrcweir STRING Complex::GetString() const THROWDEF_RTE_IAE
1908cdf0e10cSrcweir {
1909cdf0e10cSrcweir     static const String aI( 'i' );
1910cdf0e10cSrcweir     static const String aJ( 'j' );
1911cdf0e10cSrcweir     static const String aPlus( '+' );
1912cdf0e10cSrcweir     static const String aMinus( '-' );
1913cdf0e10cSrcweir 
1914ee8f9847SPedro Giffuni     CHK_FINITE(Num.real());
1915ee8f9847SPedro Giffuni     CHK_FINITE(Num.imag());
1916cdf0e10cSrcweir     STRING aRet;
1917cdf0e10cSrcweir 
1918ee8f9847SPedro Giffuni     bool bHasImag = Num.imag() != 0.0;
1919ee8f9847SPedro Giffuni     bool bHasReal = !bHasImag || (Num.real() != 0.0);
1920cdf0e10cSrcweir 
1921cdf0e10cSrcweir 	if( bHasReal )
1922ee8f9847SPedro Giffuni 	    aRet = ::GetString( Num.real() );
1923cdf0e10cSrcweir     if( bHasImag )
1924cdf0e10cSrcweir     {
1925ee8f9847SPedro Giffuni         if( Num.imag() == 1.0 )
1926cdf0e10cSrcweir         {
1927cdf0e10cSrcweir             if( bHasReal )
1928cdf0e10cSrcweir                 aRet += aPlus;
1929cdf0e10cSrcweir         }
1930ee8f9847SPedro Giffuni         else if( Num.imag() == -1.0 )
1931cdf0e10cSrcweir             aRet += aMinus;
1932cdf0e10cSrcweir         else
1933ee8f9847SPedro Giffuni             aRet += ::GetString( Num.imag(), bHasReal );
1934cdf0e10cSrcweir         aRet += (c != 'j') ? aI : aJ;
1935cdf0e10cSrcweir     }
1936cdf0e10cSrcweir 
1937cdf0e10cSrcweir 	return aRet;
1938cdf0e10cSrcweir }
1939cdf0e10cSrcweir 
1940cdf0e10cSrcweir 
Arg(void) const1941cdf0e10cSrcweir double Complex::Arg( void ) const THROWDEF_RTE_IAE
1942cdf0e10cSrcweir {
1943ee8f9847SPedro Giffuni 	if( Num.real() == 0.0 && Num.imag() == 0.0 )
1944cdf0e10cSrcweir 		THROW_IAE;
1945cdf0e10cSrcweir 
1946ee8f9847SPedro Giffuni 	double	phi = acos( Num.real() / Abs() );
1947cdf0e10cSrcweir 
1948ee8f9847SPedro Giffuni 	if( Num.imag() < 0.0 )
1949cdf0e10cSrcweir 		phi = -phi;
1950cdf0e10cSrcweir 
1951cdf0e10cSrcweir 	return phi;
1952cdf0e10cSrcweir }
1953cdf0e10cSrcweir 
1954cdf0e10cSrcweir 
Power(double fPower)1955cdf0e10cSrcweir void Complex::Power( double fPower ) THROWDEF_RTE_IAE
1956cdf0e10cSrcweir {
1957ee8f9847SPedro Giffuni 	if( Num.real() == 0.0 && Num.imag() == 0.0 )
1958cdf0e10cSrcweir 	{
1959cdf0e10cSrcweir 		if( fPower > 0 )
1960cdf0e10cSrcweir 		{
1961ee8f9847SPedro Giffuni 			Num = double_complex ( 0.0, 0.0 );
1962cdf0e10cSrcweir 			return;
1963cdf0e10cSrcweir 		}
1964cdf0e10cSrcweir 		else
1965cdf0e10cSrcweir 			THROW_IAE;
1966cdf0e10cSrcweir 	}
1967cdf0e10cSrcweir 
1968cdf0e10cSrcweir 	double		p, phi;
1969cdf0e10cSrcweir 
1970cdf0e10cSrcweir 	p = Abs();
1971cdf0e10cSrcweir 
1972ee8f9847SPedro Giffuni 	phi = acos( Num.real() / p );
1973ee8f9847SPedro Giffuni 	if( Num.imag() < 0.0 )
1974cdf0e10cSrcweir 		phi = -phi;
1975cdf0e10cSrcweir 
1976cdf0e10cSrcweir 	p = pow( p, fPower );
1977cdf0e10cSrcweir 	phi *= fPower;
1978cdf0e10cSrcweir 
1979ee8f9847SPedro Giffuni 	Num = double_complex (cos( phi ) * p, sin( phi ) * p);
1980cdf0e10cSrcweir }
1981cdf0e10cSrcweir 
1982cdf0e10cSrcweir 
Sqrt(void)1983cdf0e10cSrcweir void Complex::Sqrt( void )
1984cdf0e10cSrcweir {
1985cdf0e10cSrcweir 	static const double	fMultConst = 0.7071067811865475;	// ...2440084436210485 = 1/sqrt(2)
1986cdf0e10cSrcweir 	double	p = Abs();
1987ee8f9847SPedro Giffuni 	double	i_ = sqrt( p - Num.real() ) * fMultConst;
1988cdf0e10cSrcweir 
1989ee8f9847SPedro Giffuni 	Num = double_complex (sqrt( p + Num.real() ) * fMultConst, ( Num.imag() < 0.0 )? -i_ : i_);
1990cdf0e10cSrcweir }
1991cdf0e10cSrcweir 
1992cdf0e10cSrcweir 
Sin(void)1993cdf0e10cSrcweir void Complex::Sin( void ) THROWDEF_RTE_IAE
1994cdf0e10cSrcweir {
1995ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
1996feb8f109SRegina Henschel     if( !::rtl::math::isValidArcArg( r ) )
1997cdf0e10cSrcweir 		THROW_IAE;
1998cdf0e10cSrcweir 
1999cdf0e10cSrcweir 	if( i )
2000cdf0e10cSrcweir 	{
2001cdf0e10cSrcweir 		double	r_;
2002cdf0e10cSrcweir 
2003cdf0e10cSrcweir 		r_ = sin( r ) * cosh( i );
2004cdf0e10cSrcweir 		i = cos( r ) * sinh( i );
2005cdf0e10cSrcweir 		r = r_;
2006cdf0e10cSrcweir 	}
2007cdf0e10cSrcweir 	else
2008cdf0e10cSrcweir 		r = sin( r );
2009ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2010cdf0e10cSrcweir }
2011cdf0e10cSrcweir 
2012cdf0e10cSrcweir 
Cos(void)2013cdf0e10cSrcweir void Complex::Cos( void ) THROWDEF_RTE_IAE
2014cdf0e10cSrcweir {
2015ee8f9847SPedro Giffuni 	double r = Num.real(), i = Num.imag() ;
2016feb8f109SRegina Henschel 	if( !::rtl::math::isValidArcArg( r ) )
2017cdf0e10cSrcweir 		THROW_IAE;
2018cdf0e10cSrcweir 
2019cdf0e10cSrcweir 	if( i )
2020cdf0e10cSrcweir 	{
2021cdf0e10cSrcweir 		double		r_;
2022cdf0e10cSrcweir 
2023cdf0e10cSrcweir 		r_ = cos( r ) * cosh( i );
2024cdf0e10cSrcweir 		i = -( sin( r ) * sinh( i ) );
2025cdf0e10cSrcweir 		r = r_;
2026cdf0e10cSrcweir 	}
2027cdf0e10cSrcweir 	else
2028cdf0e10cSrcweir 		r = cos( r );
2029ee8f9847SPedro Giffuni 	Num = double_complex ( r, i );
2030cdf0e10cSrcweir 
2031ee8f9847SPedro Giffuni }
2032cdf0e10cSrcweir 
Div(const Complex & z)2033cdf0e10cSrcweir void Complex::Div( const Complex& z ) THROWDEF_RTE_IAE
2034cdf0e10cSrcweir {
2035ee8f9847SPedro Giffuni 	if( z.Num.real() == 0 && z.Num.imag() == 0 )
2036cdf0e10cSrcweir 		THROW_IAE;
2037cdf0e10cSrcweir 
2038ee8f9847SPedro Giffuni 	double	a1 = Num.real();
2039ee8f9847SPedro Giffuni 	double	a2 = z.Num.real();
2040ee8f9847SPedro Giffuni 	double	b1 = Num.imag();
2041ee8f9847SPedro Giffuni 	double	b2 = z.Num.imag();
2042cdf0e10cSrcweir 
2043cdf0e10cSrcweir 	double	f = 1.0 / ( a2 * a2 + b2 * b2 );
2044cdf0e10cSrcweir 
2045ee8f9847SPedro Giffuni 	Num = f * double_complex ( a1 * a2 + b1 * b2 ,  a2 * b1 - a1 * b2 );
2046cdf0e10cSrcweir 
2047cdf0e10cSrcweir     if( !c ) c = z.c;
2048cdf0e10cSrcweir }
2049cdf0e10cSrcweir 
2050cdf0e10cSrcweir 
Exp(void)2051cdf0e10cSrcweir void Complex::Exp( void )
2052cdf0e10cSrcweir {
2053ee8f9847SPedro Giffuni 	double	fE = exp( Num.real() );
2054ee8f9847SPedro Giffuni 	Num = fE * double_complex ( cos( Num.imag() ), sin( Num.imag() ) );
2055cdf0e10cSrcweir }
2056cdf0e10cSrcweir 
2057cdf0e10cSrcweir 
Ln(void)2058cdf0e10cSrcweir void Complex::Ln( void ) THROWDEF_RTE_IAE
2059cdf0e10cSrcweir {
2060ee8f9847SPedro Giffuni 	double r = Num.real(), i = Num.imag() ;
2061cdf0e10cSrcweir 	if( r == 0.0 && i == 0.0 )
2062cdf0e10cSrcweir 		THROW_IAE;
2063cdf0e10cSrcweir 
2064cdf0e10cSrcweir 	double		fAbs = Abs();
2065cdf0e10cSrcweir 	sal_Bool	bNegi = i < 0.0;
2066cdf0e10cSrcweir 
2067cdf0e10cSrcweir 	i = acos( r / fAbs );
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir 	if( bNegi )
2070cdf0e10cSrcweir 		i = -i;
2071cdf0e10cSrcweir 
2072cdf0e10cSrcweir 	r = log( fAbs );
2073ee8f9847SPedro Giffuni 	Num = double_complex ( r, i );
2074cdf0e10cSrcweir }
2075cdf0e10cSrcweir 
2076cdf0e10cSrcweir 
Log10(void)2077cdf0e10cSrcweir void Complex::Log10( void ) THROWDEF_RTE_IAE
2078cdf0e10cSrcweir {
2079cdf0e10cSrcweir 	Ln();
2080cdf0e10cSrcweir 	Mult( 0.434294481903251828 );	// * log10( e )
2081cdf0e10cSrcweir }
2082cdf0e10cSrcweir 
2083cdf0e10cSrcweir 
Log2(void)2084cdf0e10cSrcweir void Complex::Log2( void ) THROWDEF_RTE_IAE
2085cdf0e10cSrcweir {
2086cdf0e10cSrcweir 	Ln();
2087cdf0e10cSrcweir 	Mult( 1.442695040888963407 );	// * log2( e )
2088cdf0e10cSrcweir }
2089cdf0e10cSrcweir 
2090cdf0e10cSrcweir 
Tan(void)2091feb8f109SRegina Henschel void Complex::Tan(void) THROWDEF_RTE_IAE
2092feb8f109SRegina Henschel {
2093ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
2094feb8f109SRegina Henschel     if ( i )
2095feb8f109SRegina Henschel     {
2096feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( 2.0 * r ) )
2097feb8f109SRegina Henschel             THROW_IAE;
2098feb8f109SRegina Henschel         double fScale =1.0 / ( cos( 2.0 * r ) + cosh( 2.0 * i ));
2099feb8f109SRegina Henschel         r = sin( 2.0 * r ) * fScale;
2100feb8f109SRegina Henschel         i = sinh( 2.0 * i ) * fScale;
2101feb8f109SRegina Henschel     }
2102feb8f109SRegina Henschel     else
2103feb8f109SRegina Henschel     {
2104feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( r ) )
2105feb8f109SRegina Henschel             THROW_IAE;
2106feb8f109SRegina Henschel         r = tan( r );
2107feb8f109SRegina Henschel     }
2108ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2109feb8f109SRegina Henschel }
2110feb8f109SRegina Henschel 
2111feb8f109SRegina Henschel 
Sec(void)2112feb8f109SRegina Henschel void Complex::Sec( void ) THROWDEF_RTE_IAE
2113feb8f109SRegina Henschel {
2114ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
2115feb8f109SRegina Henschel     if( i )
2116feb8f109SRegina Henschel     {
2117feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( 2 * r ) )
2118feb8f109SRegina Henschel             THROW_IAE;
2119feb8f109SRegina Henschel         double fScale = 1.0 / (cosh( 2.0 * i) + cos ( 2.0 * r));
2120feb8f109SRegina Henschel         double  r_;
2121feb8f109SRegina Henschel         r_ = 2.0 * cos( r ) * cosh( i ) * fScale;
2122feb8f109SRegina Henschel         i = 2.0 * sin( r ) * sinh( i ) * fScale;
2123feb8f109SRegina Henschel         r = r_;
2124feb8f109SRegina Henschel     }
2125feb8f109SRegina Henschel     else
2126feb8f109SRegina Henschel     {
2127feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( r ) )
2128feb8f109SRegina Henschel             THROW_IAE;
2129feb8f109SRegina Henschel         r = 1.0 / cos( r );
2130feb8f109SRegina Henschel     }
2131ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2132feb8f109SRegina Henschel }
2133feb8f109SRegina Henschel 
2134feb8f109SRegina Henschel 
Csc(void)2135feb8f109SRegina Henschel void Complex::Csc( void ) THROWDEF_RTE_IAE
2136feb8f109SRegina Henschel {
2137ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
2138feb8f109SRegina Henschel     if( i )
2139feb8f109SRegina Henschel     {
2140feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( 2 * r ) )
2141feb8f109SRegina Henschel             THROW_IAE;
2142feb8f109SRegina Henschel         double fScale = 1.0 / (cosh( 2.0 * i) - cos ( 2.0 * r));
2143feb8f109SRegina Henschel         double  r_;
2144feb8f109SRegina Henschel         r_ = 2.0 * sin( r ) * cosh( i ) * fScale;
2145feb8f109SRegina Henschel         i = -2.0 * cos( r ) * sinh( i ) * fScale;
2146feb8f109SRegina Henschel         r = r_;
2147feb8f109SRegina Henschel     }
2148feb8f109SRegina Henschel     else
2149feb8f109SRegina Henschel     {
2150feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( r ) )
2151feb8f109SRegina Henschel             THROW_IAE;
2152feb8f109SRegina Henschel         r = 1.0 / sin( r );
2153feb8f109SRegina Henschel     }
2154ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2155feb8f109SRegina Henschel }
2156feb8f109SRegina Henschel 
2157feb8f109SRegina Henschel 
Cot(void)2158feb8f109SRegina Henschel void Complex::Cot(void) THROWDEF_RTE_IAE
2159feb8f109SRegina Henschel {
2160ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
2161feb8f109SRegina Henschel     if ( i )
2162feb8f109SRegina Henschel     {
2163feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( 2.0 * r ) )
2164feb8f109SRegina Henschel             THROW_IAE;
2165feb8f109SRegina Henschel         double fScale =1.0 / ( cosh( 2.0 * i ) - cos( 2.0 * r ) );
2166feb8f109SRegina Henschel         r = sin( 2.0 * r ) * fScale;
2167feb8f109SRegina Henschel         i = - ( sinh( 2.0 * i ) * fScale );
2168feb8f109SRegina Henschel     }
2169feb8f109SRegina Henschel     else
2170feb8f109SRegina Henschel     {
2171feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( r ) )
2172feb8f109SRegina Henschel             THROW_IAE;
2173feb8f109SRegina Henschel         r = 1.0 / tan( r );
2174feb8f109SRegina Henschel     }
2175ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2176feb8f109SRegina Henschel }
2177feb8f109SRegina Henschel 
2178feb8f109SRegina Henschel 
Sinh(void)2179feb8f109SRegina Henschel void Complex::Sinh( void ) THROWDEF_RTE_IAE
2180feb8f109SRegina Henschel {
2181ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
2182feb8f109SRegina Henschel     if( !::rtl::math::isValidArcArg( r ) )
2183feb8f109SRegina Henschel         THROW_IAE;
2184feb8f109SRegina Henschel 
2185feb8f109SRegina Henschel     if( i )
2186feb8f109SRegina Henschel     {
2187feb8f109SRegina Henschel         double	r_;
2188feb8f109SRegina Henschel         r_ = sinh( r ) * cos( i );
2189feb8f109SRegina Henschel 		i = cosh( r ) * sin( i );
2190feb8f109SRegina Henschel 		r = r_;
2191feb8f109SRegina Henschel 	}
2192feb8f109SRegina Henschel 	else
2193feb8f109SRegina Henschel 		r = sinh( r );
2194ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2195feb8f109SRegina Henschel }
2196feb8f109SRegina Henschel 
2197feb8f109SRegina Henschel 
Cosh(void)2198feb8f109SRegina Henschel void Complex::Cosh( void ) THROWDEF_RTE_IAE
2199feb8f109SRegina Henschel {
2200ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
2201feb8f109SRegina Henschel     if( !::rtl::math::isValidArcArg( r ) )
2202feb8f109SRegina Henschel         THROW_IAE;
2203feb8f109SRegina Henschel 
2204feb8f109SRegina Henschel     if( i )
2205feb8f109SRegina Henschel     {
2206feb8f109SRegina Henschel         double	r_;
2207feb8f109SRegina Henschel         r_ = cosh( r ) * cos( i );
2208feb8f109SRegina Henschel 		i = sinh( r ) * sin( i );
2209feb8f109SRegina Henschel 		r = r_;
2210feb8f109SRegina Henschel 	}
2211feb8f109SRegina Henschel 	else
2212feb8f109SRegina Henschel 		r = cosh( r );
2213ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2214feb8f109SRegina Henschel }
2215feb8f109SRegina Henschel 
2216feb8f109SRegina Henschel 
Sech(void)2217feb8f109SRegina Henschel void Complex::Sech(void) THROWDEF_RTE_IAE
2218feb8f109SRegina Henschel {
2219ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
2220feb8f109SRegina Henschel     if ( i )
2221feb8f109SRegina Henschel     {
2222feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( 2.0 * r ) )
2223feb8f109SRegina Henschel             THROW_IAE;
2224feb8f109SRegina Henschel         double fScale =1.0 / ( cosh( 2.0 * r ) + cos( 2.0 * i ));
2225feb8f109SRegina Henschel         double r_;
2226a40d3a0fSRegina Henschel 		r_ = 2.0 * cosh( r ) * cos( i ) * fScale;
2227a40d3a0fSRegina Henschel 		i = - (2.0 * sinh( r ) * sin( i ) * fScale );
2228feb8f109SRegina Henschel         r = r_ ;
2229feb8f109SRegina Henschel     }
2230feb8f109SRegina Henschel     else
2231feb8f109SRegina Henschel     {
2232feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( r ) )
2233feb8f109SRegina Henschel             THROW_IAE;
2234feb8f109SRegina Henschel         r = 1.0 / cosh( r );
2235feb8f109SRegina Henschel     }
2236ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2237feb8f109SRegina Henschel }
2238feb8f109SRegina Henschel 
2239feb8f109SRegina Henschel 
Csch(void)2240feb8f109SRegina Henschel void Complex::Csch(void) THROWDEF_RTE_IAE
2241feb8f109SRegina Henschel {
2242ee8f9847SPedro Giffuni     double r = Num.real(), i = Num.imag() ;
2243feb8f109SRegina Henschel     if ( i )
2244feb8f109SRegina Henschel     {
2245feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( 2.0 * r ) )
2246feb8f109SRegina Henschel             THROW_IAE;
2247feb8f109SRegina Henschel         double fScale =1.0 / ( cosh( 2.0 * r ) - cos( 2.0 * i ));
2248feb8f109SRegina Henschel         double r_;
2249a40d3a0fSRegina Henschel 		r_ = 2.0 * sinh( r ) * cos( i ) * fScale;
2250a40d3a0fSRegina Henschel 		i = - ( 2.0 * cosh( r ) * sin( i ) * fScale );
2251feb8f109SRegina Henschel         r = r_ ;
2252feb8f109SRegina Henschel     }
2253feb8f109SRegina Henschel     else
2254feb8f109SRegina Henschel     {
2255feb8f109SRegina Henschel         if( !::rtl::math::isValidArcArg( r ) )
2256feb8f109SRegina Henschel             THROW_IAE;
2257feb8f109SRegina Henschel         r = 1.0 / sinh( r );
2258feb8f109SRegina Henschel     }
2259ee8f9847SPedro Giffuni     Num = double_complex ( r, i );
2260feb8f109SRegina Henschel }
2261cdf0e10cSrcweir 
2262cdf0e10cSrcweir 
~ComplexList()2263cdf0e10cSrcweir ComplexList::~ComplexList()
2264cdf0e10cSrcweir {
2265cdf0e10cSrcweir 	for( Complex* p = ( Complex* ) First() ; p ; p = ( Complex* ) Next() )
2266cdf0e10cSrcweir 		delete p;
2267cdf0e10cSrcweir }
2268cdf0e10cSrcweir 
2269cdf0e10cSrcweir 
Append(const SEQSEQ (STRING)& r,ComplListAppendHandl eAH)2270cdf0e10cSrcweir void ComplexList::Append( const SEQSEQ( STRING )& r, ComplListAppendHandl eAH ) THROWDEF_RTE_IAE
2271cdf0e10cSrcweir {
2272cdf0e10cSrcweir 	sal_Int32	n1, n2;
2273cdf0e10cSrcweir 	sal_Int32	nE1 = r.getLength();
2274cdf0e10cSrcweir 	sal_Int32	nE2;
2275cdf0e10cSrcweir 	sal_Bool	bEmpty0 = eAH == AH_EmpyAs0;
2276cdf0e10cSrcweir 	sal_Bool	bErrOnEmpty = eAH == AH_EmptyAsErr;
2277cdf0e10cSrcweir 
2278cdf0e10cSrcweir 	for( n1 = 0 ; n1 < nE1 ; n1++ )
2279cdf0e10cSrcweir 	{
2280cdf0e10cSrcweir 		const SEQ( STRING )&	rList = r[ n1 ];
2281cdf0e10cSrcweir 		nE2 = rList.getLength();
2282cdf0e10cSrcweir 
2283cdf0e10cSrcweir 		for( n2 = 0 ; n2 < nE2 ; n2++ )
2284cdf0e10cSrcweir 		{
2285cdf0e10cSrcweir 			const STRING&	rStr = rList[ n2 ];
2286cdf0e10cSrcweir 
2287cdf0e10cSrcweir 			if( rStr.getLength() )
2288cdf0e10cSrcweir 				Append( new Complex( rStr ) );
2289cdf0e10cSrcweir 			else if( bEmpty0 )
2290cdf0e10cSrcweir 				Append( new Complex( 0.0 ) );
2291cdf0e10cSrcweir 			else if( bErrOnEmpty )
2292cdf0e10cSrcweir 				THROW_IAE;
2293cdf0e10cSrcweir 		}
2294cdf0e10cSrcweir 	}
2295cdf0e10cSrcweir }
2296cdf0e10cSrcweir 
2297cdf0e10cSrcweir 
Append(const SEQ (ANY)& aMultPars,ComplListAppendHandl eAH)2298cdf0e10cSrcweir void ComplexList::Append( const SEQ( ANY )& aMultPars, ComplListAppendHandl eAH ) THROWDEF_RTE_IAE
2299cdf0e10cSrcweir {
2300cdf0e10cSrcweir 	sal_Int32		nEle = aMultPars.getLength();
2301cdf0e10cSrcweir 	sal_Bool		bEmpty0 = eAH == AH_EmpyAs0;
2302cdf0e10cSrcweir 	sal_Bool		bErrOnEmpty = eAH == AH_EmptyAsErr;
2303cdf0e10cSrcweir 
2304cdf0e10cSrcweir 	for( sal_Int32 i = 0 ; i < nEle ; i++ )
2305cdf0e10cSrcweir 	{
2306cdf0e10cSrcweir 		const ANY&	r = aMultPars[ i ];
2307cdf0e10cSrcweir 		switch( r.getValueTypeClass() )
2308cdf0e10cSrcweir 		{
2309cdf0e10cSrcweir 			case uno::TypeClass_VOID:		break;
2310cdf0e10cSrcweir 			case uno::TypeClass_STRING:
2311cdf0e10cSrcweir 				{
2312cdf0e10cSrcweir 				const STRING*		pStr = ( const STRING* ) r.getValue();
2313cdf0e10cSrcweir 
2314cdf0e10cSrcweir 				if( pStr->getLength() )
2315cdf0e10cSrcweir 					Append( new Complex( *( STRING* ) r.getValue() ) );
2316cdf0e10cSrcweir 				else if( bEmpty0 )
2317cdf0e10cSrcweir 					Append( new Complex( 0.0 ) );
2318cdf0e10cSrcweir 				else if( bErrOnEmpty )
2319cdf0e10cSrcweir 					THROW_IAE;
2320cdf0e10cSrcweir 				}
2321cdf0e10cSrcweir 				break;
2322cdf0e10cSrcweir 			case uno::TypeClass_DOUBLE:
2323cdf0e10cSrcweir 				Append( new Complex( *( double* ) r.getValue(), 0.0 ) );
2324cdf0e10cSrcweir 				break;
2325cdf0e10cSrcweir 			case uno::TypeClass_SEQUENCE:
2326cdf0e10cSrcweir 				{
2327cdf0e10cSrcweir 				SEQSEQ( ANY )			aValArr;
2328cdf0e10cSrcweir 				if( r >>= aValArr )
2329cdf0e10cSrcweir 				{
2330cdf0e10cSrcweir 					sal_Int32			nE = aValArr.getLength();
2331cdf0e10cSrcweir 					const SEQ( ANY )*	pArr = aValArr.getConstArray();
2332cdf0e10cSrcweir 					for( sal_Int32 n = 0 ; n < nE ; n++ )
2333cdf0e10cSrcweir 						Append( pArr[ n ], eAH );
2334cdf0e10cSrcweir 				}
2335cdf0e10cSrcweir 				else
2336cdf0e10cSrcweir 					THROW_IAE;
2337cdf0e10cSrcweir 				}
2338cdf0e10cSrcweir 				break;
2339cdf0e10cSrcweir 			default:
2340cdf0e10cSrcweir 				THROW_IAE;
2341cdf0e10cSrcweir 		}
2342cdf0e10cSrcweir 	}
2343cdf0e10cSrcweir }
2344cdf0e10cSrcweir 
2345cdf0e10cSrcweir 
2346cdf0e10cSrcweir 
2347cdf0e10cSrcweir 
ConvertData(const sal_Char p[],double fC,ConvertDataClass e,sal_Bool bPrefSupport)2348cdf0e10cSrcweir ConvertData::ConvertData( const sal_Char p[], double fC, ConvertDataClass e, sal_Bool bPrefSupport ) : aName( p, strlen( p ), RTL_TEXTENCODING_MS_1252 )
2349cdf0e10cSrcweir {
2350cdf0e10cSrcweir 	fConst = fC;
2351cdf0e10cSrcweir 	eClass = e;
2352cdf0e10cSrcweir     bPrefixSupport = bPrefSupport;
2353cdf0e10cSrcweir }
2354cdf0e10cSrcweir 
~ConvertData()2355cdf0e10cSrcweir ConvertData::~ConvertData()
2356cdf0e10cSrcweir {
2357cdf0e10cSrcweir }
2358cdf0e10cSrcweir 
2359cdf0e10cSrcweir 
GetMatchingLevel(const STRING & rRef) const2360cdf0e10cSrcweir sal_Int16 ConvertData::GetMatchingLevel( const STRING& rRef ) const
2361cdf0e10cSrcweir {
2362cdf0e10cSrcweir     STRING aStr = rRef;
2363cdf0e10cSrcweir     sal_Int32 nLen = rRef.getLength();
2364cdf0e10cSrcweir     sal_Int32 nIndex = rRef.lastIndexOf( '^' );
2365cdf0e10cSrcweir     if( nIndex > 0 && nIndex  == ( nLen - 2 ) )
2366cdf0e10cSrcweir     {
2367cdf0e10cSrcweir         const sal_Unicode*  p = aStr.getStr();
2368cdf0e10cSrcweir         aStr = STRING( p, nLen - 2 );
2369cdf0e10cSrcweir         aStr += STRING( p[ nLen - 1 ] );
2370cdf0e10cSrcweir     }
2371cdf0e10cSrcweir     if( aName.equals( aStr ) )
2372cdf0e10cSrcweir 		return 0;
2373cdf0e10cSrcweir 	else
2374cdf0e10cSrcweir 	{
2375cdf0e10cSrcweir         const sal_Unicode*	p = aStr.getStr();
2376cdf0e10cSrcweir 
2377cdf0e10cSrcweir         nLen = aStr.getLength();
2378cdf0e10cSrcweir         bool bPref = IsPrefixSupport();
2379cdf0e10cSrcweir         bool bOneChar = (bPref && nLen > 1 && (aName == p + 1));
2380cdf0e10cSrcweir         if (bOneChar || (bPref && nLen > 2 && (aName == p + 2) &&
2381cdf0e10cSrcweir                     *p == 'd' && *(p+1) == 'a'))
2382cdf0e10cSrcweir 		{
2383cdf0e10cSrcweir 			sal_Int16		n;
2384cdf0e10cSrcweir 			switch( *p )
2385cdf0e10cSrcweir 			{
2386cdf0e10cSrcweir 				case 'y':	n = -24;	break;		// yocto
2387cdf0e10cSrcweir 				case 'z':	n = -21;	break;		// zepto
2388cdf0e10cSrcweir 				case 'a':	n = -18;	break;
2389cdf0e10cSrcweir 				case 'f':	n = -15;	break;
2390cdf0e10cSrcweir 				case 'p':	n = -12;	break;
2391cdf0e10cSrcweir 				case 'n':	n = -9;		break;
2392cdf0e10cSrcweir 				case 'u':	n = -6;		break;
2393cdf0e10cSrcweir 				case 'm':	n = -3;		break;
2394cdf0e10cSrcweir 				case 'c':	n = -2;		break;
2395cdf0e10cSrcweir                 case 'd':
2396cdf0e10cSrcweir                     {
2397cdf0e10cSrcweir                         if ( bOneChar )
2398cdf0e10cSrcweir                             n = -1;                 // deci
2399cdf0e10cSrcweir                         else
2400cdf0e10cSrcweir                             n = 1;                  // deca
2401cdf0e10cSrcweir                     }
2402cdf0e10cSrcweir                     break;
2403cdf0e10cSrcweir 				case 'e':	n = 1;		break;
2404cdf0e10cSrcweir 				case 'h':	n = 2;		break;
2405cdf0e10cSrcweir 				case 'k':	n = 3;		break;
2406cdf0e10cSrcweir 				case 'M':	n = 6;		break;
2407cdf0e10cSrcweir 				case 'G':	n = 9;		break;
2408cdf0e10cSrcweir 				case 'T':	n = 12;		break;
2409cdf0e10cSrcweir 				case 'P':	n = 15;		break;
2410cdf0e10cSrcweir 				case 'E':	n = 18;		break;
2411cdf0e10cSrcweir 				case 'Z':	n = 21;		break;		// zetta
2412cdf0e10cSrcweir 				case 'Y':	n = 24;		break;		// yotta
2413cdf0e10cSrcweir 				default:
2414cdf0e10cSrcweir 							n = INV_MATCHLEV;
2415cdf0e10cSrcweir 			}
2416cdf0e10cSrcweir 
2417cdf0e10cSrcweir // We could weed some nonsense out, ODFF doesn't say so though.
2418cdf0e10cSrcweir #if 0
2419cdf0e10cSrcweir             if (n < 0 && Class() == CDC_Information)
2420cdf0e10cSrcweir                 n = INV_MATCHLEV;   // milli-bits doesn't make sense
2421cdf0e10cSrcweir #endif
2422cdf0e10cSrcweir 
2423cdf0e10cSrcweir //! <HACK> #100616# "cm3" is not 10^-2 m^3 but 10^-6 m^3 !!! ------------------
2424cdf0e10cSrcweir             if( n != INV_MATCHLEV )
2425cdf0e10cSrcweir             {
2426cdf0e10cSrcweir                 sal_Unicode cLast = p[ aStr.getLength() - 1 ];
2427cdf0e10cSrcweir                 if( cLast == '2' )
2428cdf0e10cSrcweir                     n *= 2;
2429cdf0e10cSrcweir                 else if( cLast == '3' )
2430cdf0e10cSrcweir                     n *= 3;
2431cdf0e10cSrcweir             }
2432cdf0e10cSrcweir //! </HACK> -------------------------------------------------------------------
2433cdf0e10cSrcweir 
2434cdf0e10cSrcweir 			return n;
2435cdf0e10cSrcweir 		}
2436cdf0e10cSrcweir         else if ( nLen > 2 && ( aName == p + 2 ) && ( Class() == CDC_Information ) )
2437cdf0e10cSrcweir         {
2438cdf0e10cSrcweir             const sal_Unicode*  pStr = aStr.getStr();
2439cdf0e10cSrcweir             if ( *(pStr + 1) != 'i')
2440cdf0e10cSrcweir                 return INV_MATCHLEV;
2441cdf0e10cSrcweir             sal_Int16 n;
2442cdf0e10cSrcweir             switch( *pStr )
2443cdf0e10cSrcweir             {
2444cdf0e10cSrcweir                 case 'k':   n = 10;      break;
2445cdf0e10cSrcweir                 case 'M':   n = 20;      break;
2446cdf0e10cSrcweir                 case 'G':   n = 30;      break;
2447cdf0e10cSrcweir                 case 'T':   n = 40;      break;
2448cdf0e10cSrcweir                 case 'P':   n = 50;      break;
2449cdf0e10cSrcweir                 case 'E':   n = 60;      break;
2450cdf0e10cSrcweir                 case 'Z':   n = 70;      break;
2451cdf0e10cSrcweir                 case 'Y':   n = 80;      break;
2452cdf0e10cSrcweir                 default:
2453cdf0e10cSrcweir                             n = INV_MATCHLEV;
2454cdf0e10cSrcweir             }
2455cdf0e10cSrcweir             return n;
2456cdf0e10cSrcweir         }
2457cdf0e10cSrcweir         else
2458cdf0e10cSrcweir             return INV_MATCHLEV;
2459cdf0e10cSrcweir 	}
2460cdf0e10cSrcweir }
2461cdf0e10cSrcweir 
2462cdf0e10cSrcweir 
Convert(double f,const ConvertData & r,sal_Int16 nLevFrom,sal_Int16 nLevTo) const2463cdf0e10cSrcweir double ConvertData::Convert(
2464cdf0e10cSrcweir 	double f, const ConvertData& r, sal_Int16 nLevFrom, sal_Int16 nLevTo ) const THROWDEF_RTE_IAE
2465cdf0e10cSrcweir {
2466cdf0e10cSrcweir 	if( Class() != r.Class() )
2467cdf0e10cSrcweir 		THROW_IAE;
2468cdf0e10cSrcweir 
2469cdf0e10cSrcweir     sal_Bool bBinFromLev = ( nLevFrom > 0 && ( nLevFrom % 10 ) == 0 );
2470cdf0e10cSrcweir     sal_Bool bBinToLev   = ( nLevTo > 0 && ( nLevTo % 10 ) == 0 );
2471cdf0e10cSrcweir 
2472cdf0e10cSrcweir     if ( Class() == CDC_Information && ( bBinFromLev || bBinToLev ) )
2473cdf0e10cSrcweir     {
2474cdf0e10cSrcweir         if ( bBinFromLev && bBinToLev )
2475cdf0e10cSrcweir         {
2476cdf0e10cSrcweir             nLevFrom = sal::static_int_cast<sal_Int16>( nLevFrom - nLevTo );
2477cdf0e10cSrcweir             f *= r.fConst / fConst;
2478cdf0e10cSrcweir             if( nLevFrom )
2479cdf0e10cSrcweir                 f *= pow( 2.0, nLevFrom );
2480cdf0e10cSrcweir         }
2481cdf0e10cSrcweir         else if ( bBinFromLev )
2482cdf0e10cSrcweir             f *= ( r.fConst / fConst ) * ( pow( 2.0, nLevFrom ) / pow( 10.0, nLevTo ) );
2483cdf0e10cSrcweir         else
2484cdf0e10cSrcweir             f *= ( r.fConst / fConst ) * ( pow( 10.0, nLevFrom ) / pow( 2.0, nLevTo ) );
2485cdf0e10cSrcweir         return f;
2486cdf0e10cSrcweir     }
2487cdf0e10cSrcweir 
2488cdf0e10cSrcweir     nLevFrom = sal::static_int_cast<sal_Int16>( nLevFrom - nLevTo );    // effective level
2489cdf0e10cSrcweir 
2490cdf0e10cSrcweir 	f *= r.fConst / fConst;
2491cdf0e10cSrcweir 
2492cdf0e10cSrcweir 	if( nLevFrom )
2493cdf0e10cSrcweir 		f = ::rtl::math::pow10Exp( f, nLevFrom );
2494cdf0e10cSrcweir 
2495cdf0e10cSrcweir 	return f;
2496cdf0e10cSrcweir }
2497cdf0e10cSrcweir 
2498cdf0e10cSrcweir 
ConvertToBase(double f,sal_Int16 n) const2499cdf0e10cSrcweir double ConvertData::ConvertToBase( double f, sal_Int16 n ) const
2500cdf0e10cSrcweir {
2501cdf0e10cSrcweir 	return ::rtl::math::pow10Exp( f / fConst, n );
2502cdf0e10cSrcweir }
2503cdf0e10cSrcweir 
2504cdf0e10cSrcweir 
ConvertFromBase(double f,sal_Int16 n) const2505cdf0e10cSrcweir double ConvertData::ConvertFromBase( double f, sal_Int16 n ) const
2506cdf0e10cSrcweir {
2507cdf0e10cSrcweir 	return ::rtl::math::pow10Exp( f * fConst, -n );
2508cdf0e10cSrcweir }
2509cdf0e10cSrcweir 
2510cdf0e10cSrcweir 
2511cdf0e10cSrcweir 
~ConvertDataLinear()2512cdf0e10cSrcweir ConvertDataLinear::~ConvertDataLinear()
2513cdf0e10cSrcweir {
2514cdf0e10cSrcweir }
2515cdf0e10cSrcweir 
Convert(double f,const ConvertData & r,sal_Int16 nLevFrom,sal_Int16 nLevTo) const2516cdf0e10cSrcweir double ConvertDataLinear::Convert(
2517cdf0e10cSrcweir 	double f, const ConvertData& r, sal_Int16 nLevFrom, sal_Int16 nLevTo ) const THROWDEF_RTE_IAE
2518cdf0e10cSrcweir {
2519cdf0e10cSrcweir 	if( Class() != r.Class() )
2520cdf0e10cSrcweir 		THROW_IAE;
2521cdf0e10cSrcweir 
2522cdf0e10cSrcweir //	return ::rtl::math::round( r.ConvertFromBase( ConvertToBase( f, nLevFrom ), nLevTo ), 13 );
2523cdf0e10cSrcweir 	return r.ConvertFromBase( ConvertToBase( f, nLevFrom ), nLevTo );
2524cdf0e10cSrcweir }
2525cdf0e10cSrcweir 
2526cdf0e10cSrcweir 
ConvertToBase(double f,sal_Int16 n) const2527cdf0e10cSrcweir double ConvertDataLinear::ConvertToBase( double f, sal_Int16 n ) const
2528cdf0e10cSrcweir {
2529cdf0e10cSrcweir 	if( n )
2530cdf0e10cSrcweir         f = ::rtl::math::pow10Exp( f, n );
2531cdf0e10cSrcweir 
2532cdf0e10cSrcweir 	f /= fConst;
2533cdf0e10cSrcweir 	f -= fOffs;
2534cdf0e10cSrcweir 
2535cdf0e10cSrcweir 	return f;
2536cdf0e10cSrcweir }
2537cdf0e10cSrcweir 
2538cdf0e10cSrcweir 
ConvertFromBase(double f,sal_Int16 n) const2539cdf0e10cSrcweir double ConvertDataLinear::ConvertFromBase( double f, sal_Int16 n ) const
2540cdf0e10cSrcweir {
2541cdf0e10cSrcweir 	f += fOffs;
2542cdf0e10cSrcweir 	f *= fConst;
2543cdf0e10cSrcweir 
2544cdf0e10cSrcweir 	if( n )
2545cdf0e10cSrcweir         f = ::rtl::math::pow10Exp( f, -n );
2546cdf0e10cSrcweir 
2547cdf0e10cSrcweir 	return f;
2548cdf0e10cSrcweir }
2549cdf0e10cSrcweir 
2550cdf0e10cSrcweir 
2551cdf0e10cSrcweir 
2552cdf0e10cSrcweir 
ConvertDataList(void)2553cdf0e10cSrcweir ConvertDataList::ConvertDataList( void )
2554cdf0e10cSrcweir {
2555cdf0e10cSrcweir #define NEWD(str,unit,cl)	Append(new ConvertData(str,unit,cl))
2556cdf0e10cSrcweir #define NEWDP(str,unit,cl)	Append(new ConvertData(str,unit,cl,sal_True))
2557cdf0e10cSrcweir #define NEWL(str,unit,offs,cl)	Append(new ConvertDataLinear(str,unit,offs,cl))
2558cdf0e10cSrcweir #define NEWLP(str,unit,offs,cl)	Append(new ConvertDataLinear(str,unit,offs,cl,sal_True))
2559cdf0e10cSrcweir 
2560cdf0e10cSrcweir 	// *** are extra and not standard Excel Analysis Addin!
2561cdf0e10cSrcweir 
2562cdf0e10cSrcweir     // MASS: 1 Gram is...
2563cdf0e10cSrcweir     NEWDP( "g",         1.0000000000000000E00,  CDC_Mass ); // Gram
2564cdf0e10cSrcweir     NEWD( "sg",         6.8522050005347800E-05, CDC_Mass ); // Pieces
2565cdf0e10cSrcweir     NEWD( "lbm",        2.2046229146913400E-03, CDC_Mass ); // Pound (commercial weight)
2566cdf0e10cSrcweir     NEWDP( "u",         6.0221370000000000E23,  CDC_Mass ); // U (atomic mass)
2567cdf0e10cSrcweir     NEWD( "ozm",        3.5273971800362700E-02, CDC_Mass ); // Ounce (commercial weight)
2568cdf0e10cSrcweir     NEWD( "stone",      1.574730e-04,           CDC_Mass ); // *** Stone
2569cdf0e10cSrcweir     NEWD( "ton",        1.102311e-06,           CDC_Mass ); // *** Ton
2570cdf0e10cSrcweir     NEWD( "grain",      1.543236E01,            CDC_Mass ); // *** Grain
2571cdf0e10cSrcweir     NEWD( "pweight",    7.054792E-01,           CDC_Mass ); // *** Pennyweight
2572cdf0e10cSrcweir     NEWD( "hweight",    1.968413E-05,           CDC_Mass ); // *** Hundredweight
2573cdf0e10cSrcweir     NEWD( "shweight",   2.204623E-05,           CDC_Mass ); // *** Shorthundredweight
2574cdf0e10cSrcweir     NEWD( "brton",      9.842065E-07,           CDC_Mass ); // *** Gross Registered Ton
2575cdf0e10cSrcweir     NEWD( "cwt",        2.2046226218487758E-05, CDC_Mass ); // U.S. (short) hundredweight
2576cdf0e10cSrcweir     NEWD( "shweight",   2.2046226218487758E-05, CDC_Mass ); // U.S. (short) hundredweight also
2577cdf0e10cSrcweir     NEWD( "uk_cwt",     1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight
2578cdf0e10cSrcweir     NEWD( "lcwt",       1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight also
2579cdf0e10cSrcweir     NEWD( "hweight",    1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight also
2580cdf0e10cSrcweir     NEWD( "uk_ton",     9.8420652761106063E-07, CDC_Mass ); // Imperial ton
2581cdf0e10cSrcweir     NEWD( "LTON",       9.8420652761106063E-07, CDC_Mass ); // Imperial ton also
2582cdf0e10cSrcweir 
2583cdf0e10cSrcweir     // LENGTH: 1 Meter is...
2584cdf0e10cSrcweir     NEWDP( "m",         1.0000000000000000E00,  CDC_Length ); // Meter
2585cdf0e10cSrcweir     NEWD( "mi",         6.2137119223733397E-04, CDC_Length ); // Britsh Mile        6,21371192237333969617434184363e-4
2586cdf0e10cSrcweir     NEWD( "Nmi",        5.3995680345572354E-04, CDC_Length ); // Nautical Mile      5,39956803455723542116630669546e-4
2587cdf0e10cSrcweir     NEWD( "in",         3.9370078740157480E01,  CDC_Length ); // Inch               39,37007874015748031496062992126
2588cdf0e10cSrcweir     NEWD( "ft",         3.2808398950131234E00,  CDC_Length ); // Foot               3,2808398950131233595800524934383
2589cdf0e10cSrcweir     NEWD( "yd",         1.0936132983377078E00,  CDC_Length ); // Yard               1,0936132983377077865266841644794
2590cdf0e10cSrcweir     NEWDP( "ang",       1.0000000000000000E10,  CDC_Length ); // Angstroem
2591cdf0e10cSrcweir     NEWD( "Pica",       2.8346456692913386E03,  CDC_Length ); // Pica (1/72 Inch)   2834,6456692913385826771653543307
2592cdf0e10cSrcweir     NEWD( "ell",        8.748906E-01,           CDC_Length ); // *** Ell
2593cdf0e10cSrcweir     NEWDP( "parsec",    3.240779E-17,           CDC_Length ); // *** Parsec
2594cdf0e10cSrcweir     NEWDP( "pc",        3.240779E-17,           CDC_Length ); // *** Parsec also
2595cdf0e10cSrcweir     NEWDP( "lightyear", 1.0570234557732930E-16, CDC_Length ); // *** Light Year
2596cdf0e10cSrcweir     NEWDP( "ly",        1.0570234557732930E-16, CDC_Length ); // *** Light Year also
2597cdf0e10cSrcweir     NEWD( "survey_mi",  6.2136994949494949E-04, CDC_Length ); // U.S. survey mile
2598cdf0e10cSrcweir 
2599cdf0e10cSrcweir     // TIME: 1 Second is...
2600cdf0e10cSrcweir     NEWD( "yr",     3.1688087814028950E-08, CDC_Time ); // Year
2601cdf0e10cSrcweir     NEWD( "day",    1.1574074074074074E-05, CDC_Time ); // Day
2602cdf0e10cSrcweir     NEWD( "d",      1.1574074074074074E-05, CDC_Time ); // Day also
2603cdf0e10cSrcweir     NEWD( "hr",     2.7777777777777778E-04, CDC_Time ); // Hour
2604cdf0e10cSrcweir     NEWD( "mn",     1.6666666666666667E-02, CDC_Time ); // Minute
2605cdf0e10cSrcweir     NEWD( "min",    1.6666666666666667E-02, CDC_Time ); // Minute also
2606cdf0e10cSrcweir     NEWDP( "sec",   1.0000000000000000E00,  CDC_Time ); // Second
2607cdf0e10cSrcweir     NEWDP( "s",     1.0000000000000000E00,  CDC_Time ); // Second also
2608cdf0e10cSrcweir 
2609cdf0e10cSrcweir     // PRESSURE: 1 Pascal is...
2610cdf0e10cSrcweir     NEWDP( "Pa",    1.0000000000000000E00,  CDC_Pressure ); // Pascal
2611cdf0e10cSrcweir     NEWDP( "atm",   9.8692329999819300E-06, CDC_Pressure ); // Atmosphere
2612cdf0e10cSrcweir     NEWDP( "at",    9.8692329999819300E-06, CDC_Pressure ); // Atmosphere also
2613cdf0e10cSrcweir     NEWDP( "mmHg",  7.5006170799862700E-03, CDC_Pressure ); // mm Hg (Mercury)
2614cdf0e10cSrcweir     NEWD( "Torr",   7.5006380000000000E-03, CDC_Pressure ); // *** Torr
2615cdf0e10cSrcweir     NEWD( "psi",    1.4503770000000000E-04, CDC_Pressure ); // *** Psi
2616cdf0e10cSrcweir 
2617cdf0e10cSrcweir     // FORCE: 1 Newton is...
2618cdf0e10cSrcweir     NEWDP( "N",     1.0000000000000000E00,  CDC_Force ); // Newton
2619cdf0e10cSrcweir     NEWDP( "dyn",   1.0000000000000000E05,  CDC_Force ); // Dyn
2620cdf0e10cSrcweir     NEWDP( "dy",    1.0000000000000000E05,  CDC_Force ); // Dyn also
2621cdf0e10cSrcweir     NEWD( "lbf",    2.24808923655339E-01,   CDC_Force ); // Pound-Force
2622cdf0e10cSrcweir     NEWDP( "pond",  1.019716E02,            CDC_Force ); // *** Pond
2623cdf0e10cSrcweir 
2624cdf0e10cSrcweir     // ENERGY: 1 Joule is...
2625cdf0e10cSrcweir     NEWDP( "J",     1.0000000000000000E00,  CDC_Energy ); // Joule
2626cdf0e10cSrcweir     NEWDP( "e",     1.0000000000000000E07,  CDC_Energy ); // Erg  -> http://www.chemie.fu-berlin.de/chemistry/general/si.html
2627cdf0e10cSrcweir //  NEWD( "e",      9.99999519343231E06,    CDC_Energy ); // Erg
2628cdf0e10cSrcweir     NEWDP( "c",     2.3900624947346700E-01, CDC_Energy ); // Thermodynamical Calorie
2629cdf0e10cSrcweir     NEWDP( "cal",   2.3884619064201700E-01, CDC_Energy ); // Calorie
2630cdf0e10cSrcweir     NEWDP( "eV",    6.2414570000000000E18,  CDC_Energy ); // Electronvolt
2631cdf0e10cSrcweir     NEWDP( "ev",    6.2414570000000000E18,  CDC_Energy ); // Electronvolt also
2632cdf0e10cSrcweir     NEWD( "HPh",    3.7250611111111111E-07, CDC_Energy ); // Horsepower Hours
2633cdf0e10cSrcweir     NEWD( "hh",     3.7250611111111111E-07, CDC_Energy ); // Horsepower Hours also
2634cdf0e10cSrcweir //  NEWD( "HPh",    3.72506430801000E-07,   CDC_Energy ); // Horsepower Hours
2635cdf0e10cSrcweir     NEWDP( "Wh",    2.7777777777777778E-04, CDC_Energy ); // Watt Hours
2636cdf0e10cSrcweir     NEWDP( "wh",    2.7777777777777778E-04, CDC_Energy ); // Watt Hours also
2637cdf0e10cSrcweir     NEWD( "flb",    2.37304222192651E01,    CDC_Energy ); // Foot Pound
2638cdf0e10cSrcweir     NEWD( "BTU",    9.4781506734901500E-04, CDC_Energy ); // British Thermal Unit
2639cdf0e10cSrcweir     NEWD( "btu",    9.4781506734901500E-04, CDC_Energy ); // British Thermal Unit also
2640cdf0e10cSrcweir 
2641cdf0e10cSrcweir     // POWER: 1 Watt is...
2642cdf0e10cSrcweir     NEWDP( "W",     1.0000000000000000E00,  CDC_Power ); // Watt
2643cdf0e10cSrcweir     NEWDP( "w",     1.0000000000000000E00,  CDC_Power ); // Watt also
2644cdf0e10cSrcweir     NEWD( "HP",     1.341022E-03,           CDC_Power ); // Horsepower
2645cdf0e10cSrcweir     NEWD( "h",      1.341022E-03,           CDC_Power ); // Horsepower also
2646cdf0e10cSrcweir     NEWD( "PS",     1.359622E-03,           CDC_Power ); // *** German Pferdestaerke
2647cdf0e10cSrcweir //  NEWD( "HP",     1.4102006031908E-03,    CDC_Power ); // Excel seams to be a little bit wrong... either this doesn't fit to J -> HPh
2648cdf0e10cSrcweir 
2649cdf0e10cSrcweir     // MAGNETISM: 1 Tesla is...
2650cdf0e10cSrcweir     NEWDP( "T",     1.0000000000000000E00,  CDC_Magnetism ); // Tesla
2651cdf0e10cSrcweir     NEWDP( "ga",    1.0000000000000000E04,  CDC_Magnetism ); // Gauss
2652cdf0e10cSrcweir 
2653cdf0e10cSrcweir     // TEMERATURE: 1 Kelvin is...
2654cdf0e10cSrcweir     NEWL( "C",      1.0000000000000000E00,  -2.7315000000000000E02, CDC_Temperature ); // Celsius
2655cdf0e10cSrcweir     NEWL( "cel",    1.0000000000000000E00,  -2.7315000000000000E02, CDC_Temperature ); // Celsius also
2656cdf0e10cSrcweir     NEWL( "F",      1.8000000000000000E00,  -2.5537222222222222E02, CDC_Temperature ); // Fahrenheit
2657cdf0e10cSrcweir     NEWL( "fah",    1.8000000000000000E00,  -2.5537222222222222E02, CDC_Temperature ); // Fahrenheit also
2658cdf0e10cSrcweir     NEWLP( "K",     1.0000000000000000E00,  +0.0000000000000000E00, CDC_Temperature ); // Kelvin
2659cdf0e10cSrcweir     NEWLP( "kel",   1.0000000000000000E00,  +0.0000000000000000E00, CDC_Temperature ); // Kelvin also
2660cdf0e10cSrcweir     NEWL( "Reau",   8.0000000000000000E-01, -2.7315000000000000E02, CDC_Temperature ); // *** Reaumur
2661cdf0e10cSrcweir     NEWL( "Rank",   1.8000000000000000E00,  +0.0000000000000000E00, CDC_Temperature ); // *** Rankine
2662cdf0e10cSrcweir 
2663cdf0e10cSrcweir     // VOLUMNE: 1 Liter is...
2664cdf0e10cSrcweir     NEWD( "tsp",        2.0284000000000000E02,  CDC_Volume ); // Teaspoon
2665cdf0e10cSrcweir     NEWD( "tbs",        6.7613333333333333E01,  CDC_Volume ); // Tablespoon
2666cdf0e10cSrcweir     NEWD( "oz",         3.3806666666666667E01,  CDC_Volume ); // Ounce Liquid
2667cdf0e10cSrcweir     NEWD( "cup",        4.2258333333333333E00,  CDC_Volume ); // Cup
2668cdf0e10cSrcweir     NEWD( "pt",         2.1129166666666667E00,  CDC_Volume ); // US Pint
2669cdf0e10cSrcweir     NEWD( "us_pt",      2.1129166666666667E00,  CDC_Volume ); // US Pint also
2670cdf0e10cSrcweir     NEWD( "uk_pt",      1.75975569552166E00,    CDC_Volume ); // UK Pint
2671cdf0e10cSrcweir     NEWD( "qt",         1.0564583333333333E00,  CDC_Volume ); // Quart
2672cdf0e10cSrcweir     NEWD( "gal",        2.6411458333333333E-01, CDC_Volume ); // Gallone
2673cdf0e10cSrcweir     NEWDP( "l",         1.0000000000000000E00,  CDC_Volume ); // Liter
2674cdf0e10cSrcweir     NEWDP( "L",         1.0000000000000000E00,  CDC_Volume ); // Liter also
2675cdf0e10cSrcweir     NEWDP( "lt",        1.0000000000000000E00,  CDC_Volume ); // Liter also
2676cdf0e10cSrcweir     NEWDP( "m3",        1.0000000000000000E-03, CDC_Volume ); // *** Cubic Meter
2677cdf0e10cSrcweir     NEWD( "mi3",        2.3991275857892772E-13, CDC_Volume ); // *** Cubic Britsh Mile
2678cdf0e10cSrcweir     NEWD( "Nmi3",       1.5742621468581148E-13, CDC_Volume ); // *** Cubic Nautical Mile
2679cdf0e10cSrcweir     NEWD( "in3",        6.1023744094732284E01,  CDC_Volume ); // *** Cubic Inch
2680cdf0e10cSrcweir     NEWD( "ft3",        3.5314666721488590E-02, CDC_Volume ); // *** Cubic Foot
2681cdf0e10cSrcweir     NEWD( "yd3",        1.3079506193143922E-03, CDC_Volume ); // *** Cubic Yard
2682cdf0e10cSrcweir     NEWDP( "ang3",      1.0000000000000000E27,  CDC_Volume ); // *** Cubic Angstroem
2683cdf0e10cSrcweir     NEWD( "Pica3",      2.2776990435870636E07,  CDC_Volume ); // *** Cubic Pica
2684cdf0e10cSrcweir     NEWD( "barrel",     6.289811E-03,           CDC_Volume ); // *** Barrel (=42gal?)
2685cdf0e10cSrcweir     NEWD( "bushel",     2.837759E-02,           CDC_Volume ); // *** Bushel
2686cdf0e10cSrcweir     NEWD( "regton",     3.531467E-04,           CDC_Volume ); // *** Register ton
2687cdf0e10cSrcweir     NEWD( "GRT",        3.531467E-04,           CDC_Volume ); // *** Register ton also
2688cdf0e10cSrcweir     NEWD( "Schooner",   2.3529411764705882E00,  CDC_Volume ); // *** austr. Schooner
2689cdf0e10cSrcweir     NEWD( "Middy",      3.5087719298245614E00,  CDC_Volume ); // *** austr. Middy
2690cdf0e10cSrcweir     NEWD( "Glass",      5.0000000000000000E00,  CDC_Volume ); // *** austr. Glass
2691cdf0e10cSrcweir     NEWD( "Sixpack",    0.5,                    CDC_Volume ); // ***
2692cdf0e10cSrcweir     NEWD( "Humpen",     2.0,                    CDC_Volume ); // ***
2693cdf0e10cSrcweir     NEWD( "ly3",        1.1810108125623799E-51, CDC_Volume ); // *** Cubic light-year
2694cdf0e10cSrcweir     NEWD( "MTON",       1.4125866688595436E00,  CDC_Volume ); // *** Measurement ton
2695cdf0e10cSrcweir     NEWD( "tspm",       5.0000000000000000E02,  CDC_Volume ); // *** Modern teaspoon
2696cdf0e10cSrcweir     NEWD( "uk_gal",     2.199694619402070E-01,  CDC_Volume ); // U.K. / Imperial gallon
2697cdf0e10cSrcweir     NEWD( "uk_qt",      8.798778477608300E-01,  CDC_Volume ); // U.K. / Imperial quart
2698cdf0e10cSrcweir 
2699cdf0e10cSrcweir     // 1 Square Meter is...
2700cdf0e10cSrcweir     NEWDP( "m2",        1.0000000000000000E00,  CDC_Area ); // *** Square Meter
2701cdf0e10cSrcweir     NEWD( "mi2",        3.8610215854244585E-07, CDC_Area ); // *** Square Britsh Mile
2702cdf0e10cSrcweir     NEWD( "Nmi2",       2.9155334959812286E-07, CDC_Area ); // *** Square Nautical Mile
2703cdf0e10cSrcweir     NEWD( "in2",        1.5500031000062000E03,  CDC_Area ); // *** Square Inch
2704cdf0e10cSrcweir     NEWD( "ft2",        1.0763910416709722E01,  CDC_Area ); // *** Square Foot
2705cdf0e10cSrcweir     NEWD( "yd2",        1.1959900463010803E00,  CDC_Area ); // *** Square Yard
2706cdf0e10cSrcweir     NEWDP( "ang2",      1.0000000000000000E20,  CDC_Area ); // *** Square Angstroem
2707cdf0e10cSrcweir     NEWD( "Pica2",      8.0352160704321409E06,  CDC_Area ); // *** Square Pica
2708cdf0e10cSrcweir     NEWD( "Morgen",     4.0000000000000000E-04, CDC_Area ); // *** Morgen
2709cdf0e10cSrcweir     NEWDP( "ar",        1.000000E-02,           CDC_Area ); // *** Ar
2710cdf0e10cSrcweir     NEWD( "acre",       2.471053815E-04,        CDC_Area ); // *** Acre
2711cdf0e10cSrcweir     NEWD( "uk_acre",    2.4710538146716534E-04, CDC_Area ); // *** International acre
2712cdf0e10cSrcweir     NEWD( "us_acre",    2.4710439304662790E-04, CDC_Area ); // *** U.S. survey/statute acre
2713cdf0e10cSrcweir     NEWD( "ly2",        1.1172985860549147E-32, CDC_Area ); // *** Square Light-year
2714cdf0e10cSrcweir     NEWD( "ha",         1.000000E-04,           CDC_Area ); // *** Hectare
2715cdf0e10cSrcweir     NEWD( "Quadratlatschen",5.6689342403628117914,CDC_Area ); // ***
2716cdf0e10cSrcweir 
2717cdf0e10cSrcweir     // SPEED: 1 Meter per Second is...
2718cdf0e10cSrcweir     NEWDP( "m/s",   1.0000000000000000E00,  CDC_Speed ); // *** Meters per Second
2719cdf0e10cSrcweir     NEWDP( "m/sec", 1.0000000000000000E00,  CDC_Speed ); // *** Meters per Second also
2720cdf0e10cSrcweir     NEWDP( "m/h",   3.6000000000000000E03,  CDC_Speed ); // *** Meters per Hour
2721cdf0e10cSrcweir     NEWDP( "m/hr",  3.6000000000000000E03,  CDC_Speed ); // *** Meters per Hour also
2722cdf0e10cSrcweir     NEWD( "mph",    2.2369362920544023E00,  CDC_Speed ); // *** Britsh Miles per Hour
2723cdf0e10cSrcweir     NEWD( "kn",     1.9438444924406048E00,  CDC_Speed ); // *** Knot = Nautical Miles per Hour
2724cdf0e10cSrcweir     NEWD( "admkn",  1.9438446603753486E00,  CDC_Speed ); // *** Admiralty Knot
2725cdf0e10cSrcweir     NEWD( "wahnsinnige Geschwindigkeit", 2.0494886343432328E-14, CDC_Speed ); // ***
2726cdf0e10cSrcweir     NEWD( "ludicrous speed", 2.0494886343432328E-14, CDC_Speed ); // ***
2727cdf0e10cSrcweir     NEWD( "laecherliche Geschwindigkeit", 4.0156958471424288E-06, CDC_Speed); // ***
2728cdf0e10cSrcweir     NEWD( "ridiculous speed", 4.0156958471424288E-06, CDC_Speed); // ***
2729cdf0e10cSrcweir 
2730cdf0e10cSrcweir     // INFORMATION: 1 Bit is...
2731cdf0e10cSrcweir     NEWDP( "bit",   1.00E00,  CDC_Information); // *** Bit
2732cdf0e10cSrcweir     NEWDP( "byte",  1.25E-01, CDC_Information); // *** Byte
2733cdf0e10cSrcweir }
2734cdf0e10cSrcweir 
2735cdf0e10cSrcweir 
~ConvertDataList()2736cdf0e10cSrcweir ConvertDataList::~ConvertDataList()
2737cdf0e10cSrcweir {
2738cdf0e10cSrcweir 	for( ConvertData* p = First() ; p ; p = Next() )
2739cdf0e10cSrcweir 		delete p;
2740cdf0e10cSrcweir }
2741cdf0e10cSrcweir 
2742cdf0e10cSrcweir 
Convert(double fVal,const STRING & rFrom,const STRING & rTo)2743cdf0e10cSrcweir double ConvertDataList::Convert( double fVal, const STRING& rFrom, const STRING& rTo ) THROWDEF_RTE_IAE
2744cdf0e10cSrcweir {
2745cdf0e10cSrcweir // This will not catch illegal units
2746cdf0e10cSrcweir //   if( rFrom == rTo )
2747cdf0e10cSrcweir //       return fVal;
2748cdf0e10cSrcweir 
2749cdf0e10cSrcweir 	ConvertData*	pFrom = NULL;
2750cdf0e10cSrcweir 	ConvertData*	pTo = NULL;
2751cdf0e10cSrcweir 	sal_Bool		bSearchFrom = sal_True;
2752cdf0e10cSrcweir 	sal_Bool		bSearchTo = sal_True;
2753cdf0e10cSrcweir 	sal_Int16		nLevelFrom = 0;
2754cdf0e10cSrcweir 	sal_Int16		nLevelTo = 0;
2755cdf0e10cSrcweir 
2756cdf0e10cSrcweir 	ConvertData*	p = First();
2757cdf0e10cSrcweir 	while( p && ( bSearchFrom || bSearchTo ) )
2758cdf0e10cSrcweir 	{
2759cdf0e10cSrcweir 		if( bSearchFrom )
2760cdf0e10cSrcweir 		{
2761cdf0e10cSrcweir 			sal_Int16	n = p->GetMatchingLevel( rFrom );
2762cdf0e10cSrcweir 			if( n != INV_MATCHLEV )
2763cdf0e10cSrcweir 			{
2764cdf0e10cSrcweir 				if( n )
2765cdf0e10cSrcweir 				{	// only first match for partial equality rulz a little bit more
2766cdf0e10cSrcweir 					pFrom = p;
2767cdf0e10cSrcweir 					nLevelFrom = n;
2768cdf0e10cSrcweir 				}
2769cdf0e10cSrcweir 				else
2770cdf0e10cSrcweir 				{	// ... but exact match rulz most
2771cdf0e10cSrcweir 					pFrom = p;
2772cdf0e10cSrcweir 					bSearchFrom = sal_False;
2773cdf0e10cSrcweir 					nLevelFrom = n;
2774cdf0e10cSrcweir 				}
2775cdf0e10cSrcweir 			}
2776cdf0e10cSrcweir 		}
2777cdf0e10cSrcweir 
2778cdf0e10cSrcweir 		if( bSearchTo )
2779cdf0e10cSrcweir 		{
2780cdf0e10cSrcweir 			sal_Int16	n = p->GetMatchingLevel( rTo );
2781cdf0e10cSrcweir 			if( n != INV_MATCHLEV )
2782cdf0e10cSrcweir 			{
2783cdf0e10cSrcweir 				if( n )
2784cdf0e10cSrcweir 				{	// only first match for partial equality rulz a little bit more
2785cdf0e10cSrcweir 					pTo = p;
2786cdf0e10cSrcweir 					nLevelTo = n;
2787cdf0e10cSrcweir 				}
2788cdf0e10cSrcweir 				else
2789cdf0e10cSrcweir 				{	// ... but exact match rulz most
2790cdf0e10cSrcweir 					pTo = p;
2791cdf0e10cSrcweir 					bSearchTo = sal_False;
2792cdf0e10cSrcweir 					nLevelTo = n;
2793cdf0e10cSrcweir 				}
2794cdf0e10cSrcweir 			}
2795cdf0e10cSrcweir 		}
2796cdf0e10cSrcweir 
2797cdf0e10cSrcweir 		p = Next();
2798cdf0e10cSrcweir 	}
2799cdf0e10cSrcweir 
2800cdf0e10cSrcweir 	if( pFrom && pTo )
2801cdf0e10cSrcweir 		return pFrom->Convert( fVal, *pTo, nLevelFrom, nLevelTo );
2802cdf0e10cSrcweir 	else
2803cdf0e10cSrcweir 		THROW_IAE;
2804cdf0e10cSrcweir }
2805cdf0e10cSrcweir 
2806cdf0e10cSrcweir 
2807cdf0e10cSrcweir 
2808cdf0e10cSrcweir //-----------------------------------------------------------------------------
2809cdf0e10cSrcweir 
ScaDate()2810cdf0e10cSrcweir ScaDate::ScaDate() :
2811cdf0e10cSrcweir     nOrigDay( 1 ),
2812cdf0e10cSrcweir     nDay( 1 ),
2813cdf0e10cSrcweir     nMonth( 1 ),
2814cdf0e10cSrcweir     nYear( 1900 ),
2815cdf0e10cSrcweir     bLastDayMode( sal_True ),
2816cdf0e10cSrcweir     bLastDay( sal_False ),
2817cdf0e10cSrcweir     b30Days( sal_False ),
2818cdf0e10cSrcweir     bUSMode( sal_False )
2819cdf0e10cSrcweir {
2820cdf0e10cSrcweir }
2821cdf0e10cSrcweir 
ScaDate(sal_Int32 nNullDate,sal_Int32 nDate,sal_Int32 nBase)2822cdf0e10cSrcweir ScaDate::ScaDate( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nBase )
2823cdf0e10cSrcweir {
2824cdf0e10cSrcweir     DaysToDate( nNullDate + nDate, nOrigDay, nMonth, nYear );
2825cdf0e10cSrcweir     bLastDayMode = (nBase != 5);
2826cdf0e10cSrcweir     bLastDay = (nOrigDay >= ::DaysInMonth( nMonth, nYear ));
2827cdf0e10cSrcweir     b30Days = (nBase == 0) || (nBase == 4);
2828cdf0e10cSrcweir     bUSMode = (nBase == 0);
2829cdf0e10cSrcweir     setDay();
2830cdf0e10cSrcweir }
2831cdf0e10cSrcweir 
ScaDate(const ScaDate & rCopy)2832cdf0e10cSrcweir ScaDate::ScaDate( const ScaDate& rCopy ) :
2833cdf0e10cSrcweir     nOrigDay( rCopy.nOrigDay ),
2834cdf0e10cSrcweir     nDay( rCopy.nDay ),
2835cdf0e10cSrcweir     nMonth( rCopy.nMonth ),
2836cdf0e10cSrcweir     nYear( rCopy.nYear ),
2837cdf0e10cSrcweir     bLastDayMode( rCopy.bLastDayMode ),
2838cdf0e10cSrcweir     bLastDay( rCopy.bLastDay ),
2839cdf0e10cSrcweir     b30Days( rCopy.b30Days ),
2840cdf0e10cSrcweir     bUSMode( rCopy.bUSMode )
2841cdf0e10cSrcweir {
2842cdf0e10cSrcweir }
2843cdf0e10cSrcweir 
operator =(const ScaDate & rCopy)2844cdf0e10cSrcweir ScaDate& ScaDate::operator=( const ScaDate& rCopy )
2845cdf0e10cSrcweir {
2846cdf0e10cSrcweir     if( this != &rCopy )
2847cdf0e10cSrcweir     {
2848cdf0e10cSrcweir         nOrigDay = rCopy.nOrigDay;
2849cdf0e10cSrcweir         nDay = rCopy.nDay;
2850cdf0e10cSrcweir         nMonth = rCopy.nMonth;
2851cdf0e10cSrcweir         nYear = rCopy.nYear;
2852cdf0e10cSrcweir         bLastDayMode = rCopy.bLastDayMode;
2853cdf0e10cSrcweir         bLastDay = rCopy.bLastDay;
2854cdf0e10cSrcweir         b30Days = rCopy.b30Days;
2855cdf0e10cSrcweir         bUSMode = rCopy.bUSMode;
2856cdf0e10cSrcweir     }
2857cdf0e10cSrcweir     return *this;
2858cdf0e10cSrcweir }
2859cdf0e10cSrcweir 
setDay()2860cdf0e10cSrcweir void ScaDate::setDay()
2861cdf0e10cSrcweir {
2862cdf0e10cSrcweir     if( b30Days )
2863cdf0e10cSrcweir     {
2864cdf0e10cSrcweir         // 30-days-mode: set nDay to 30 if original was last day in month
2865cdf0e10cSrcweir         nDay = Min( nOrigDay, static_cast< sal_uInt16 >( 30 ) );
2866cdf0e10cSrcweir         if( bLastDay || (nDay >= ::DaysInMonth( nMonth, nYear )) )
2867cdf0e10cSrcweir             nDay = 30;
2868cdf0e10cSrcweir     }
2869cdf0e10cSrcweir     else
2870cdf0e10cSrcweir     {
2871cdf0e10cSrcweir         // set nDay to last day in this month if original was last day
2872cdf0e10cSrcweir         sal_uInt16 nLastDay = ::DaysInMonth( nMonth, nYear );
2873cdf0e10cSrcweir         nDay = bLastDay ? nLastDay : Min( nOrigDay, nLastDay );
2874cdf0e10cSrcweir     }
2875cdf0e10cSrcweir }
2876cdf0e10cSrcweir 
getDaysInMonthRange(sal_uInt16 nFrom,sal_uInt16 nTo) const2877cdf0e10cSrcweir sal_Int32 ScaDate::getDaysInMonthRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const
2878cdf0e10cSrcweir {
2879cdf0e10cSrcweir     if( nFrom > nTo )
2880cdf0e10cSrcweir         return 0;
2881cdf0e10cSrcweir 
2882cdf0e10cSrcweir     sal_Int32 nRet = 0;
2883cdf0e10cSrcweir     if( b30Days )
2884cdf0e10cSrcweir         nRet = (nTo - nFrom + 1) * 30;
2885cdf0e10cSrcweir     else
2886cdf0e10cSrcweir     {
2887cdf0e10cSrcweir         for( sal_uInt16 nMonthIx = nFrom; nMonthIx <= nTo; ++nMonthIx )
2888cdf0e10cSrcweir             nRet += getDaysInMonth( nMonthIx );
2889cdf0e10cSrcweir     }
2890cdf0e10cSrcweir     return nRet;
2891cdf0e10cSrcweir }
2892cdf0e10cSrcweir 
getDaysInYearRange(sal_uInt16 nFrom,sal_uInt16 nTo) const2893cdf0e10cSrcweir sal_Int32 ScaDate::getDaysInYearRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const
2894cdf0e10cSrcweir {
2895cdf0e10cSrcweir     if( nFrom > nTo )
2896cdf0e10cSrcweir         return 0;
2897cdf0e10cSrcweir 
2898cdf0e10cSrcweir     return b30Days ? ((nTo - nFrom + 1) * 360) : ::GetDaysInYears( nFrom, nTo );
2899cdf0e10cSrcweir }
2900cdf0e10cSrcweir 
doAddYears(sal_Int32 nYearCount)2901cdf0e10cSrcweir void ScaDate::doAddYears( sal_Int32 nYearCount ) throw( lang::IllegalArgumentException )
2902cdf0e10cSrcweir {
2903cdf0e10cSrcweir     sal_Int32 nNewYear = nYearCount + nYear;
2904cdf0e10cSrcweir     if( (nNewYear < 0) || (nNewYear > 0x7FFF) )
2905cdf0e10cSrcweir         throw lang::IllegalArgumentException();
2906cdf0e10cSrcweir     nYear = static_cast< sal_uInt16 >( nNewYear );
2907cdf0e10cSrcweir }
2908cdf0e10cSrcweir 
addMonths(sal_Int32 nMonthCount)2909cdf0e10cSrcweir void ScaDate::addMonths( sal_Int32 nMonthCount ) throw( lang::IllegalArgumentException )
2910cdf0e10cSrcweir {
2911cdf0e10cSrcweir     sal_Int32 nNewMonth = nMonthCount + nMonth;
2912cdf0e10cSrcweir     if( nNewMonth > 12 )
2913cdf0e10cSrcweir     {
2914cdf0e10cSrcweir         --nNewMonth;
2915cdf0e10cSrcweir         doAddYears( nNewMonth / 12 );
2916cdf0e10cSrcweir         nMonth = static_cast< sal_uInt16 >( nNewMonth % 12 ) + 1;
2917cdf0e10cSrcweir     }
2918cdf0e10cSrcweir     else if( nNewMonth < 1 )
2919cdf0e10cSrcweir     {
2920cdf0e10cSrcweir         doAddYears( nNewMonth / 12 - 1 );
2921cdf0e10cSrcweir         nMonth = static_cast< sal_uInt16 >( nNewMonth % 12 + 12 );
2922cdf0e10cSrcweir     }
2923cdf0e10cSrcweir     else
2924cdf0e10cSrcweir         nMonth = static_cast< sal_uInt16 >( nNewMonth );
2925cdf0e10cSrcweir     setDay();
2926cdf0e10cSrcweir }
2927cdf0e10cSrcweir 
getDate(sal_Int32 nNullDate) const2928cdf0e10cSrcweir sal_Int32 ScaDate::getDate( sal_Int32 nNullDate ) const
2929cdf0e10cSrcweir {
2930cdf0e10cSrcweir     sal_uInt16 nLastDay = ::DaysInMonth( nMonth, nYear );
2931cdf0e10cSrcweir     sal_uInt16 nRealDay = (bLastDayMode && bLastDay) ? nLastDay : Min( nLastDay, nOrigDay );
2932cdf0e10cSrcweir     return ::DateToDays( nRealDay, nMonth, nYear ) - nNullDate;
2933cdf0e10cSrcweir }
2934cdf0e10cSrcweir 
getDiff(const ScaDate & rFrom,const ScaDate & rTo)2935cdf0e10cSrcweir sal_Int32 ScaDate::getDiff( const ScaDate& rFrom, const ScaDate& rTo ) throw( lang::IllegalArgumentException )
2936cdf0e10cSrcweir {
2937cdf0e10cSrcweir     if( rFrom > rTo )
2938cdf0e10cSrcweir         return getDiff( rTo, rFrom );
2939cdf0e10cSrcweir 
2940cdf0e10cSrcweir     sal_Int32 nDiff = 0;
2941cdf0e10cSrcweir     ScaDate aFrom( rFrom );
2942cdf0e10cSrcweir     ScaDate aTo( rTo );
2943cdf0e10cSrcweir 
2944cdf0e10cSrcweir     if( rTo.b30Days )
2945cdf0e10cSrcweir     {
2946cdf0e10cSrcweir         // corrections for base 0 (US NASD)
2947cdf0e10cSrcweir         if( rTo.bUSMode )
2948cdf0e10cSrcweir         {
2949cdf0e10cSrcweir             if( ((rFrom.nMonth == 2) || (rFrom.nDay < 30)) && (aTo.nOrigDay == 31) )
2950cdf0e10cSrcweir                 aTo.nDay = 31;
2951cdf0e10cSrcweir             else if( (aTo.nMonth == 2) && aTo.bLastDay )
2952cdf0e10cSrcweir                 aTo.nDay = ::DaysInMonth( 2, aTo.nYear );
2953cdf0e10cSrcweir         }
2954cdf0e10cSrcweir         // corrections for base 4 (Europe)
2955cdf0e10cSrcweir         else
2956cdf0e10cSrcweir         {
2957cdf0e10cSrcweir             if( (aFrom.nMonth == 2) && (aFrom.nDay == 30) )
2958cdf0e10cSrcweir                 aFrom.nDay = ::DaysInMonth( 2, aFrom.nYear );
2959cdf0e10cSrcweir             if( (aTo.nMonth == 2) && (aTo.nDay == 30) )
2960cdf0e10cSrcweir                 aTo.nDay = ::DaysInMonth( 2, aTo.nYear );
2961cdf0e10cSrcweir         }
2962cdf0e10cSrcweir     }
2963cdf0e10cSrcweir 
2964cdf0e10cSrcweir     if( (aFrom.nYear < aTo.nYear) || ((aFrom.nYear == aTo.nYear) && (aFrom.nMonth < aTo.nMonth)) )
2965cdf0e10cSrcweir     {
2966cdf0e10cSrcweir         // move aFrom to 1st day of next month
2967cdf0e10cSrcweir         nDiff = aFrom.getDaysInMonth() - aFrom.nDay + 1;
2968cdf0e10cSrcweir         aFrom.nOrigDay = aFrom.nDay = 1;
2969cdf0e10cSrcweir         aFrom.bLastDay = sal_False;
2970cdf0e10cSrcweir         aFrom.addMonths( 1 );
2971cdf0e10cSrcweir 
2972cdf0e10cSrcweir         if( aFrom.nYear < aTo.nYear )
2973cdf0e10cSrcweir         {
2974cdf0e10cSrcweir             // move aFrom to 1st day of next year
2975cdf0e10cSrcweir             nDiff += aFrom.getDaysInMonthRange( aFrom.nMonth, 12 );
2976cdf0e10cSrcweir             aFrom.addMonths( 13 - aFrom.nMonth );
2977cdf0e10cSrcweir 
2978cdf0e10cSrcweir             // move aFrom to 1st day of this year
2979cdf0e10cSrcweir             nDiff += aFrom.getDaysInYearRange( aFrom.nYear, aTo.nYear - 1 );
2980cdf0e10cSrcweir             aFrom.addYears( aTo.nYear - aFrom.nYear );
2981cdf0e10cSrcweir         }
2982cdf0e10cSrcweir 
2983cdf0e10cSrcweir         // move aFrom to 1st day of this month
2984cdf0e10cSrcweir         nDiff += aFrom.getDaysInMonthRange( aFrom.nMonth, aTo.nMonth - 1 );
2985cdf0e10cSrcweir         aFrom.addMonths( aTo.nMonth - aFrom.nMonth );
2986cdf0e10cSrcweir     }
2987cdf0e10cSrcweir     // finally add remaining days in this month
2988cdf0e10cSrcweir     nDiff += aTo.nDay - aFrom.nDay;
2989cdf0e10cSrcweir     return nDiff > 0 ? nDiff : 0;
2990cdf0e10cSrcweir }
2991cdf0e10cSrcweir 
operator <(const ScaDate & rCmp) const2992cdf0e10cSrcweir sal_Bool ScaDate::operator<( const ScaDate& rCmp ) const
2993cdf0e10cSrcweir {
2994cdf0e10cSrcweir     if( nYear != rCmp.nYear )
2995cdf0e10cSrcweir         return nYear < rCmp.nYear;
2996cdf0e10cSrcweir     if( nMonth != rCmp.nMonth )
2997cdf0e10cSrcweir         return nMonth < rCmp.nMonth;
2998cdf0e10cSrcweir     if( nDay != rCmp.nDay )
2999cdf0e10cSrcweir         return nDay < rCmp.nDay;
3000cdf0e10cSrcweir     if( bLastDay || rCmp.bLastDay )
3001cdf0e10cSrcweir         return !bLastDay && rCmp.bLastDay;
3002cdf0e10cSrcweir     return nOrigDay < rCmp.nOrigDay;
3003cdf0e10cSrcweir }
3004cdf0e10cSrcweir 
3005cdf0e10cSrcweir 
3006cdf0e10cSrcweir 
3007cdf0e10cSrcweir //-----------------------------------------------------------------------------
3008cdf0e10cSrcweir 
ScaAnyConverter(const uno::Reference<lang::XMultiServiceFactory> & xServiceFact)3009cdf0e10cSrcweir ScaAnyConverter::ScaAnyConverter( const uno::Reference< lang::XMultiServiceFactory >& xServiceFact ) :
3010cdf0e10cSrcweir     bHasValidFormat( sal_False )
3011cdf0e10cSrcweir {
3012cdf0e10cSrcweir     if( xServiceFact.is() )
3013cdf0e10cSrcweir     {
3014cdf0e10cSrcweir         uno::Reference< uno::XInterface > xInstance = xServiceFact->createInstance(
3015cdf0e10cSrcweir             OUString::createFromAscii( "com.sun.star.util.NumberFormatter" ) );
3016cdf0e10cSrcweir         xFormatter = uno::Reference< util::XNumberFormatter >( xInstance, uno::UNO_QUERY );
3017cdf0e10cSrcweir     }
3018cdf0e10cSrcweir }
3019cdf0e10cSrcweir 
~ScaAnyConverter()3020cdf0e10cSrcweir ScaAnyConverter::~ScaAnyConverter()
3021cdf0e10cSrcweir {
3022cdf0e10cSrcweir }
3023cdf0e10cSrcweir 
init(const uno::Reference<beans::XPropertySet> & xPropSet)3024cdf0e10cSrcweir void ScaAnyConverter::init( const uno::Reference< beans::XPropertySet >& xPropSet ) throw( uno::RuntimeException )
3025cdf0e10cSrcweir {
3026cdf0e10cSrcweir     // try to get default number format
3027cdf0e10cSrcweir     bHasValidFormat = sal_False;
3028cdf0e10cSrcweir     if( xFormatter.is() )
3029cdf0e10cSrcweir     {
3030cdf0e10cSrcweir         // get XFormatsSupplier from outer XPropertySet
3031cdf0e10cSrcweir         uno::Reference< util::XNumberFormatsSupplier > xFormatsSupp( xPropSet, uno::UNO_QUERY );
3032cdf0e10cSrcweir         if( xFormatsSupp.is() )
3033cdf0e10cSrcweir         {
3034cdf0e10cSrcweir             // get XNumberFormatTypes from XNumberFormatsSupplier to get standard index
3035cdf0e10cSrcweir             uno::Reference< util::XNumberFormats > xFormats( xFormatsSupp->getNumberFormats() );
3036cdf0e10cSrcweir             uno::Reference< util::XNumberFormatTypes > xFormatTypes( xFormats, uno::UNO_QUERY );
3037cdf0e10cSrcweir             if( xFormatTypes.is() )
3038cdf0e10cSrcweir             {
3039cdf0e10cSrcweir                 lang::Locale eLocale;
3040cdf0e10cSrcweir                 nDefaultFormat = xFormatTypes->getStandardIndex( eLocale );
3041cdf0e10cSrcweir                 xFormatter->attachNumberFormatsSupplier( xFormatsSupp );
3042cdf0e10cSrcweir                 bHasValidFormat = sal_True;
3043cdf0e10cSrcweir             }
3044cdf0e10cSrcweir         }
3045cdf0e10cSrcweir     }
3046cdf0e10cSrcweir }
3047cdf0e10cSrcweir 
convertToDouble(const OUString & rString) const3048cdf0e10cSrcweir double ScaAnyConverter::convertToDouble( const OUString& rString ) const throw( lang::IllegalArgumentException )
3049cdf0e10cSrcweir {
3050cdf0e10cSrcweir     double fValue = 0.0;
3051cdf0e10cSrcweir     if( bHasValidFormat )
3052cdf0e10cSrcweir     {
3053cdf0e10cSrcweir         try
3054cdf0e10cSrcweir         {
3055cdf0e10cSrcweir             fValue = xFormatter->convertStringToNumber( nDefaultFormat, rString );
3056cdf0e10cSrcweir         }
3057cdf0e10cSrcweir         catch( uno::Exception& )
3058cdf0e10cSrcweir         {
3059cdf0e10cSrcweir             throw lang::IllegalArgumentException();
3060cdf0e10cSrcweir         }
3061cdf0e10cSrcweir     }
3062cdf0e10cSrcweir     else
3063cdf0e10cSrcweir     {
3064cdf0e10cSrcweir         rtl_math_ConversionStatus eStatus;
3065cdf0e10cSrcweir         sal_Int32 nEnd;
3066cdf0e10cSrcweir         fValue = ::rtl::math::stringToDouble( rString, '.', ',', &eStatus, &nEnd );
3067cdf0e10cSrcweir         if( (eStatus != rtl_math_ConversionStatus_Ok) || (nEnd < rString.getLength()) )
3068cdf0e10cSrcweir             throw lang::IllegalArgumentException();
3069cdf0e10cSrcweir     }
3070cdf0e10cSrcweir     return fValue;
3071cdf0e10cSrcweir }
3072cdf0e10cSrcweir 
getDouble(double & rfResult,const uno::Any & rAny) const3073cdf0e10cSrcweir sal_Bool ScaAnyConverter::getDouble(
3074cdf0e10cSrcweir         double& rfResult,
3075cdf0e10cSrcweir         const uno::Any& rAny ) const throw( lang::IllegalArgumentException )
3076cdf0e10cSrcweir {
3077cdf0e10cSrcweir     rfResult = 0.0;
3078cdf0e10cSrcweir     sal_Bool bContainsVal = sal_True;
3079cdf0e10cSrcweir     switch( rAny.getValueTypeClass() )
3080cdf0e10cSrcweir     {
3081cdf0e10cSrcweir         case uno::TypeClass_VOID:
3082cdf0e10cSrcweir             bContainsVal = sal_False;
3083cdf0e10cSrcweir         break;
3084cdf0e10cSrcweir         case uno::TypeClass_DOUBLE:
3085cdf0e10cSrcweir             rAny >>= rfResult;
3086cdf0e10cSrcweir         break;
3087cdf0e10cSrcweir         case uno::TypeClass_STRING:
3088cdf0e10cSrcweir         {
3089cdf0e10cSrcweir             const OUString* pString = static_cast< const OUString* >( rAny.getValue() );
3090cdf0e10cSrcweir             if( pString->getLength() )
3091cdf0e10cSrcweir                 rfResult = convertToDouble( *pString );
3092cdf0e10cSrcweir             else
3093cdf0e10cSrcweir                 bContainsVal = sal_False;
3094cdf0e10cSrcweir         }
3095cdf0e10cSrcweir         break;
3096cdf0e10cSrcweir         default:
3097cdf0e10cSrcweir             throw lang::IllegalArgumentException();
3098cdf0e10cSrcweir     }
3099cdf0e10cSrcweir     return bContainsVal;
3100cdf0e10cSrcweir }
3101cdf0e10cSrcweir 
getDouble(double & rfResult,const uno::Reference<beans::XPropertySet> & xPropSet,const uno::Any & rAny)3102cdf0e10cSrcweir sal_Bool ScaAnyConverter::getDouble(
3103cdf0e10cSrcweir         double& rfResult,
3104cdf0e10cSrcweir         const uno::Reference< beans::XPropertySet >& xPropSet,
3105cdf0e10cSrcweir         const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
3106cdf0e10cSrcweir {
3107cdf0e10cSrcweir     init( xPropSet );
3108cdf0e10cSrcweir     return getDouble( rfResult, rAny );
3109cdf0e10cSrcweir }
3110cdf0e10cSrcweir 
getDouble(const uno::Reference<beans::XPropertySet> & xPropSet,const uno::Any & rAny,double fDefault)3111cdf0e10cSrcweir double ScaAnyConverter::getDouble(
3112cdf0e10cSrcweir         const uno::Reference< beans::XPropertySet >& xPropSet,
3113cdf0e10cSrcweir         const uno::Any& rAny,
3114cdf0e10cSrcweir         double fDefault ) throw( uno::RuntimeException, lang::IllegalArgumentException )
3115cdf0e10cSrcweir {
3116cdf0e10cSrcweir     double fResult;
3117cdf0e10cSrcweir     if( !getDouble( fResult, xPropSet, rAny ) )
3118cdf0e10cSrcweir         fResult = fDefault;
3119cdf0e10cSrcweir     return fResult;
3120cdf0e10cSrcweir }
3121cdf0e10cSrcweir 
getInt32(sal_Int32 & rnResult,const uno::Reference<beans::XPropertySet> & xPropSet,const uno::Any & rAny)3122cdf0e10cSrcweir sal_Bool ScaAnyConverter::getInt32(
3123cdf0e10cSrcweir         sal_Int32& rnResult,
3124cdf0e10cSrcweir         const uno::Reference< beans::XPropertySet >& xPropSet,
3125cdf0e10cSrcweir         const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
3126cdf0e10cSrcweir {
3127cdf0e10cSrcweir     double fResult;
3128cdf0e10cSrcweir     sal_Bool bContainsVal = getDouble( fResult, xPropSet, rAny );
3129cdf0e10cSrcweir     if( (fResult <= -2147483649.0) || (fResult >= 2147483648.0) )
3130cdf0e10cSrcweir         throw lang::IllegalArgumentException();
3131cdf0e10cSrcweir 
3132cdf0e10cSrcweir     rnResult = static_cast< sal_Int32 >( fResult );
3133cdf0e10cSrcweir     return bContainsVal;
3134cdf0e10cSrcweir }
3135cdf0e10cSrcweir 
getInt32(const uno::Reference<beans::XPropertySet> & xPropSet,const uno::Any & rAny,sal_Int32 nDefault)3136cdf0e10cSrcweir sal_Int32 ScaAnyConverter::getInt32(
3137cdf0e10cSrcweir         const uno::Reference< beans::XPropertySet >& xPropSet,
3138cdf0e10cSrcweir         const uno::Any& rAny,
3139cdf0e10cSrcweir         sal_Int32 nDefault ) throw( uno::RuntimeException, lang::IllegalArgumentException )
3140cdf0e10cSrcweir {
3141cdf0e10cSrcweir     sal_Int32 nResult;
3142cdf0e10cSrcweir     if( !getInt32( nResult, xPropSet, rAny ) )
3143cdf0e10cSrcweir         nResult = nDefault;
3144cdf0e10cSrcweir     return nResult;
3145cdf0e10cSrcweir }
3146cdf0e10cSrcweir 
3147cdf0e10cSrcweir 
3148cdf0e10cSrcweir 
3149cdf0e10cSrcweir //-----------------------------------------------------------------------------
3150cdf0e10cSrcweir 
3151cdf0e10cSrcweir 
3152