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