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