1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/util/XNumberFormatTypes.hpp>
33 #include <tools/resary.hxx>
34 #include <rtl/math.hxx>
35 #include <sal/macros.h>
36 #include "analysishelper.hxx"
37 #include "analysis.hrc"
39 using namespace ::rtl
;
40 using namespace ::com::sun::star
;
44 #define UNIQUE sal_False // function name does not exist in Calc
45 #define DOUBLE sal_True // function name exists in Calc
47 #define STDPAR sal_False // all parameters are described
48 #define INTPAR sal_True // first parameter is internal
50 #define FUNCDATA( FUNCNAME, DBL, OPT, NUMOFPAR, CAT ) \
51 { "get" #FUNCNAME, ANALYSIS_FUNCNAME_##FUNCNAME, ANALYSIS_##FUNCNAME, DBL, OPT, ANALYSIS_DEFFUNCNAME_##FUNCNAME, NUMOFPAR, CAT }
53 const FuncDataBase pFuncDatas
[] =
55 // UNIQUE or INTPAR or
56 // function name DOUBLE STDPAR # of param category
57 FUNCDATA( Workday
, UNIQUE
, INTPAR
, 3, FDCat_DateTime
),
58 FUNCDATA( Yearfrac
, UNIQUE
, INTPAR
, 3, FDCat_DateTime
),
59 FUNCDATA( Edate
, UNIQUE
, INTPAR
, 2, FDCat_DateTime
),
60 FUNCDATA( Weeknum
, DOUBLE
, INTPAR
, 2, FDCat_DateTime
),
61 FUNCDATA( Eomonth
, UNIQUE
, INTPAR
, 2, FDCat_DateTime
),
62 FUNCDATA( Networkdays
, UNIQUE
, INTPAR
, 3, FDCat_DateTime
),
63 FUNCDATA( Iseven
, DOUBLE
, STDPAR
, 1, FDCat_Inf
),
64 FUNCDATA( Isodd
, DOUBLE
, STDPAR
, 1, FDCat_Inf
),
65 FUNCDATA( Multinomial
, UNIQUE
, STDPAR
, 1, FDCat_Math
),
66 FUNCDATA( Seriessum
, UNIQUE
, STDPAR
, 4, FDCat_Math
),
67 FUNCDATA( Quotient
, UNIQUE
, STDPAR
, 2, FDCat_Math
),
68 FUNCDATA( Mround
, UNIQUE
, STDPAR
, 2, FDCat_Math
),
69 FUNCDATA( Sqrtpi
, UNIQUE
, STDPAR
, 1, FDCat_Math
),
70 FUNCDATA( Randbetween
, UNIQUE
, STDPAR
, 2, FDCat_Math
),
71 FUNCDATA( Gcd
, DOUBLE
, INTPAR
, 1, FDCat_Math
),
72 FUNCDATA( Lcm
, DOUBLE
, INTPAR
, 1, FDCat_Math
),
73 FUNCDATA( Besseli
, UNIQUE
, STDPAR
, 2, FDCat_Tech
),
74 FUNCDATA( Besselj
, UNIQUE
, STDPAR
, 2, FDCat_Tech
),
75 FUNCDATA( Besselk
, UNIQUE
, STDPAR
, 2, FDCat_Tech
),
76 FUNCDATA( Bessely
, UNIQUE
, STDPAR
, 2, FDCat_Tech
),
77 FUNCDATA( Bin2Oct
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
78 FUNCDATA( Bin2Dec
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
79 FUNCDATA( Bin2Hex
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
80 FUNCDATA( Oct2Bin
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
81 FUNCDATA( Oct2Dec
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
82 FUNCDATA( Oct2Hex
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
83 FUNCDATA( Dec2Bin
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
84 FUNCDATA( Dec2Hex
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
85 FUNCDATA( Dec2Oct
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
86 FUNCDATA( Hex2Bin
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
87 FUNCDATA( Hex2Dec
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
88 FUNCDATA( Hex2Oct
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
89 FUNCDATA( Delta
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
90 FUNCDATA( Erf
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
91 FUNCDATA( Erfc
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
92 FUNCDATA( Gestep
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
93 FUNCDATA( Factdouble
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
94 FUNCDATA( Imabs
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
95 FUNCDATA( Imaginary
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
96 FUNCDATA( Impower
, UNIQUE
, STDPAR
, 2, FDCat_Tech
),
97 FUNCDATA( Imargument
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
98 FUNCDATA( Imcos
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
99 FUNCDATA( Imdiv
, UNIQUE
, STDPAR
, 2, FDCat_Tech
),
100 FUNCDATA( Imexp
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
101 FUNCDATA( Imconjugate
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
102 FUNCDATA( Imln
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
103 FUNCDATA( Imlog10
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
104 FUNCDATA( Imlog2
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
105 FUNCDATA( Improduct
, UNIQUE
, INTPAR
, 2, FDCat_Tech
),
106 FUNCDATA( Imreal
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
107 FUNCDATA( Imsin
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
108 FUNCDATA( Imsub
, UNIQUE
, STDPAR
, 2, FDCat_Tech
),
109 FUNCDATA( Imsqrt
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
110 FUNCDATA( Imsum
, UNIQUE
, INTPAR
, 1, FDCat_Tech
),
111 FUNCDATA( Imtan
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
112 FUNCDATA( Imsec
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
113 FUNCDATA( Imcsc
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
114 FUNCDATA( Imcot
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
115 FUNCDATA( Imsinh
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
116 FUNCDATA( Imcosh
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
117 FUNCDATA( Imsech
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
118 FUNCDATA( Imcsch
, UNIQUE
, STDPAR
, 1, FDCat_Tech
),
119 FUNCDATA( Complex
, UNIQUE
, STDPAR
, 3, FDCat_Tech
),
120 FUNCDATA( Convert
, DOUBLE
, STDPAR
, 3, FDCat_Tech
),
121 FUNCDATA( Amordegrc
, UNIQUE
, INTPAR
, 7, FDCat_Finance
),
122 FUNCDATA( Amorlinc
, UNIQUE
, INTPAR
, 7, FDCat_Finance
),
123 FUNCDATA( Accrint
, UNIQUE
, INTPAR
, 7, FDCat_Finance
),
124 FUNCDATA( Accrintm
, UNIQUE
, INTPAR
, 5, FDCat_Finance
),
125 FUNCDATA( Received
, UNIQUE
, INTPAR
, 5, FDCat_Finance
),
126 FUNCDATA( Disc
, UNIQUE
, INTPAR
, 5, FDCat_Finance
),
127 FUNCDATA( Duration
, DOUBLE
, INTPAR
, 6, FDCat_Finance
),
128 FUNCDATA( Effect
, DOUBLE
, STDPAR
, 2, FDCat_Finance
),
129 FUNCDATA( Cumprinc
, DOUBLE
, STDPAR
, 6, FDCat_Finance
),
130 FUNCDATA( Cumipmt
, DOUBLE
, STDPAR
, 6, FDCat_Finance
),
131 FUNCDATA( Price
, UNIQUE
, INTPAR
, 7, FDCat_Finance
),
132 FUNCDATA( Pricedisc
, UNIQUE
, INTPAR
, 5, FDCat_Finance
),
133 FUNCDATA( Pricemat
, UNIQUE
, INTPAR
, 6, FDCat_Finance
),
134 FUNCDATA( Mduration
, UNIQUE
, INTPAR
, 6, FDCat_Finance
),
135 FUNCDATA( Nominal
, DOUBLE
, STDPAR
, 2, FDCat_Finance
),
136 FUNCDATA( Dollarfr
, UNIQUE
, STDPAR
, 2, FDCat_Finance
),
137 FUNCDATA( Dollarde
, UNIQUE
, STDPAR
, 2, FDCat_Finance
),
138 FUNCDATA( Yield
, UNIQUE
, INTPAR
, 7, FDCat_Finance
),
139 FUNCDATA( Yielddisc
, UNIQUE
, INTPAR
, 5, FDCat_Finance
),
140 FUNCDATA( Yieldmat
, UNIQUE
, INTPAR
, 6, FDCat_Finance
),
141 FUNCDATA( Tbilleq
, UNIQUE
, INTPAR
, 3, FDCat_Finance
),
142 FUNCDATA( Tbillprice
, UNIQUE
, INTPAR
, 3, FDCat_Finance
),
143 FUNCDATA( Tbillyield
, UNIQUE
, INTPAR
, 3, FDCat_Finance
),
144 FUNCDATA( Oddfprice
, UNIQUE
, INTPAR
, 9, FDCat_Finance
),
145 FUNCDATA( Oddfyield
, UNIQUE
, INTPAR
, 9, FDCat_Finance
),
146 FUNCDATA( Oddlprice
, UNIQUE
, INTPAR
, 8, FDCat_Finance
),
147 FUNCDATA( Oddlyield
, UNIQUE
, INTPAR
, 8, FDCat_Finance
),
148 FUNCDATA( Xirr
, UNIQUE
, INTPAR
, 3, FDCat_Finance
),
149 FUNCDATA( Xnpv
, UNIQUE
, STDPAR
, 3, FDCat_Finance
),
150 FUNCDATA( Intrate
, UNIQUE
, INTPAR
, 5, FDCat_Finance
),
151 FUNCDATA( Coupncd
, UNIQUE
, INTPAR
, 4, FDCat_Finance
),
152 FUNCDATA( Coupdays
, UNIQUE
, INTPAR
, 4, FDCat_Finance
),
153 FUNCDATA( Coupdaysnc
, UNIQUE
, INTPAR
, 4, FDCat_Finance
),
154 FUNCDATA( Coupdaybs
, UNIQUE
, INTPAR
, 4, FDCat_Finance
),
155 FUNCDATA( Couppcd
, UNIQUE
, INTPAR
, 4, FDCat_Finance
),
156 FUNCDATA( Coupnum
, UNIQUE
, INTPAR
, 4, FDCat_Finance
),
157 FUNCDATA( Fvschedule
, UNIQUE
, STDPAR
, 2, FDCat_Finance
)
162 sal_uInt16
DaysInMonth( sal_uInt16 nMonth
, sal_uInt16 nYear
)
164 if( (nMonth
== 2) && IsLeapYear( nYear
) )
166 static const sal_uInt16 aDaysInMonth
[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
167 return aDaysInMonth
[ nMonth
];
172 * Convert a date to a count of days starting from 01/01/0001
174 * The internal representation of a Date used in this Addin
175 * is the number of days between 01/01/0001 and the date
176 * this function converts a Day , Month, Year representation
177 * to this internal Date value.
181 sal_Int32
DateToDays( sal_uInt16 nDay
, sal_uInt16 nMonth
, sal_uInt16 nYear
)
183 sal_Int32 nDays
= ((sal_Int32
)nYear
-1) * 365;
184 nDays
+= ((nYear
-1) / 4) - ((nYear
-1) / 100) + ((nYear
-1) / 400);
186 for( sal_uInt16 i
= 1; i
< nMonth
; i
++ )
187 nDays
+= DaysInMonth(i
,nYear
);
195 * Convert a count of days starting from 01/01/0001 to a date
197 * The internal representation of a Date used in this Addin
198 * is the number of days between 01/01/0001 and the date
199 * this function converts this internal Date value
200 * to a Day , Month, Year representation of a Date.
204 void DaysToDate( sal_Int32 nDays
, sal_uInt16
& rDay
, sal_uInt16
& rMonth
, sal_uInt16
& rYear
)
205 throw( lang::IllegalArgumentException
)
208 throw lang::IllegalArgumentException();
217 rYear
= (sal_uInt16
)((nTempDays
/ 365) - i
);
218 nTempDays
-= ((sal_Int32
) rYear
-1) * 365;
219 nTempDays
-= (( rYear
-1) / 4) - (( rYear
-1) / 100) + ((rYear
-1) / 400);
228 if ( nTempDays
> 365 )
230 if ( (nTempDays
!= 366) || !IsLeapYear( rYear
) )
241 while ( (sal_Int32
)nTempDays
> DaysInMonth( rMonth
, rYear
) )
243 nTempDays
-= DaysInMonth( rMonth
, rYear
);
246 rDay
= (sal_uInt16
)nTempDays
;
251 * Get the null date used by the spreadsheet document
253 * The internal representation of a Date used in this Addin
254 * is the number of days between 01/01/0001 and the date
255 * this function returns this internal Date value for the document null date
259 sal_Int32
GetNullDate( constREFXPS
& xOpt
) THROWDEF_RTE
265 ANY aAny
= xOpt
->getPropertyValue( STRFROMASCII( "NullDate" ) );
268 return DateToDays( aDate
.Day
, aDate
.Month
, aDate
.Year
);
270 catch( uno::Exception
& )
275 // no null date available -> no calculations possible
276 throw uno::RuntimeException();
280 sal_Int32
GetDiffDate360(
281 sal_uInt16 nDay1
, sal_uInt16 nMonth1
, sal_uInt16 nYear1
, sal_Bool bLeapYear1
,
282 sal_uInt16 nDay2
, sal_uInt16 nMonth2
, sal_uInt16 nYear2
,
283 sal_Bool bUSAMethod
)
287 else if( bUSAMethod
&& ( nMonth1
== 2 && ( nDay1
== 29 || ( nDay1
== 28 && !bLeapYear1
) ) ) )
292 if( bUSAMethod
&& nDay1
!= 30 )
307 return nDay2
+ nMonth2
* 30 + nYear2
* 360 - nDay1
- nMonth1
* 30 - nYear1
* 360;
311 sal_Int32
GetDiffDate360( sal_Int32 nNullDate
, sal_Int32 nDate1
, sal_Int32 nDate2
, sal_Bool bUSAMethod
)
316 sal_uInt16 nDay1
, nMonth1
, nYear1
, nDay2
, nMonth2
, nYear2
;
318 DaysToDate( nDate1
, nDay1
, nMonth1
, nYear1
);
319 DaysToDate( nDate2
, nDay2
, nMonth2
, nYear2
);
321 return GetDiffDate360( nDay1
, nMonth1
, nYear1
, IsLeapYear( nYear1
), nDay2
, nMonth2
, nYear2
, bUSAMethod
);
325 sal_Int32
GetDaysInYears( sal_uInt16 nYear1
, sal_uInt16 nYear2
)
327 sal_uInt16 nLeaps
= 0;
328 for( sal_uInt16 n
= nYear1
; n
<= nYear2
; n
++ )
330 if( IsLeapYear( n
) )
344 void GetDiffParam( sal_Int32 nNullDate
, sal_Int32 nStartDate
, sal_Int32 nEndDate
, sal_Int32 nMode
,
345 sal_uInt16
& rYears
, sal_Int32
& rDayDiffPart
, sal_Int32
& rDaysInYear
) THROWDEF_RTE_IAE
347 if( nStartDate
> nEndDate
)
349 sal_Int32 n
= nEndDate
;
350 nEndDate
= nStartDate
;
354 sal_Int32 nDate1
= nStartDate
+ nNullDate
;
355 sal_Int32 nDate2
= nEndDate
+ nNullDate
;
357 sal_uInt16 nDay1
, nDay2
;
358 sal_uInt16 nMonth1
, nMonth2
;
359 sal_uInt16 nYear1
, nYear2
;
361 DaysToDate( nDate1
, nDay1
, nMonth1
, nYear1
);
362 DaysToDate( nDate2
, nDay2
, nMonth2
, nYear2
);
366 sal_Int32 nDayDiff
, nDaysInYear
;
370 case 0: // 0=USA (NASD) 30/360
371 case 4: // 4=Europe 30/360
373 nYears
= nYear2
- nYear1
;
374 nDayDiff
= GetDiffDate360( nDay1
, nMonth1
, nYear1
, IsLeapYear( nYear1
),
375 nDay2
, nMonth2
, nYear2
, nMode
== 0 ) - nYears
* nDaysInYear
;
377 case 1: // 1=exact/exact
378 nYears
= nYear2
- nYear1
;
380 nDaysInYear
= IsLeapYear( nYear1
)? 366 : 365;
382 if( nYears
&& ( nMonth1
> nMonth2
|| ( nMonth1
== nMonth2
&& nDay1
> nDay2
) ) )
386 nDayDiff
= nDate2
- DateToDays( nDay1
, nMonth1
, nYear2
);
388 nDayDiff
= nDate2
- nDate1
;
391 nDayDiff
+= nDaysInYear
;
394 case 2: // 2=exact/360
396 nYears
= sal_uInt16( ( nDate2
- nDate1
) / nDaysInYear
);
397 nDayDiff
= nDate2
- nDate1
;
398 nDayDiff
%= nDaysInYear
;
400 case 3: //3=exact/365
402 nYears
= sal_uInt16( ( nDate2
- nDate1
) / nDaysInYear
);
403 nDayDiff
= nDate2
- nDate1
;
404 nDayDiff
%= nDaysInYear
;
411 rDayDiffPart
= nDayDiff
;
412 rDaysInYear
= nDaysInYear
;
416 sal_Int32
GetDiffDate( sal_Int32 nNullDate
, sal_Int32 nStartDate
, sal_Int32 nEndDate
, sal_Int32 nMode
,
417 sal_Int32
* pOptDaysIn1stYear
) THROWDEF_RTE_IAE
419 sal_Bool bNeg
= nStartDate
> nEndDate
;
423 sal_Int32 n
= nEndDate
;
424 nEndDate
= nStartDate
;
432 case 0: // 0=USA (NASD) 30/360
433 case 4: // 4=Europe 30/360
435 sal_uInt16 nD1
, nM1
, nY1
, nD2
, nM2
, nY2
;
437 nStartDate
+= nNullDate
;
438 nEndDate
+= nNullDate
;
440 DaysToDate( nStartDate
, nD1
, nM1
, nY1
);
441 DaysToDate( nEndDate
, nD2
, nM2
, nY2
);
443 sal_Bool bLeap
= IsLeapYear( nY1
);
444 sal_Int32 nDays
, nMonths
;
449 nMonths
+= ( nY2
- nY1
) * 12;
451 nRet
= nMonths
* 30 + nDays
;
452 if( nMode
== 0 && nM1
== 2 && nM2
!= 2 && nY1
== nY2
)
453 nRet
-= bLeap
? 1 : 2;
455 if( pOptDaysIn1stYear
)
456 *pOptDaysIn1stYear
= 360;
459 case 1: // 1=exact/exact
460 if( pOptDaysIn1stYear
)
462 sal_uInt16 nD
, nM
, nY
;
464 DaysToDate( nStartDate
+ nNullDate
, nD
, nM
, nY
);
466 *pOptDaysIn1stYear
= IsLeapYear( nY
)? 366 : 365;
468 nRet
= nEndDate
- nStartDate
;
470 case 2: // 2=exact/360
471 nRet
= nEndDate
- nStartDate
;
472 if( pOptDaysIn1stYear
)
473 *pOptDaysIn1stYear
= 360;
475 case 3: //3=exact/365
476 nRet
= nEndDate
- nStartDate
;
477 if( pOptDaysIn1stYear
)
478 *pOptDaysIn1stYear
= 365;
484 return bNeg
? -nRet
: nRet
;
488 double GetYearDiff( sal_Int32 nNullDate
, sal_Int32 nStartDate
, sal_Int32 nEndDate
, sal_Int32 nMode
) THROWDEF_RTE_IAE
490 sal_Int32 nDays1stYear
;
491 sal_Int32 nTotalDays
= GetDiffDate( nNullDate
, nStartDate
, nEndDate
, nMode
, &nDays1stYear
);
493 return double( nTotalDays
) / double( nDays1stYear
);
497 sal_Int32
GetDaysInYear( sal_Int32 nNullDate
, sal_Int32 nDate
, sal_Int32 nMode
) THROWDEF_RTE_IAE
501 case 0: // 0=USA (NASD) 30/360
502 case 2: // 2=exact/360
503 case 4: // 4=Europe 30/360
505 case 1: // 1=exact/exact
507 sal_uInt16 nD
, nM
, nY
;
509 DaysToDate( nDate
, nD
, nM
, nY
);
510 return IsLeapYear( nY
)? 366 : 365;
512 case 3: //3=exact/365
520 double GetYearFrac( sal_Int32 nNullDate
, sal_Int32 nStartDate
, sal_Int32 nEndDate
, sal_Int32 nMode
) THROWDEF_RTE_IAE
522 if( nStartDate
== nEndDate
)
523 return 0.0; // nothing to do...
526 sal_Int32 nDayDiff
, nDaysInYear
;
528 GetDiffParam( nNullDate
, nStartDate
, nEndDate
, nMode
, nYears
, nDayDiff
, nDaysInYear
);
530 return double( nYears
) + double( nDayDiff
) / double( nDaysInYear
);
534 double Fak( sal_Int32 n
)
556 double GetGcd( double f1
, double f2
)
558 double f
= fmod( f1
, f2
);
570 double ConvertToDec( const STRING
& aStr
, sal_uInt16 nBase
, sal_uInt16 nCharLim
) THROWDEF_RTE_IAE
572 if ( nBase
< 2 || nBase
> 36 )
575 sal_uInt32 nStrLen
= aStr
.getLength();
576 if( nStrLen
> nCharLim
)
583 register const sal_Unicode
* p
= aStr
.getStr();
585 sal_uInt16 nFirstDig
= 0;
586 sal_Bool bFirstDig
= sal_True
;
587 double fBase
= nBase
;
593 if( '0' <= *p
&& *p
<= '9' )
595 else if( 'A' <= *p
&& *p
<= 'Z' )
596 n
= 10 + ( *p
- 'A' );
597 else if ( 'a' <= *p
&& *p
<= 'z' )
598 n
= 10 + ( *p
- 'a' );
606 bFirstDig
= sal_False
;
609 fVal
= fVal
* fBase
+ double( n
);
619 if( nStrLen
== nCharLim
&& !bFirstDig
&& (nFirstDig
>= nBase
/ 2) )
620 { // handling negativ values
621 fVal
= ( pow( double( nBase
), double( nCharLim
) ) - fVal
); // complement
629 static inline sal_Char
GetMaxChar( sal_uInt16 nBase
)
631 const sal_Char
* c
= "--123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
636 STRING
ConvertFromDec( double fNum
, double fMin
, double fMax
, sal_uInt16 nBase
,
637 sal_Int32 nPlaces
, sal_Int32 nMaxPlaces
, sal_Bool bUsePlaces
) THROWDEF_RTE_IAE
639 fNum
= ::rtl::math::approxFloor( fNum
);
640 fMin
= ::rtl::math::approxFloor( fMin
);
641 fMax
= ::rtl::math::approxFloor( fMax
);
643 if( fNum
< fMin
|| fNum
> fMax
|| ( bUsePlaces
&& ( nPlaces
<= 0 || nPlaces
> nMaxPlaces
) ) )
646 sal_Int64 nNum
= static_cast< sal_Int64
>( fNum
);
647 sal_Bool bNeg
= nNum
< 0;
649 nNum
= sal_Int64( pow( double( nBase
), double( nMaxPlaces
) ) ) + nNum
;
651 STRING
aRet( STRING::valueOf( nNum
, nBase
).toAsciiUpperCase() );
656 sal_Int32 nLen
= aRet
.getLength();
657 if( !bNeg
&& nLen
> nPlaces
)
661 else if( ( bNeg
&& nLen
< nMaxPlaces
) || ( !bNeg
&& nLen
< nPlaces
) )
663 sal_Int32 nLeft
= nPlaces
- nLen
;
664 sal_Char
* p
= new sal_Char
[ nLeft
+ 1 ];
665 memset( p
, bNeg
? GetMaxChar( nBase
) : '0', nLeft
);
667 STRING
aTmp( p
, nLeft
, RTL_TEXTENCODING_MS_1252
);
678 // implementation moved to module sal, see #i97091#
679 double Erf( double x
)
681 return ::rtl::math::erf(x
);
684 // implementation moved to module sal, see #i97091#
685 double Erfc( double x
)
687 return ::rtl::math::erfc(x
);
690 inline sal_Bool
IsNum( sal_Unicode c
)
692 return c
>= '0' && c
<= '9';
696 inline sal_Bool
IsComma( sal_Unicode c
)
698 return c
== '.' || c
== ',';
702 inline sal_Bool
IsExpStart( sal_Unicode c
)
704 return c
== 'e' || c
== 'E';
708 inline sal_Bool
IsImagUnit( sal_Unicode c
)
710 return c
== 'i' || c
== 'j';
714 inline sal_uInt16
GetVal( sal_Unicode c
)
716 return sal_uInt16( c
- '0' );
720 sal_Bool
ParseDouble( const sal_Unicode
*& rp
, double& rRet
)
724 double fMult
= 0.1; // multiplier to multiply digits with, when adding fractional ones
726 sal_Int32 nMaxExp
= 307;
727 sal_uInt16 nDigCnt
= 18; // max. number of digits to read in, rest doesn't matter
729 enum State
{ S_End
= 0, S_Sign
, S_IntStart
, S_Int
, S_IgnoreIntDigs
, S_Frac
, S_IgnoreFracDigs
, S_ExpSign
, S_Exp
};
733 sal_Bool bNegNum
= sal_False
;
734 sal_Bool bNegExp
= sal_False
;
736 const sal_Unicode
* p
= rp
;
758 else if( IsComma( c
) )
770 else if( IsComma( c
) )
772 else if( IsImagUnit( c
) )
784 fInt
+= double( GetVal( c
) );
787 eS
= S_IgnoreIntDigs
;
789 else if( IsComma( c
) )
791 else if( IsExpStart( c
) )
796 case S_IgnoreIntDigs
:
798 nExp
++; // just multiply num with 10... ;-)
799 else if( IsComma( c
) )
801 else if( IsExpStart( c
) )
809 fFrac
+= double( GetVal( c
) ) * fMult
;
814 eS
= S_IgnoreFracDigs
;
816 else if( IsExpStart( c
) )
821 case S_IgnoreFracDigs
:
822 if( IsExpStart( c
) )
824 else if( !IsNum( c
) )
852 case S_End
: // to avoid compiler warning
853 break; // loop exits anyway
859 p
--; // set pointer back to last
863 sal_Int32 nLog10
= sal_Int32( log10( fInt
) );
868 if( nLog10
+ nExp
> nMaxExp
)
871 fInt
= ::rtl::math::pow10Exp( fInt
, nExp
);
882 STRING
GetString( double f
, sal_Bool bLeadingSign
, sal_uInt16 nMaxDig
)
884 const int nBuff
= 256;
885 sal_Char aBuff
[ nBuff
+ 1 ];
886 const char* pFormStr
= bLeadingSign
? "%+.*g" : "%.*g";
887 int nLen
= snprintf( aBuff
, nBuff
, pFormStr
, int( nMaxDig
), f
);
888 // you never know which underlying implementation you get ...
890 if ( nLen
< 0 || nLen
> nBuff
)
891 nLen
= strlen( aBuff
);
893 STRING
aRet( aBuff
, nLen
, RTL_TEXTENCODING_MS_1252
);
899 double GetAmordegrc( sal_Int32 nNullDate
, double fCost
, sal_Int32 nDate
, sal_Int32 nFirstPer
,
900 double fRestVal
, double fPer
, double fRate
, sal_Int32 nBase
) THROWDEF_RTE_IAE
905 sal_uInt32 nPer
= sal_uInt32( fPer
);
906 double fUsePer
= 1.0 / fRate
;
911 else if( fUsePer
< 5.0 )
913 else if( fUsePer
<= 6.0 )
919 double fNRate
= ::rtl::math::round( GetYearFrac( nNullDate
, nDate
, nFirstPer
, nBase
) * fRate
* fCost
, 0 );
921 double fRest
= fCost
- fRestVal
; // Anschaffungskosten - Restwert - Summe aller Abschreibungen
923 for( sal_uInt32 n
= 0 ; n
< nPer
; n
++ )
925 fNRate
= ::rtl::math::round( fRate
* fCost
, 0 );
934 return ::rtl::math::round( fCost
* 0.5, 0 );
947 double GetAmorlinc( sal_Int32 nNullDate
, double fCost
, sal_Int32 nDate
, sal_Int32 nFirstPer
,
948 double fRestVal
, double fPer
, double fRate
, sal_Int32 nBase
) THROWDEF_RTE_IAE
953 sal_uInt32 nPer
= sal_uInt32( fPer
);
954 double fOneRate
= fCost
* fRate
;
955 double fCostDelta
= fCost
- fRestVal
;
956 double f0Rate
= GetYearFrac( nNullDate
, nDate
, nFirstPer
, nBase
) * fRate
* fCost
;
957 sal_uInt32 nNumOfFullPeriods
= sal_uInt32( ( fCost
- fRestVal
- f0Rate
) / fOneRate
);
961 else if( nPer
<= nNumOfFullPeriods
)
963 else if( nPer
== nNumOfFullPeriods
+ 1 )
964 return fCostDelta
- fOneRate
* nNumOfFullPeriods
- f0Rate
;
970 double GetDuration( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, double fCoup
,
971 double fYield
, sal_Int32 nFreq
, sal_Int32 nBase
) THROWDEF_RTE_IAE
973 double fYearfrac
= GetYearFrac( nNullDate
, nSettle
, nMat
, nBase
);
974 double fNumOfCoups
= GetCoupnum( nNullDate
, nSettle
, nMat
, nFreq
, nBase
);
976 const double f100
= 100.0;
977 fCoup
*= f100
/ double( nFreq
); // fCoup is used as cash flow
981 double nDiff
= fYearfrac
* nFreq
- fNumOfCoups
;
985 for( t
= 1.0 ; t
< fNumOfCoups
; t
++ )
986 fDur
+= ( t
+ nDiff
) * ( fCoup
) / pow( fYield
, t
+ nDiff
);
988 fDur
+= ( fNumOfCoups
+ nDiff
) * ( fCoup
+ f100
) / pow( fYield
, fNumOfCoups
+ nDiff
);
991 for( t
= 1.0 ; t
< fNumOfCoups
; t
++ )
992 p
+= fCoup
/ pow( fYield
, t
+ nDiff
);
994 p
+= ( fCoup
+ f100
) / pow( fYield
, fNumOfCoups
+ nDiff
);
997 fDur
/= double( nFreq
);
1003 double GetYieldmat( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nIssue
,
1004 double fRate
, double fPrice
, sal_Int32 nBase
) THROWDEF_RTE_IAE
1006 double fIssMat
= GetYearFrac( nNullDate
, nIssue
, nMat
, nBase
);
1007 double fIssSet
= GetYearFrac( nNullDate
, nIssue
, nSettle
, nBase
);
1008 double fSetMat
= GetYearFrac( nNullDate
, nSettle
, nMat
, nBase
);
1010 double y
= 1.0 + fIssMat
* fRate
;
1011 y
/= fPrice
/ 100.0 + fIssSet
* fRate
;
1019 double GetOddfprice( sal_Int32
/*nNullDate*/, sal_Int32
/*nSettle*/, sal_Int32
/*nMat*/, sal_Int32
/*nIssue*/,
1020 sal_Int32
/*nFirstCoup*/, double /*fRate*/, double /*fYield*/, double /*fRedemp*/, sal_Int32
/*nFreq*/,
1021 sal_Int32
/*nBase*/ ) THROWDEF_RTE_IAE
1023 THROW_RTE
; // #87380#
1027 double getYield_( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, double fCoup
, double fPrice
,
1028 double fRedemp
, sal_Int32 nFreq
, sal_Int32 nBase
) THROWDEF_RTE_IAE
1030 double fRate
= fCoup
;
1031 double fPriceN
= 0.0;
1032 double fYield1
= 0.0;
1033 double fYield2
= 1.0;
1034 double fPrice1
= getPrice_( nNullDate
, nSettle
, nMat
, fRate
, fYield1
, fRedemp
, nFreq
, nBase
);
1035 double fPrice2
= getPrice_( nNullDate
, nSettle
, nMat
, fRate
, fYield2
, fRedemp
, nFreq
, nBase
);
1036 double fYieldN
= ( fYield2
- fYield1
) * 0.5;
1038 for( sal_uInt32 nIter
= 0 ; nIter
< 100 && fPriceN
!= fPrice
; nIter
++ )
1040 fPriceN
= getPrice_( nNullDate
, nSettle
, nMat
, fRate
, fYieldN
, fRedemp
, nFreq
, nBase
);
1042 if( fPrice
== fPrice1
)
1044 else if( fPrice
== fPrice2
)
1046 else if( fPrice
== fPriceN
)
1048 else if( fPrice
< fPrice2
)
1051 fPrice2
= getPrice_( nNullDate
, nSettle
, nMat
, fRate
, fYield2
, fRedemp
, nFreq
, nBase
);
1053 fYieldN
= ( fYield2
- fYield1
) * 0.5;
1057 if( fPrice
< fPriceN
)
1068 fYieldN
= fYield2
- ( fYield2
- fYield1
) * ( ( fPrice
- fPrice2
) / ( fPrice1
- fPrice2
) );
1072 if( fabs( fPrice
- fPriceN
) > fPrice
/ 100.0 )
1073 THROW_IAE
; // result not precise enough
1079 double getPrice_( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, double fRate
, double fYield
,
1080 double fRedemp
, sal_Int32 nFreq
, sal_Int32 nBase
) THROWDEF_RTE_IAE
1082 double fFreq
= nFreq
;
1084 double fE
= GetCoupdays( nNullDate
, nSettle
, nMat
, nFreq
, nBase
);
1085 double fDSC_E
= GetCoupdaysnc( nNullDate
, nSettle
, nMat
, nFreq
, nBase
) / fE
;
1086 double fN
= GetCoupnum( nNullDate
, nSettle
, nMat
, nFreq
, nBase
);
1087 double fA
= GetCoupdaybs( nNullDate
, nSettle
, nMat
, nFreq
, nBase
);
1089 double fRet
= fRedemp
/ ( pow( 1.0 + fYield
/ fFreq
, fN
- 1.0 + fDSC_E
) );
1090 fRet
-= 100.0 * fRate
/ fFreq
* fA
/ fE
;
1092 double fT1
= 100.0 * fRate
/ fFreq
;
1093 double fT2
= 1.0 + fYield
/ fFreq
;
1095 for( double fK
= 0.0 ; fK
< fN
; fK
++ )
1096 fRet
+= fT1
/ pow( fT2
, fK
+ fDSC_E
);
1102 double GetOddfyield( sal_Int32
/*nNullDate*/, sal_Int32
/*nSettle*/, sal_Int32
/*nMat*/, sal_Int32
/*nIssue*/,
1103 sal_Int32
/*nFirstCoup*/, double /*fRate*/, double /*fPrice*/, double /*fRedemp*/, sal_Int32
/*nFreq*/,
1104 sal_Int32
/*nBase*/ ) THROWDEF_RTE_IAE
1106 THROW_RTE
; // #87380#
1110 double GetOddlprice( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nLastCoup
,
1111 double fRate
, double fYield
, double fRedemp
, sal_Int32 nFreq
, sal_Int32 nBase
) THROWDEF_RTE_IAE
1113 double fFreq
= double( nFreq
);
1114 double fDCi
= GetYearFrac( nNullDate
, nLastCoup
, nMat
, nBase
) * fFreq
;
1115 double fDSCi
= GetYearFrac( nNullDate
, nSettle
, nMat
, nBase
) * fFreq
;
1116 double fAi
= GetYearFrac( nNullDate
, nLastCoup
, nSettle
, nBase
) * fFreq
;
1118 double p
= fRedemp
+ fDCi
* 100.0 * fRate
/ fFreq
;
1119 p
/= fDSCi
* fYield
/ fFreq
+ 1.0;
1120 p
-= fAi
* 100.0 * fRate
/ fFreq
;
1126 double GetOddlyield( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nLastCoup
,
1127 double fRate
, double fPrice
, double fRedemp
, sal_Int32 nFreq
, sal_Int32 nBase
) THROWDEF_RTE_IAE
1129 double fFreq
= double( nFreq
);
1130 double fDCi
= GetYearFrac( nNullDate
, nLastCoup
, nMat
, nBase
) * fFreq
;
1131 double fDSCi
= GetYearFrac( nNullDate
, nSettle
, nMat
, nBase
) * fFreq
;
1132 double fAi
= GetYearFrac( nNullDate
, nLastCoup
, nSettle
, nBase
) * fFreq
;
1134 double y
= fRedemp
+ fDCi
* 100.0 * fRate
/ fFreq
;
1135 y
/= fPrice
+ fAi
* 100.0 * fRate
/ fFreq
;
1143 double GetRmz( double fZins
, double fZzr
, double fBw
, double fZw
, sal_Int32 nF
)
1147 fRmz
= ( fBw
+ fZw
) / fZzr
;
1150 double fTerm
= pow( 1.0 + fZins
, fZzr
);
1152 fRmz
= ( fZw
* fZins
/ ( fTerm
- 1.0 ) + fBw
* fZins
/ ( 1.0 - 1.0 / fTerm
) ) / ( 1.0 + fZins
);
1154 fRmz
= fZw
* fZins
/ ( fTerm
- 1.0 ) + fBw
* fZins
/ ( 1.0 - 1.0 / fTerm
);
1161 double GetZw( double fZins
, double fZzr
, double fRmz
, double fBw
, sal_Int32 nF
)
1165 fZw
= fBw
+ fRmz
* fZzr
;
1168 double fTerm
= pow( 1.0 + fZins
, fZzr
);
1170 fZw
= fBw
* fTerm
+ fRmz
* ( 1.0 + fZins
) * ( fTerm
- 1.0 ) / fZins
;
1172 fZw
= fBw
* fTerm
+ fRmz
* ( fTerm
- 1.0 ) / fZins
;
1179 //-----------------------------------------------------------------------------
1180 // financial functions COUP***
1184 // COUPPCD: find last coupon date before settlement (can be equal to settlement)
1185 void lcl_GetCouppcd( ScaDate
& rDate
, const ScaDate
& rSettle
, const ScaDate
& rMat
, sal_Int32 nFreq
)
1186 throw( lang::IllegalArgumentException
)
1189 rDate
.setYear( rSettle
.getYear() );
1190 if( rDate
< rSettle
)
1191 rDate
.addYears( 1 );
1192 while( rDate
> rSettle
)
1193 rDate
.addMonths( -12 / nFreq
);
1196 double GetCouppcd( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, sal_Int32 nBase
)
1199 if( nSettle
>= nMat
|| CHK_Freq
)
1203 lcl_GetCouppcd( aDate
, ScaDate( nNullDate
, nSettle
, nBase
), ScaDate( nNullDate
, nMat
, nBase
), nFreq
);
1204 return aDate
.getDate( nNullDate
);
1209 // COUPNCD: find first coupon date after settlement (is never equal to settlement)
1210 void lcl_GetCoupncd( ScaDate
& rDate
, const ScaDate
& rSettle
, const ScaDate
& rMat
, sal_Int32 nFreq
)
1211 throw( lang::IllegalArgumentException
)
1214 rDate
.setYear( rSettle
.getYear() );
1215 if( rDate
> rSettle
)
1216 rDate
.addYears( -1 );
1217 while( rDate
<= rSettle
)
1218 rDate
.addMonths( 12 / nFreq
);
1221 double GetCoupncd( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, sal_Int32 nBase
)
1224 if( nSettle
>= nMat
|| CHK_Freq
)
1228 lcl_GetCoupncd( aDate
, ScaDate( nNullDate
, nSettle
, nBase
), ScaDate( nNullDate
, nMat
, nBase
), nFreq
);
1229 return aDate
.getDate( nNullDate
);
1234 // COUPDAYBS: get day count: coupon date before settlement <-> settlement
1235 double GetCoupdaybs( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, sal_Int32 nBase
)
1238 if( nSettle
>= nMat
|| CHK_Freq
)
1241 ScaDate
aSettle( nNullDate
, nSettle
, nBase
);
1243 lcl_GetCouppcd( aDate
, aSettle
, ScaDate( nNullDate
, nMat
, nBase
), nFreq
);
1244 return ScaDate::getDiff( aDate
, aSettle
);
1249 // COUPDAYSNC: get day count: settlement <-> coupon date after settlement
1250 double GetCoupdaysnc( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, sal_Int32 nBase
)
1253 if( nSettle
>= nMat
|| CHK_Freq
)
1256 if( (nBase
!= 0) && (nBase
!= 4) )
1258 ScaDate
aSettle( nNullDate
, nSettle
, nBase
);
1260 lcl_GetCoupncd( aDate
, aSettle
, ScaDate( nNullDate
, nMat
, nBase
), nFreq
);
1261 return ScaDate::getDiff( aSettle
, aDate
);
1263 return GetCoupdays( nNullDate
, nSettle
, nMat
, nFreq
, nBase
) - GetCoupdaybs( nNullDate
, nSettle
, nMat
, nFreq
, nBase
);
1268 // COUPDAYS: get day count: coupon date before settlement <-> coupon date after settlement
1269 double GetCoupdays( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, sal_Int32 nBase
)
1272 if( nSettle
>= nMat
|| CHK_Freq
)
1278 lcl_GetCouppcd( aDate
, ScaDate( nNullDate
, nSettle
, nBase
), ScaDate( nNullDate
, nMat
, nBase
), nFreq
);
1279 ScaDate
aNextDate( aDate
);
1280 aNextDate
.addMonths( 12 / nFreq
);
1281 return ScaDate::getDiff( aDate
, aNextDate
);
1283 return static_cast< double >( GetDaysInYear( 0, 0, nBase
) ) / nFreq
;
1288 // COUPNUM: get count of coupon dates
1289 double GetCoupnum( sal_Int32 nNullDate
, sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, sal_Int32 nBase
)
1292 if( nSettle
>= nMat
|| CHK_Freq
)
1295 ScaDate
aMat( nNullDate
, nMat
, nBase
);
1297 lcl_GetCouppcd( aDate
, ScaDate( nNullDate
, nSettle
, nBase
), aMat
, nFreq
);
1298 sal_uInt16 nMonths
= (aMat
.getYear() - aDate
.getYear()) * 12 + aMat
.getMonth() - aDate
.getMonth();
1299 return static_cast< double >( nMonths
* nFreq
/ 12 );
1308 const sal_uInt32
MyList::nStartSize
= 16;
1309 const sal_uInt32
MyList::nIncrSize
= 16;
1312 void MyList::_Grow( void )
1316 void** pNewData
= new void*[ nSize
];
1317 memcpy( pNewData
, pData
, nNew
* sizeof( void* ) );
1324 MyList::MyList( void )
1327 pData
= new void*[ nSize
];
1338 void MyList::Insert( void* p
, sal_uInt32 n
)
1346 void** pIns
= pData
+ n
;
1347 memmove( pIns
+ 1, pIns
, ( nNew
- n
) * sizeof( void* ) );
1358 StringList::~StringList()
1360 for( STRING
* p
= ( STRING
* ) First() ; p
; p
= ( STRING
* ) Next() )
1365 class AnalysisRscStrArrLoader
: public Resource
1368 ResStringArray aStrArray
;
1370 AnalysisRscStrArrLoader( sal_uInt16 nRsc
, sal_uInt16 nArrayId
, ResMgr
& rResMgr
) :
1371 Resource( AnalysisResId( nRsc
, rResMgr
) ),
1372 aStrArray( AnalysisResId( nArrayId
, rResMgr
) )
1377 const ResStringArray
& GetStringArray() const { return aStrArray
; }
1383 FuncData::FuncData( const FuncDataBase
& r
, ResMgr
& rResMgr
) :
1384 aIntName( OUString::createFromAscii( r
.pIntName
) ),
1385 nUINameID( r
.nUINameID
),
1386 nDescrID( r
.nDescrID
),
1387 bDouble( r
.bDouble
),
1388 bWithOpt( r
.bWithOpt
),
1389 nParam( r
.nNumOfParams
),
1390 nCompID( r
.nCompListID
),
1393 AnalysisRscStrArrLoader
aArrLoader( RID_ANALYSIS_DEFFUNCTION_NAMES
, nCompID
, rResMgr
);
1394 const ResStringArray
& rArr
= aArrLoader
.GetStringArray();
1396 sal_uInt16 nCount
= sal::static_int_cast
<sal_uInt16
>( rArr
.Count() );
1399 for( n
= 0 ; n
< nCount
; n
++ )
1400 aCompList
.Append( rArr
.GetString( n
) );
1404 FuncData::~FuncData()
1409 sal_uInt16
FuncData::GetStrIndex( sal_uInt16 nParamNum
) const
1414 if( nParamNum
> nParam
)
1417 return nParamNum
* 2;
1423 FuncDataList::FuncDataList( ResMgr
& rResMgr
)
1425 for( sal_uInt16 n
= 0 ; n
< SAL_N_ELEMENTS(pFuncDatas
) ; n
++ )
1426 Append( new FuncData( pFuncDatas
[ n
], rResMgr
) );
1430 FuncDataList::~FuncDataList()
1432 for( FuncData
* p
= ( FuncData
* ) First() ; p
; p
= ( FuncData
* ) Next() )
1437 const FuncData
* FuncDataList::Get( const OUString
& aProgrammaticName
) const
1439 if( aLastName
== aProgrammaticName
)
1440 return Get( nLast
);
1442 ( ( FuncDataList
* ) this )->aLastName
= aProgrammaticName
;
1444 sal_uInt32 nE
= Count();
1445 for( sal_uInt32 n
= 0 ; n
< nE
; n
++ )
1447 const FuncData
* p
= Get( n
);
1448 if( p
->Is( aProgrammaticName
) )
1450 ( ( FuncDataList
* ) this )->nLast
= n
;
1455 ( ( FuncDataList
* ) this )->nLast
= 0xFFFFFFFF;
1460 AnalysisResId::AnalysisResId( sal_uInt16 nId
, ResMgr
& rResMgr
) : ResId( nId
, rResMgr
)
1467 SortedIndividualInt32List::SortedIndividualInt32List()
1472 SortedIndividualInt32List::~SortedIndividualInt32List()
1477 void SortedIndividualInt32List::Insert( sal_Int32 nDay
)
1479 sal_uInt32 nIndex
= Count();
1483 sal_Int32 nRef
= Get( nIndex
);
1486 else if( nDay
> nRef
)
1488 MyList::Insert( (void*)(sal_IntPtr
)nDay
, nIndex
+ 1 );
1492 MyList::Insert( (void*)(sal_IntPtr
)nDay
, 0UL );
1496 void SortedIndividualInt32List::Insert( sal_Int32 nDay
, sal_Int32 nNullDate
, sal_Bool bInsertOnWeekend
)
1502 if( bInsertOnWeekend
|| (GetDayOfWeek( nDay
) < 5) )
1507 void SortedIndividualInt32List::Insert(
1508 double fDay
, sal_Int32 nNullDate
, sal_Bool bInsertOnWeekend
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1510 if( (fDay
< -2147483648.0) || (fDay
> 2147483649.0) )
1511 throw lang::IllegalArgumentException();
1512 Insert( static_cast< sal_Int32
>( fDay
), nNullDate
, bInsertOnWeekend
);
1516 sal_Bool
SortedIndividualInt32List::Find( sal_Int32 nVal
) const
1518 sal_uInt32 nE
= Count();
1520 if( !nE
|| nVal
< Get( 0 ) || nVal
> Get( nE
- 1 ) )
1525 for( sal_uInt32 n
= 0 ; n
< nE
; n
++ )
1527 sal_Int32 nRef
= Get( n
);
1531 else if( nRef
> nVal
)
1538 void SortedIndividualInt32List::InsertHolidayList(
1539 const ScaAnyConverter
& rAnyConv
,
1540 const uno::Any
& rHolAny
,
1541 sal_Int32 nNullDate
,
1542 sal_Bool bInsertOnWeekend
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1545 if( rAnyConv
.getDouble( fDay
, rHolAny
) )
1546 Insert( fDay
, nNullDate
, bInsertOnWeekend
);
1550 void SortedIndividualInt32List::InsertHolidayList(
1551 ScaAnyConverter
& rAnyConv
,
1552 const uno::Reference
< beans::XPropertySet
>& xOptions
,
1553 const uno::Any
& rHolAny
,
1554 sal_Int32 nNullDate
,
1555 sal_Bool bInsertOnWeekend
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1557 rAnyConv
.init( xOptions
);
1558 if( rHolAny
.getValueTypeClass() == uno::TypeClass_SEQUENCE
)
1560 uno::Sequence
< uno::Sequence
< uno::Any
> > aAnySeq
;
1561 if( rHolAny
>>= aAnySeq
)
1563 const uno::Sequence
< uno::Any
>* pSeqArray
= aAnySeq
.getConstArray();
1564 for( sal_Int32 nIndex1
= 0; nIndex1
< aAnySeq
.getLength(); nIndex1
++ )
1566 const uno::Sequence
< uno::Any
>& rSubSeq
= pSeqArray
[ nIndex1
];
1567 const uno::Any
* pAnyArray
= rSubSeq
.getConstArray();
1569 for( sal_Int32 nIndex2
= 0; nIndex2
< rSubSeq
.getLength(); nIndex2
++ )
1570 InsertHolidayList( rAnyConv
, pAnyArray
[ nIndex2
], nNullDate
, bInsertOnWeekend
);
1574 throw lang::IllegalArgumentException();
1577 InsertHolidayList( rAnyConv
, rHolAny
, nNullDate
, bInsertOnWeekend
);
1582 //-----------------------------------------------------------------------------
1584 ScaDoubleList::~ScaDoubleList()
1586 for( double* pDbl
= const_cast< double* >( First() ); pDbl
; pDbl
= const_cast< double* >( Next() ) )
1591 void ScaDoubleList::Append(
1592 const uno::Sequence
< uno::Sequence
< double > >& rValueSeq
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1594 const uno::Sequence
< double >* pSeqArray
= rValueSeq
.getConstArray();
1595 for( sal_Int32 nIndex1
= 0; nIndex1
< rValueSeq
.getLength(); nIndex1
++ )
1597 const uno::Sequence
< double >& rSubSeq
= pSeqArray
[ nIndex1
];
1598 const double* pArray
= rSubSeq
.getConstArray();
1599 for( sal_Int32 nIndex2
= 0; nIndex2
< rSubSeq
.getLength(); nIndex2
++ )
1600 Append( pArray
[ nIndex2
] );
1605 void ScaDoubleList::Append(
1606 const uno::Sequence
< uno::Sequence
< sal_Int32
> >& rValueSeq
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1608 const uno::Sequence
< sal_Int32
>* pSeqArray
= rValueSeq
.getConstArray();
1609 for( sal_Int32 nIndex1
= 0; nIndex1
< rValueSeq
.getLength(); nIndex1
++ )
1611 const uno::Sequence
< sal_Int32
>& rSubSeq
= pSeqArray
[ nIndex1
];
1612 const sal_Int32
* pArray
= rSubSeq
.getConstArray();
1613 for( sal_Int32 nIndex2
= 0; nIndex2
< rSubSeq
.getLength(); nIndex2
++ )
1614 Append( pArray
[ nIndex2
] );
1620 void ScaDoubleList::Append(
1621 const ScaAnyConverter
& rAnyConv
,
1622 const uno::Any
& rAny
,
1623 sal_Bool bIgnoreEmpty
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1625 if( rAny
.getValueTypeClass() == uno::TypeClass_SEQUENCE
)
1626 Append( rAnyConv
, *static_cast< const uno::Sequence
< uno::Sequence
< uno::Any
> >* >( rAny
.getValue() ), bIgnoreEmpty
);
1630 if( rAnyConv
.getDouble( fValue
, rAny
) )
1632 else if( !bIgnoreEmpty
)
1638 void ScaDoubleList::Append(
1639 const ScaAnyConverter
& rAnyConv
,
1640 const uno::Sequence
< uno::Any
>& rAnySeq
,
1641 sal_Bool bIgnoreEmpty
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1643 const uno::Any
* pArray
= rAnySeq
.getConstArray();
1644 for( sal_Int32 nIndex
= 0; nIndex
< rAnySeq
.getLength(); nIndex
++ )
1645 Append( rAnyConv
, pArray
[ nIndex
], bIgnoreEmpty
);
1649 void ScaDoubleList::Append(
1650 const ScaAnyConverter
& rAnyConv
,
1651 const uno::Sequence
< uno::Sequence
< uno::Any
> >& rAnySeq
,
1652 sal_Bool bIgnoreEmpty
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1654 const uno::Sequence
< uno::Any
>* pArray
= rAnySeq
.getConstArray();
1655 for( sal_Int32 nIndex
= 0; nIndex
< rAnySeq
.getLength(); nIndex
++ )
1656 Append( rAnyConv
, pArray
[ nIndex
], bIgnoreEmpty
);
1661 void ScaDoubleList::Append(
1662 ScaAnyConverter
& rAnyConv
,
1663 const uno::Reference
< beans::XPropertySet
>& xOpt
,
1664 const uno::Sequence
< uno::Any
>& rAnySeq
,
1665 sal_Bool bIgnoreEmpty
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1667 rAnyConv
.init( xOpt
);
1668 Append( rAnyConv
, rAnySeq
, bIgnoreEmpty
);
1672 sal_Bool
ScaDoubleList::CheckInsert( double ) const throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1679 //-----------------------------------------------------------------------------
1681 sal_Bool
ScaDoubleListGT0::CheckInsert( double fValue
) const throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1684 throw lang::IllegalArgumentException();
1685 return fValue
> 0.0;
1690 //-----------------------------------------------------------------------------
1692 sal_Bool
ScaDoubleListGE0::CheckInsert( double fValue
) const throw( uno::RuntimeException
, lang::IllegalArgumentException
)
1695 throw lang::IllegalArgumentException();
1701 //-----------------------------------------------------------------------------
1703 Complex::Complex( const STRING
& rStr
) THROWDEF_RTE_IAE
1705 if( !ParseString( rStr
, *this ) )
1710 inline sal_Bool
Complex::IsImagUnit( sal_Unicode c
)
1712 return c
== 'i' || c
== 'j';
1715 sal_Bool
Complex::ParseString( const STRING
& rStr
, Complex
& rCompl
)
1717 rCompl
.c
= '\0'; // do not force a symbol, if only real part present
1719 const sal_Unicode
* pStr
= rStr
.getStr();
1721 if( IsImagUnit( *pStr
) && rStr
.getLength() == 1)
1731 if( !ParseDouble( pStr
, f
) )
1736 case '-': // imag part follows
1740 if( IsImagUnit( pStr
[ 1 ] ) )
1742 rCompl
.c
= pStr
[ 1 ];
1743 if( pStr
[ 2 ] == 0 )
1746 rCompl
.i
= ( *pStr
== '+' )? 1.0 : -1.0;
1750 else if( ParseDouble( pStr
, f
) && IsImagUnit( *pStr
) )
1774 case 0: // only real-part
1784 STRING
Complex::GetString() const THROWDEF_RTE_IAE
1786 static const String
aI( 'i' );
1787 static const String
aJ( 'j' );
1788 static const String
aPlus( '+' );
1789 static const String
aMinus( '-' );
1795 bool bHasImag
= i
!= 0.0;
1796 bool bHasReal
= !bHasImag
|| (r
!= 0.0);
1799 aRet
= ::GetString( r
);
1807 else if( i
== -1.0 )
1810 aRet
+= ::GetString( i
, bHasReal
);
1811 aRet
+= (c
!= 'j') ? aI
: aJ
;
1818 double Complex::Arg( void ) const THROWDEF_RTE_IAE
1820 if( r
== 0.0 && i
== 0.0 )
1823 double phi
= acos( r
/ Abs() );
1832 void Complex::Power( double fPower
) THROWDEF_RTE_IAE
1834 if( r
== 0.0 && i
== 0.0 )
1849 phi
= acos( r
/ p
);
1853 p
= pow( p
, fPower
);
1861 void Complex::Sqrt( void )
1863 static const double fMultConst
= 0.7071067811865475; // ...2440084436210485 = 1/sqrt(2)
1865 double i_
= sqrt( p
- r
) * fMultConst
;
1867 r
= sqrt( p
+ r
) * fMultConst
;
1868 i
= ( i
< 0.0 )? -i_
: i_
;
1872 void Complex::Sin( void ) THROWDEF_RTE_IAE
1874 if( !::rtl::math::isValidArcArg( r
) )
1881 r_
= sin( r
) * cosh( i
);
1882 i
= cos( r
) * sinh( i
);
1890 void Complex::Cos( void ) THROWDEF_RTE_IAE
1892 if( !::rtl::math::isValidArcArg( r
) )
1899 r_
= cos( r
) * cosh( i
);
1900 i
= -( sin( r
) * sinh( i
) );
1908 void Complex::Div( const Complex
& z
) THROWDEF_RTE_IAE
1910 if( z
.r
== 0 && z
.i
== 0 )
1918 double f
= 1.0 / ( a2
* a2
+ b2
* b2
);
1920 r
= ( a1
* a2
+ b1
* b2
) * f
;
1921 i
= ( a2
* b1
- a1
* b2
) * f
;
1927 void Complex::Exp( void )
1929 double fE
= exp( r
);
1935 void Complex::Ln( void ) THROWDEF_RTE_IAE
1937 if( r
== 0.0 && i
== 0.0 )
1940 double fAbs
= Abs();
1941 sal_Bool bNegi
= i
< 0.0;
1943 i
= acos( r
/ fAbs
);
1952 void Complex::Log10( void ) THROWDEF_RTE_IAE
1955 Mult( 0.434294481903251828 ); // * log10( e )
1959 void Complex::Log2( void ) THROWDEF_RTE_IAE
1962 Mult( 1.442695040888963407 ); // * log2( e )
1966 void Complex::Tan(void) THROWDEF_RTE_IAE
1970 if( !::rtl::math::isValidArcArg( 2.0 * r
) )
1972 double fScale
=1.0 / ( cos( 2.0 * r
) + cosh( 2.0 * i
));
1973 r
= sin( 2.0 * r
) * fScale
;
1974 i
= sinh( 2.0 * i
) * fScale
;
1978 if( !::rtl::math::isValidArcArg( r
) )
1985 void Complex::Sec( void ) THROWDEF_RTE_IAE
1989 if( !::rtl::math::isValidArcArg( 2 * r
) )
1991 double fScale
= 1.0 / (cosh( 2.0 * i
) + cos ( 2.0 * r
));
1993 r_
= 2.0 * cos( r
) * cosh( i
) * fScale
;
1994 i
= 2.0 * sin( r
) * sinh( i
) * fScale
;
1999 if( !::rtl::math::isValidArcArg( r
) )
2006 void Complex::Csc( void ) THROWDEF_RTE_IAE
2010 if( !::rtl::math::isValidArcArg( 2 * r
) )
2012 double fScale
= 1.0 / (cosh( 2.0 * i
) - cos ( 2.0 * r
));
2014 r_
= 2.0 * sin( r
) * cosh( i
) * fScale
;
2015 i
= -2.0 * cos( r
) * sinh( i
) * fScale
;
2020 if( !::rtl::math::isValidArcArg( r
) )
2027 void Complex::Cot(void) THROWDEF_RTE_IAE
2031 if( !::rtl::math::isValidArcArg( 2.0 * r
) )
2033 double fScale
=1.0 / ( cosh( 2.0 * i
) - cos( 2.0 * r
) );
2034 r
= sin( 2.0 * r
) * fScale
;
2035 i
= - ( sinh( 2.0 * i
) * fScale
);
2039 if( !::rtl::math::isValidArcArg( r
) )
2046 void Complex::Sinh( void ) THROWDEF_RTE_IAE
2048 if( !::rtl::math::isValidArcArg( r
) )
2054 r_
= sinh( r
) * cos( i
);
2055 i
= cosh( r
) * sin( i
);
2063 void Complex::Cosh( void ) THROWDEF_RTE_IAE
2065 if( !::rtl::math::isValidArcArg( r
) )
2071 r_
= cosh( r
) * cos( i
);
2072 i
= sinh( r
) * sin( i
);
2080 void Complex::Sech(void) THROWDEF_RTE_IAE
2084 if( !::rtl::math::isValidArcArg( 2.0 * r
) )
2086 double fScale
=1.0 / ( cosh( 2.0 * r
) + cos( 2.0 * i
));
2088 r_
= 2.0 * cosh( 2.0 * r
) * cos( i
) * fScale
;
2089 i
= - (2.0 * sinh( 2.0 * r
) * sin( i
) * fScale
);
2094 if( !::rtl::math::isValidArcArg( r
) )
2096 r
= 1.0 / cosh( r
);
2101 void Complex::Csch(void) THROWDEF_RTE_IAE
2105 if( !::rtl::math::isValidArcArg( 2.0 * r
) )
2107 double fScale
=1.0 / ( cosh( 2.0 * r
) - cos( 2.0 * i
));
2109 r_
= 2.0 * sinh( 2.0 * r
) * cos( i
) * fScale
;
2110 i
= - ( 2.0 * cosh( 2.0 * r
) * sin( i
) * fScale
);
2115 if( !::rtl::math::isValidArcArg( r
) )
2117 r
= 1.0 / sinh( r
);
2122 ComplexList::~ComplexList()
2124 for( Complex
* p
= ( Complex
* ) First() ; p
; p
= ( Complex
* ) Next() )
2129 void ComplexList::Append( const SEQSEQ( STRING
)& r
, ComplListAppendHandl eAH
) THROWDEF_RTE_IAE
2132 sal_Int32 nE1
= r
.getLength();
2134 sal_Bool bEmpty0
= eAH
== AH_EmpyAs0
;
2135 sal_Bool bErrOnEmpty
= eAH
== AH_EmptyAsErr
;
2137 for( n1
= 0 ; n1
< nE1
; n1
++ )
2139 const SEQ( STRING
)& rList
= r
[ n1
];
2140 nE2
= rList
.getLength();
2142 for( n2
= 0 ; n2
< nE2
; n2
++ )
2144 const STRING
& rStr
= rList
[ n2
];
2146 if( !rStr
.isEmpty() )
2147 Append( new Complex( rStr
) );
2149 Append( new Complex( 0.0 ) );
2150 else if( bErrOnEmpty
)
2157 void ComplexList::Append( const SEQ( ANY
)& aMultPars
, ComplListAppendHandl eAH
) THROWDEF_RTE_IAE
2159 sal_Int32 nEle
= aMultPars
.getLength();
2160 sal_Bool bEmpty0
= eAH
== AH_EmpyAs0
;
2161 sal_Bool bErrOnEmpty
= eAH
== AH_EmptyAsErr
;
2163 for( sal_Int32 i
= 0 ; i
< nEle
; i
++ )
2165 const ANY
& r
= aMultPars
[ i
];
2166 switch( r
.getValueTypeClass() )
2168 case uno::TypeClass_VOID
: break;
2169 case uno::TypeClass_STRING
:
2171 const STRING
* pStr
= ( const STRING
* ) r
.getValue();
2173 if( !pStr
->isEmpty() )
2174 Append( new Complex( *( STRING
* ) r
.getValue() ) );
2176 Append( new Complex( 0.0 ) );
2177 else if( bErrOnEmpty
)
2181 case uno::TypeClass_DOUBLE
:
2182 Append( new Complex( *( double* ) r
.getValue(), 0.0 ) );
2184 case uno::TypeClass_SEQUENCE
:
2186 SEQSEQ( ANY
) aValArr
;
2189 sal_Int32 nE
= aValArr
.getLength();
2190 const SEQ( ANY
)* pArr
= aValArr
.getConstArray();
2191 for( sal_Int32 n
= 0 ; n
< nE
; n
++ )
2192 Append( pArr
[ n
], eAH
);
2207 ConvertData::ConvertData( const sal_Char p
[], double fC
, ConvertDataClass e
, sal_Bool bPrefSupport
) : aName( p
, strlen( p
), RTL_TEXTENCODING_MS_1252
)
2211 bPrefixSupport
= bPrefSupport
;
2214 ConvertData::~ConvertData()
2219 sal_Int16
ConvertData::GetMatchingLevel( const STRING
& rRef
) const
2222 sal_Int32 nLen
= rRef
.getLength();
2223 sal_Int32 nIndex
= rRef
.lastIndexOf( '^' );
2224 if( nIndex
> 0 && nIndex
== ( nLen
- 2 ) )
2226 const sal_Unicode
* p
= aStr
.getStr();
2227 aStr
= STRING( p
, nLen
- 2 );
2228 aStr
+= STRING( p
[ nLen
- 1 ] );
2230 if( aName
.equals( aStr
) )
2234 const sal_Unicode
* p
= aStr
.getStr();
2236 nLen
= aStr
.getLength();
2237 bool bPref
= IsPrefixSupport();
2238 bool bOneChar
= (bPref
&& nLen
> 1 && (aName
== p
+ 1));
2239 if (bOneChar
|| (bPref
&& nLen
> 2 && (aName
== p
+ 2) &&
2240 *p
== 'd' && *(p
+1) == 'a'))
2245 case 'y': n
= -24; break; // yocto
2246 case 'z': n
= -21; break; // zepto
2247 case 'a': n
= -18; break;
2248 case 'f': n
= -15; break;
2249 case 'p': n
= -12; break;
2250 case 'n': n
= -9; break;
2251 case 'u': n
= -6; break;
2252 case 'm': n
= -3; break;
2253 case 'c': n
= -2; break;
2262 case 'e': n
= 1; break;
2263 case 'h': n
= 2; break;
2264 case 'k': n
= 3; break;
2265 case 'M': n
= 6; break;
2266 case 'G': n
= 9; break;
2267 case 'T': n
= 12; break;
2268 case 'P': n
= 15; break;
2269 case 'E': n
= 18; break;
2270 case 'Z': n
= 21; break; // zetta
2271 case 'Y': n
= 24; break; // yotta
2276 // We could weed some nonsense out, ODFF doesn't say so though.
2278 if (n
< 0 && Class() == CDC_Information
)
2279 n
= INV_MATCHLEV
; // milli-bits doesn't make sense
2282 //! <HACK> "cm3" is not 10^-2 m^3 but 10^-6 m^3 !!! ------------------
2283 if( n
!= INV_MATCHLEV
)
2285 sal_Unicode cLast
= p
[ aStr
.getLength() - 1 ];
2288 else if( cLast
== '3' )
2291 //! </HACK> -------------------------------------------------------------------
2295 else if ( nLen
> 2 && ( aName
== p
+ 2 ) && ( Class() == CDC_Information
) )
2297 const sal_Unicode
* pStr
= aStr
.getStr();
2298 if ( *(pStr
+ 1) != 'i')
2299 return INV_MATCHLEV
;
2303 case 'k': n
= 10; break;
2304 case 'M': n
= 20; break;
2305 case 'G': n
= 30; break;
2306 case 'T': n
= 40; break;
2307 case 'P': n
= 50; break;
2308 case 'E': n
= 60; break;
2309 case 'Z': n
= 70; break;
2310 case 'Y': n
= 80; break;
2317 return INV_MATCHLEV
;
2322 double ConvertData::Convert(
2323 double f
, const ConvertData
& r
, sal_Int16 nLevFrom
, sal_Int16 nLevTo
) const THROWDEF_RTE_IAE
2325 if( Class() != r
.Class() )
2328 sal_Bool bBinFromLev
= ( nLevFrom
> 0 && ( nLevFrom
% 10 ) == 0 );
2329 sal_Bool bBinToLev
= ( nLevTo
> 0 && ( nLevTo
% 10 ) == 0 );
2331 if ( Class() == CDC_Information
&& ( bBinFromLev
|| bBinToLev
) )
2333 if ( bBinFromLev
&& bBinToLev
)
2335 nLevFrom
= sal::static_int_cast
<sal_Int16
>( nLevFrom
- nLevTo
);
2336 f
*= r
.fConst
/ fConst
;
2338 f
*= pow( 2.0, nLevFrom
);
2340 else if ( bBinFromLev
)
2341 f
*= ( r
.fConst
/ fConst
) * ( pow( 2.0, nLevFrom
) / pow( 10.0, nLevTo
) );
2343 f
*= ( r
.fConst
/ fConst
) * ( pow( 10.0, nLevFrom
) / pow( 2.0, nLevTo
) );
2347 nLevFrom
= sal::static_int_cast
<sal_Int16
>( nLevFrom
- nLevTo
); // effective level
2349 f
*= r
.fConst
/ fConst
;
2352 f
= ::rtl::math::pow10Exp( f
, nLevFrom
);
2358 double ConvertData::ConvertToBase( double f
, sal_Int16 n
) const
2360 return ::rtl::math::pow10Exp( f
/ fConst
, n
);
2364 double ConvertData::ConvertFromBase( double f
, sal_Int16 n
) const
2366 return ::rtl::math::pow10Exp( f
* fConst
, -n
);
2371 ConvertDataLinear::~ConvertDataLinear()
2375 double ConvertDataLinear::Convert(
2376 double f
, const ConvertData
& r
, sal_Int16 nLevFrom
, sal_Int16 nLevTo
) const THROWDEF_RTE_IAE
2378 if( Class() != r
.Class() )
2380 return r
.ConvertFromBase( ConvertToBase( f
, nLevFrom
), nLevTo
);
2384 double ConvertDataLinear::ConvertToBase( double f
, sal_Int16 n
) const
2387 f
= ::rtl::math::pow10Exp( f
, n
);
2396 double ConvertDataLinear::ConvertFromBase( double f
, sal_Int16 n
) const
2402 f
= ::rtl::math::pow10Exp( f
, -n
);
2410 ConvertDataList::ConvertDataList( void )
2412 #define NEWD(str,unit,cl) Append(new ConvertData(str,unit,cl))
2413 #define NEWDP(str,unit,cl) Append(new ConvertData(str,unit,cl,sal_True))
2414 #define NEWL(str,unit,offs,cl) Append(new ConvertDataLinear(str,unit,offs,cl))
2415 #define NEWLP(str,unit,offs,cl) Append(new ConvertDataLinear(str,unit,offs,cl,sal_True))
2417 // *** are extra and not standard Excel Analysis Addin!
2419 // MASS: 1 Gram is...
2420 NEWDP( "g", 1.0000000000000000E00
, CDC_Mass
); // Gram
2421 NEWD( "sg", 6.8522050005347800E-05, CDC_Mass
); // Pieces
2422 NEWD( "lbm", 2.2046229146913400E-03, CDC_Mass
); // Pound (commercial weight)
2423 NEWDP( "u", 6.0221370000000000E23
, CDC_Mass
); // U (atomic mass)
2424 NEWD( "ozm", 3.5273971800362700E-02, CDC_Mass
); // Ounce (commercial weight)
2425 NEWD( "stone", 1.574730e-04, CDC_Mass
); // *** Stone
2426 NEWD( "ton", 1.102311e-06, CDC_Mass
); // *** Ton
2427 NEWD( "grain", 1.543236E01
, CDC_Mass
); // *** Grain
2428 NEWD( "pweight", 7.054792E-01, CDC_Mass
); // *** Pennyweight
2429 NEWD( "hweight", 1.968413E-05, CDC_Mass
); // *** Hundredweight
2430 NEWD( "shweight", 2.204623E-05, CDC_Mass
); // *** Shorthundredweight
2431 NEWD( "brton", 9.842065E-07, CDC_Mass
); // *** Gross Registered Ton
2432 NEWD( "cwt", 2.2046226218487758E-05, CDC_Mass
); // U.S. (short) hundredweight
2433 NEWD( "shweight", 2.2046226218487758E-05, CDC_Mass
); // U.S. (short) hundredweight also
2434 NEWD( "uk_cwt", 1.9684130552221213E-05, CDC_Mass
); // Imperial hundredweight
2435 NEWD( "lcwt", 1.9684130552221213E-05, CDC_Mass
); // Imperial hundredweight also
2436 NEWD( "hweight", 1.9684130552221213E-05, CDC_Mass
); // Imperial hundredweight also
2437 NEWD( "uk_ton", 9.8420652761106063E-07, CDC_Mass
); // Imperial ton
2438 NEWD( "LTON", 9.8420652761106063E-07, CDC_Mass
); // Imperial ton also
2440 // LENGTH: 1 Meter is...
2441 NEWDP( "m", 1.0000000000000000E00
, CDC_Length
); // Meter
2442 NEWD( "mi", 6.2137119223733397E-04, CDC_Length
); // Britsh Mile 6,21371192237333969617434184363e-4
2443 NEWD( "Nmi", 5.3995680345572354E-04, CDC_Length
); // Nautical Mile 5,39956803455723542116630669546e-4
2444 NEWD( "in", 3.9370078740157480E01
, CDC_Length
); // Inch 39,37007874015748031496062992126
2445 NEWD( "ft", 3.2808398950131234E00
, CDC_Length
); // Foot 3,2808398950131233595800524934383
2446 NEWD( "yd", 1.0936132983377078E00
, CDC_Length
); // Yard 1,0936132983377077865266841644794
2447 NEWDP( "ang", 1.0000000000000000E10
, CDC_Length
); // Angstroem
2448 NEWD( "Pica", 2.8346456692913386E03
, CDC_Length
); // Pica (1/72 Inch) 2834,6456692913385826771653543307
2449 NEWD( "ell", 8.748906E-01, CDC_Length
); // *** Ell
2450 NEWDP( "parsec", 3.240779E-17, CDC_Length
); // *** Parsec
2451 NEWDP( "pc", 3.240779E-17, CDC_Length
); // *** Parsec also
2452 NEWDP( "lightyear", 1.0570234557732930E-16, CDC_Length
); // *** Light Year
2453 NEWDP( "ly", 1.0570234557732930E-16, CDC_Length
); // *** Light Year also
2454 NEWD( "survey_mi", 6.2136994949494949E-04, CDC_Length
); // U.S. survey mile
2456 // TIME: 1 Second is...
2457 NEWD( "yr", 3.1688087814028950E-08, CDC_Time
); // Year
2458 NEWD( "day", 1.1574074074074074E-05, CDC_Time
); // Day
2459 NEWD( "d", 1.1574074074074074E-05, CDC_Time
); // Day also
2460 NEWD( "hr", 2.7777777777777778E-04, CDC_Time
); // Hour
2461 NEWD( "mn", 1.6666666666666667E-02, CDC_Time
); // Minute
2462 NEWD( "min", 1.6666666666666667E-02, CDC_Time
); // Minute also
2463 NEWDP( "sec", 1.0000000000000000E00
, CDC_Time
); // Second
2464 NEWDP( "s", 1.0000000000000000E00
, CDC_Time
); // Second also
2466 // PRESSURE: 1 Pascal is...
2467 NEWDP( "Pa", 1.0000000000000000E00
, CDC_Pressure
); // Pascal
2468 NEWDP( "atm", 9.8692329999819300E-06, CDC_Pressure
); // Atmosphere
2469 NEWDP( "at", 9.8692329999819300E-06, CDC_Pressure
); // Atmosphere also
2470 NEWDP( "mmHg", 7.5006170799862700E-03, CDC_Pressure
); // mm Hg (Mercury)
2471 NEWD( "Torr", 7.5006380000000000E-03, CDC_Pressure
); // *** Torr
2472 NEWD( "psi", 1.4503770000000000E-04, CDC_Pressure
); // *** Psi
2474 // FORCE: 1 Newton is...
2475 NEWDP( "N", 1.0000000000000000E00
, CDC_Force
); // Newton
2476 NEWDP( "dyn", 1.0000000000000000E05
, CDC_Force
); // Dyn
2477 NEWDP( "dy", 1.0000000000000000E05
, CDC_Force
); // Dyn also
2478 NEWD( "lbf", 2.24808923655339E-01, CDC_Force
); // Pound-Force
2479 NEWDP( "pond", 1.019716E02
, CDC_Force
); // *** Pond
2481 // ENERGY: 1 Joule is...
2482 NEWDP( "J", 1.0000000000000000E00
, CDC_Energy
); // Joule
2483 NEWDP( "e", 1.0000000000000000E07
, CDC_Energy
); // Erg -> http://www.chemie.fu-berlin.de/chemistry/general/si.html
2484 NEWDP( "c", 2.3900624947346700E-01, CDC_Energy
); // Thermodynamical Calorie
2485 NEWDP( "cal", 2.3884619064201700E-01, CDC_Energy
); // Calorie
2486 NEWDP( "eV", 6.2414570000000000E18
, CDC_Energy
); // Electronvolt
2487 NEWDP( "ev", 6.2414570000000000E18
, CDC_Energy
); // Electronvolt also
2488 NEWD( "HPh", 3.7250611111111111E-07, CDC_Energy
); // Horsepower Hours
2489 NEWD( "hh", 3.7250611111111111E-07, CDC_Energy
); // Horsepower Hours also
2490 NEWDP( "Wh", 2.7777777777777778E-04, CDC_Energy
); // Watt Hours
2491 NEWDP( "wh", 2.7777777777777778E-04, CDC_Energy
); // Watt Hours also
2492 NEWD( "flb", 2.37304222192651E01
, CDC_Energy
); // Foot Pound
2493 NEWD( "BTU", 9.4781506734901500E-04, CDC_Energy
); // British Thermal Unit
2494 NEWD( "btu", 9.4781506734901500E-04, CDC_Energy
); // British Thermal Unit also
2496 // POWER: 1 Watt is...
2497 NEWDP( "W", 1.0000000000000000E00
, CDC_Power
); // Watt
2498 NEWDP( "w", 1.0000000000000000E00
, CDC_Power
); // Watt also
2499 NEWD( "HP", 1.341022E-03, CDC_Power
); // Horsepower
2500 NEWD( "h", 1.341022E-03, CDC_Power
); // Horsepower also
2501 NEWD( "PS", 1.359622E-03, CDC_Power
); // *** German Pferdestaerke
2503 // MAGNETISM: 1 Tesla is...
2504 NEWDP( "T", 1.0000000000000000E00
, CDC_Magnetism
); // Tesla
2505 NEWDP( "ga", 1.0000000000000000E04
, CDC_Magnetism
); // Gauss
2507 // TEMERATURE: 1 Kelvin is...
2508 NEWL( "C", 1.0000000000000000E00
, -2.7315000000000000E02
, CDC_Temperature
); // Celsius
2509 NEWL( "cel", 1.0000000000000000E00
, -2.7315000000000000E02
, CDC_Temperature
); // Celsius also
2510 NEWL( "F", 1.8000000000000000E00
, -2.5537222222222222E02
, CDC_Temperature
); // Fahrenheit
2511 NEWL( "fah", 1.8000000000000000E00
, -2.5537222222222222E02
, CDC_Temperature
); // Fahrenheit also
2512 NEWLP( "K", 1.0000000000000000E00
, +0.0000000000000000E00
, CDC_Temperature
); // Kelvin
2513 NEWLP( "kel", 1.0000000000000000E00
, +0.0000000000000000E00
, CDC_Temperature
); // Kelvin also
2514 NEWL( "Reau", 8.0000000000000000E-01, -2.7315000000000000E02
, CDC_Temperature
); // *** Reaumur
2515 NEWL( "Rank", 1.8000000000000000E00
, +0.0000000000000000E00
, CDC_Temperature
); // *** Rankine
2517 // VOLUMNE: 1 Liter is...
2518 NEWD( "tsp", 2.0288413621105798E02
, CDC_Volume
); // US teaspoon 1/768 gallon
2519 NEWD( "tbs", 6.7628045403685994E01
, CDC_Volume
); // US tablespoon 1/256 gallon
2520 NEWD( "oz", 3.3814022701842997E01
, CDC_Volume
); // Ounce Liquid 1/128 gallon
2521 NEWD( "cup", 4.2267528377303746E00
, CDC_Volume
); // Cup 1/16 gallon
2522 NEWD( "pt", 2.1133764188651873E00
, CDC_Volume
); // US Pint 1/8 gallon
2523 NEWD( "us_pt", 2.1133764188651873E00
, CDC_Volume
); // US Pint also
2524 NEWD( "uk_pt", 1.7597539863927023E00
, CDC_Volume
); // UK Pint 1/8 imperial gallon
2525 NEWD( "qt", 1.0566882094325937E00
, CDC_Volume
); // Quart 1/4 gallon
2526 NEWD( "gal", 2.6417205235814842E-01, CDC_Volume
); // Gallon 1/3.785411784
2527 NEWDP( "l", 1.0000000000000000E00
, CDC_Volume
); // Liter
2528 NEWDP( "L", 1.0000000000000000E00
, CDC_Volume
); // Liter also
2529 NEWDP( "lt", 1.0000000000000000E00
, CDC_Volume
); // Liter also
2530 NEWDP( "m3", 1.0000000000000000E-03, CDC_Volume
); // *** Cubic Meter
2531 NEWD( "mi3", 2.3991275857892772E-13, CDC_Volume
); // *** Cubic Britsh Mile
2532 NEWD( "Nmi3", 1.5742621468581148E-13, CDC_Volume
); // *** Cubic Nautical Mile
2533 NEWD( "in3", 6.1023744094732284E01
, CDC_Volume
); // *** Cubic Inch
2534 NEWD( "ft3", 3.5314666721488590E-02, CDC_Volume
); // *** Cubic Foot
2535 NEWD( "yd3", 1.3079506193143922E-03, CDC_Volume
); // *** Cubic Yard
2536 NEWDP( "ang3", 1.0000000000000000E27
, CDC_Volume
); // *** Cubic Angstroem
2537 NEWD( "Pica3", 2.2776990435870636E07
, CDC_Volume
); // *** Cubic Pica
2538 NEWD( "barrel", 6.2898107704321051E-03, CDC_Volume
); // *** Barrel (=42gal)
2539 NEWD( "bushel", 2.837759E-02, CDC_Volume
); // *** Bushel
2540 NEWD( "regton", 3.531467E-04, CDC_Volume
); // *** Register ton
2541 NEWD( "GRT", 3.531467E-04, CDC_Volume
); // *** Register ton also
2542 NEWD( "Schooner", 2.3529411764705882E00
, CDC_Volume
); // *** austr. Schooner
2543 NEWD( "Middy", 3.5087719298245614E00
, CDC_Volume
); // *** austr. Middy
2544 NEWD( "Glass", 5.0000000000000000E00
, CDC_Volume
); // *** austr. Glass
2545 NEWD( "Sixpack", 0.5, CDC_Volume
); // ***
2546 NEWD( "Humpen", 2.0, CDC_Volume
); // ***
2547 NEWD( "ly3", 1.1810108125623799E-51, CDC_Volume
); // *** Cubic light-year
2548 NEWD( "MTON", 1.4125866688595436E00
, CDC_Volume
); // *** Measurement ton
2549 NEWD( "tspm", 5.0000000000000000E02
, CDC_Volume
); // *** Modern teaspoon
2550 NEWD( "uk_gal", 2.1996924829908779E-01, CDC_Volume
); // U.K. / Imperial gallon 1/4.54609
2551 NEWD( "uk_qt", 8.7987699319635115E-01, CDC_Volume
); // U.K. / Imperial quart 1/4 imperial gallon
2553 // 1 Square Meter is...
2554 NEWDP( "m2", 1.0000000000000000E00
, CDC_Area
); // *** Square Meter
2555 NEWD( "mi2", 3.8610215854244585E-07, CDC_Area
); // *** Square Britsh Mile
2556 NEWD( "Nmi2", 2.9155334959812286E-07, CDC_Area
); // *** Square Nautical Mile
2557 NEWD( "in2", 1.5500031000062000E03
, CDC_Area
); // *** Square Inch
2558 NEWD( "ft2", 1.0763910416709722E01
, CDC_Area
); // *** Square Foot
2559 NEWD( "yd2", 1.1959900463010803E00
, CDC_Area
); // *** Square Yard
2560 NEWDP( "ang2", 1.0000000000000000E20
, CDC_Area
); // *** Square Angstroem
2561 NEWD( "Pica2", 8.0352160704321409E06
, CDC_Area
); // *** Square Pica
2562 NEWD( "Morgen", 4.0000000000000000E-04, CDC_Area
); // *** Morgen
2563 NEWDP( "ar", 1.000000E-02, CDC_Area
); // *** Ar
2564 NEWD( "acre", 2.471053815E-04, CDC_Area
); // *** Acre
2565 NEWD( "uk_acre", 2.4710538146716534E-04, CDC_Area
); // *** International acre
2566 NEWD( "us_acre", 2.4710439304662790E-04, CDC_Area
); // *** U.S. survey/statute acre
2567 NEWD( "ly2", 1.1172985860549147E-32, CDC_Area
); // *** Square Light-year
2568 NEWD( "ha", 1.000000E-04, CDC_Area
); // *** Hectare
2569 NEWD( "Quadratlatschen",5.6689342403628117914,CDC_Area
); // ***
2571 // SPEED: 1 Meter per Second is...
2572 NEWDP( "m/s", 1.0000000000000000E00
, CDC_Speed
); // *** Meters per Second
2573 NEWDP( "m/sec", 1.0000000000000000E00
, CDC_Speed
); // *** Meters per Second also
2574 NEWDP( "m/h", 3.6000000000000000E03
, CDC_Speed
); // *** Meters per Hour
2575 NEWDP( "m/hr", 3.6000000000000000E03
, CDC_Speed
); // *** Meters per Hour also
2576 NEWD( "mph", 2.2369362920544023E00
, CDC_Speed
); // *** Britsh Miles per Hour
2577 NEWD( "kn", 1.9438444924406048E00
, CDC_Speed
); // *** Knot = Nautical Miles per Hour
2578 NEWD( "admkn", 1.9438446603753486E00
, CDC_Speed
); // *** Admiralty Knot
2579 NEWD( "wahnsinnige Geschwindigkeit", 2.0494886343432328E-14, CDC_Speed
); // ***
2580 NEWD( "ludicrous speed", 2.0494886343432328E-14, CDC_Speed
); // ***
2581 NEWD( "laecherliche Geschwindigkeit", 4.0156958471424288E-06, CDC_Speed
); // ***
2582 NEWD( "ridiculous speed", 4.0156958471424288E-06, CDC_Speed
); // ***
2584 // INFORMATION: 1 Bit is...
2585 NEWDP( "bit", 1.00E00
, CDC_Information
); // *** Bit
2586 NEWDP( "byte", 1.25E-01, CDC_Information
); // *** Byte
2590 ConvertDataList::~ConvertDataList()
2592 for( ConvertData
* p
= First() ; p
; p
= Next() )
2597 double ConvertDataList::Convert( double fVal
, const STRING
& rFrom
, const STRING
& rTo
) THROWDEF_RTE_IAE
2599 ConvertData
* pFrom
= NULL
;
2600 ConvertData
* pTo
= NULL
;
2601 sal_Bool bSearchFrom
= sal_True
;
2602 sal_Bool bSearchTo
= sal_True
;
2603 sal_Int16 nLevelFrom
= 0;
2604 sal_Int16 nLevelTo
= 0;
2606 ConvertData
* p
= First();
2607 while( p
&& ( bSearchFrom
|| bSearchTo
) )
2611 sal_Int16 n
= p
->GetMatchingLevel( rFrom
);
2612 if( n
!= INV_MATCHLEV
)
2615 { // only first match for partial equality rulz a little bit more
2620 { // ... but exact match rulz most
2622 bSearchFrom
= sal_False
;
2630 sal_Int16 n
= p
->GetMatchingLevel( rTo
);
2631 if( n
!= INV_MATCHLEV
)
2634 { // only first match for partial equality rulz a little bit more
2639 { // ... but exact match rulz most
2641 bSearchTo
= sal_False
;
2651 return pFrom
->Convert( fVal
, *pTo
, nLevelFrom
, nLevelTo
);
2658 //-----------------------------------------------------------------------------
2660 ScaDate::ScaDate() :
2665 bLastDayMode( sal_True
),
2666 bLastDay( sal_False
),
2667 b30Days( sal_False
),
2668 bUSMode( sal_False
)
2672 ScaDate::ScaDate( sal_Int32 nNullDate
, sal_Int32 nDate
, sal_Int32 nBase
)
2674 DaysToDate( nNullDate
+ nDate
, nOrigDay
, nMonth
, nYear
);
2675 bLastDayMode
= (nBase
!= 5);
2676 bLastDay
= (nOrigDay
>= ::DaysInMonth( nMonth
, nYear
));
2677 b30Days
= (nBase
== 0) || (nBase
== 4);
2678 bUSMode
= (nBase
== 0);
2682 ScaDate::ScaDate( const ScaDate
& rCopy
) :
2683 nOrigDay( rCopy
.nOrigDay
),
2685 nMonth( rCopy
.nMonth
),
2686 nYear( rCopy
.nYear
),
2687 bLastDayMode( rCopy
.bLastDayMode
),
2688 bLastDay( rCopy
.bLastDay
),
2689 b30Days( rCopy
.b30Days
),
2690 bUSMode( rCopy
.bUSMode
)
2694 ScaDate
& ScaDate::operator=( const ScaDate
& rCopy
)
2696 if( this != &rCopy
)
2698 nOrigDay
= rCopy
.nOrigDay
;
2700 nMonth
= rCopy
.nMonth
;
2701 nYear
= rCopy
.nYear
;
2702 bLastDayMode
= rCopy
.bLastDayMode
;
2703 bLastDay
= rCopy
.bLastDay
;
2704 b30Days
= rCopy
.b30Days
;
2705 bUSMode
= rCopy
.bUSMode
;
2710 void ScaDate::setDay()
2714 // 30-days-mode: set nDay to 30 if original was last day in month
2715 nDay
= Min( nOrigDay
, static_cast< sal_uInt16
>( 30 ) );
2716 if( bLastDay
|| (nDay
>= ::DaysInMonth( nMonth
, nYear
)) )
2721 // set nDay to last day in this month if original was last day
2722 sal_uInt16 nLastDay
= ::DaysInMonth( nMonth
, nYear
);
2723 nDay
= bLastDay
? nLastDay
: Min( nOrigDay
, nLastDay
);
2727 sal_Int32
ScaDate::getDaysInMonthRange( sal_uInt16 nFrom
, sal_uInt16 nTo
) const
2734 nRet
= (nTo
- nFrom
+ 1) * 30;
2737 for( sal_uInt16 nMonthIx
= nFrom
; nMonthIx
<= nTo
; ++nMonthIx
)
2738 nRet
+= getDaysInMonth( nMonthIx
);
2743 sal_Int32
ScaDate::getDaysInYearRange( sal_uInt16 nFrom
, sal_uInt16 nTo
) const
2748 return b30Days
? ((nTo
- nFrom
+ 1) * 360) : ::GetDaysInYears( nFrom
, nTo
);
2751 void ScaDate::doAddYears( sal_Int32 nYearCount
) throw( lang::IllegalArgumentException
)
2753 sal_Int32 nNewYear
= nYearCount
+ nYear
;
2754 if( (nNewYear
< 0) || (nNewYear
> 0x7FFF) )
2755 throw lang::IllegalArgumentException();
2756 nYear
= static_cast< sal_uInt16
>( nNewYear
);
2759 void ScaDate::addMonths( sal_Int32 nMonthCount
) throw( lang::IllegalArgumentException
)
2761 sal_Int32 nNewMonth
= nMonthCount
+ nMonth
;
2762 if( nNewMonth
> 12 )
2765 doAddYears( nNewMonth
/ 12 );
2766 nMonth
= static_cast< sal_uInt16
>( nNewMonth
% 12 ) + 1;
2768 else if( nNewMonth
< 1 )
2770 doAddYears( nNewMonth
/ 12 - 1 );
2771 nMonth
= static_cast< sal_uInt16
>( nNewMonth
% 12 + 12 );
2774 nMonth
= static_cast< sal_uInt16
>( nNewMonth
);
2778 sal_Int32
ScaDate::getDate( sal_Int32 nNullDate
) const
2780 sal_uInt16 nLastDay
= ::DaysInMonth( nMonth
, nYear
);
2781 sal_uInt16 nRealDay
= (bLastDayMode
&& bLastDay
) ? nLastDay
: Min( nLastDay
, nOrigDay
);
2782 return ::DateToDays( nRealDay
, nMonth
, nYear
) - nNullDate
;
2785 sal_Int32
ScaDate::getDiff( const ScaDate
& rFrom
, const ScaDate
& rTo
) throw( lang::IllegalArgumentException
)
2788 return getDiff( rTo
, rFrom
);
2790 sal_Int32 nDiff
= 0;
2791 ScaDate
aFrom( rFrom
);
2796 // corrections for base 0 (US NASD)
2799 if( ((rFrom
.nMonth
== 2) || (rFrom
.nDay
< 30)) && (aTo
.nOrigDay
== 31) )
2801 else if( (aTo
.nMonth
== 2) && aTo
.bLastDay
)
2802 aTo
.nDay
= ::DaysInMonth( 2, aTo
.nYear
);
2804 // corrections for base 4 (Europe)
2807 if( (aFrom
.nMonth
== 2) && (aFrom
.nDay
== 30) )
2808 aFrom
.nDay
= ::DaysInMonth( 2, aFrom
.nYear
);
2809 if( (aTo
.nMonth
== 2) && (aTo
.nDay
== 30) )
2810 aTo
.nDay
= ::DaysInMonth( 2, aTo
.nYear
);
2814 if( (aFrom
.nYear
< aTo
.nYear
) || ((aFrom
.nYear
== aTo
.nYear
) && (aFrom
.nMonth
< aTo
.nMonth
)) )
2816 // move aFrom to 1st day of next month
2817 nDiff
= aFrom
.getDaysInMonth() - aFrom
.nDay
+ 1;
2818 aFrom
.nOrigDay
= aFrom
.nDay
= 1;
2819 aFrom
.bLastDay
= sal_False
;
2820 aFrom
.addMonths( 1 );
2822 if( aFrom
.nYear
< aTo
.nYear
)
2824 // move aFrom to 1st day of next year
2825 nDiff
+= aFrom
.getDaysInMonthRange( aFrom
.nMonth
, 12 );
2826 aFrom
.addMonths( 13 - aFrom
.nMonth
);
2828 // move aFrom to 1st day of this year
2829 nDiff
+= aFrom
.getDaysInYearRange( aFrom
.nYear
, aTo
.nYear
- 1 );
2830 aFrom
.addYears( aTo
.nYear
- aFrom
.nYear
);
2833 // move aFrom to 1st day of this month
2834 nDiff
+= aFrom
.getDaysInMonthRange( aFrom
.nMonth
, aTo
.nMonth
- 1 );
2835 aFrom
.addMonths( aTo
.nMonth
- aFrom
.nMonth
);
2837 // finally add remaining days in this month
2838 nDiff
+= aTo
.nDay
- aFrom
.nDay
;
2839 return nDiff
> 0 ? nDiff
: 0;
2842 sal_Bool
ScaDate::operator<( const ScaDate
& rCmp
) const
2844 if( nYear
!= rCmp
.nYear
)
2845 return nYear
< rCmp
.nYear
;
2846 if( nMonth
!= rCmp
.nMonth
)
2847 return nMonth
< rCmp
.nMonth
;
2848 if( nDay
!= rCmp
.nDay
)
2849 return nDay
< rCmp
.nDay
;
2850 if( bLastDay
|| rCmp
.bLastDay
)
2851 return !bLastDay
&& rCmp
.bLastDay
;
2852 return nOrigDay
< rCmp
.nOrigDay
;
2857 //-----------------------------------------------------------------------------
2859 ScaAnyConverter::ScaAnyConverter( const uno::Reference
< lang::XMultiServiceFactory
>& xServiceFact
) :
2860 bHasValidFormat( sal_False
)
2862 if( xServiceFact
.is() )
2864 uno::Reference
< uno::XInterface
> xInstance
= xServiceFact
->createInstance(
2865 OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatter" )) );
2866 xFormatter
= uno::Reference
< util::XNumberFormatter
>( xInstance
, uno::UNO_QUERY
);
2870 ScaAnyConverter::~ScaAnyConverter()
2874 void ScaAnyConverter::init( const uno::Reference
< beans::XPropertySet
>& xPropSet
) throw( uno::RuntimeException
)
2876 // try to get default number format
2877 bHasValidFormat
= sal_False
;
2878 if( xFormatter
.is() )
2880 // get XFormatsSupplier from outer XPropertySet
2881 uno::Reference
< util::XNumberFormatsSupplier
> xFormatsSupp( xPropSet
, uno::UNO_QUERY
);
2882 if( xFormatsSupp
.is() )
2884 // get XNumberFormatTypes from XNumberFormatsSupplier to get standard index
2885 uno::Reference
< util::XNumberFormats
> xFormats( xFormatsSupp
->getNumberFormats() );
2886 uno::Reference
< util::XNumberFormatTypes
> xFormatTypes( xFormats
, uno::UNO_QUERY
);
2887 if( xFormatTypes
.is() )
2889 lang::Locale eLocale
;
2890 nDefaultFormat
= xFormatTypes
->getStandardIndex( eLocale
);
2891 xFormatter
->attachNumberFormatsSupplier( xFormatsSupp
);
2892 bHasValidFormat
= sal_True
;
2898 double ScaAnyConverter::convertToDouble( const OUString
& rString
) const throw( lang::IllegalArgumentException
)
2900 double fValue
= 0.0;
2901 if( bHasValidFormat
)
2905 fValue
= xFormatter
->convertStringToNumber( nDefaultFormat
, rString
);
2907 catch( uno::Exception
& )
2909 throw lang::IllegalArgumentException();
2914 rtl_math_ConversionStatus eStatus
;
2916 fValue
= ::rtl::math::stringToDouble( rString
, '.', ',', &eStatus
, &nEnd
);
2917 if( (eStatus
!= rtl_math_ConversionStatus_Ok
) || (nEnd
< rString
.getLength()) )
2918 throw lang::IllegalArgumentException();
2923 sal_Bool
ScaAnyConverter::getDouble(
2925 const uno::Any
& rAny
) const throw( lang::IllegalArgumentException
)
2928 sal_Bool bContainsVal
= sal_True
;
2929 switch( rAny
.getValueTypeClass() )
2931 case uno::TypeClass_VOID
:
2932 bContainsVal
= sal_False
;
2934 case uno::TypeClass_DOUBLE
:
2937 case uno::TypeClass_STRING
:
2939 const OUString
* pString
= static_cast< const OUString
* >( rAny
.getValue() );
2940 if( !pString
->isEmpty() )
2941 rfResult
= convertToDouble( *pString
);
2943 bContainsVal
= sal_False
;
2947 throw lang::IllegalArgumentException();
2949 return bContainsVal
;
2952 sal_Bool
ScaAnyConverter::getDouble(
2954 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
2955 const uno::Any
& rAny
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
2958 return getDouble( rfResult
, rAny
);
2961 double ScaAnyConverter::getDouble(
2962 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
2963 const uno::Any
& rAny
,
2964 double fDefault
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
2967 if( !getDouble( fResult
, xPropSet
, rAny
) )
2972 sal_Bool
ScaAnyConverter::getInt32(
2973 sal_Int32
& rnResult
,
2974 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
2975 const uno::Any
& rAny
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
2978 sal_Bool bContainsVal
= getDouble( fResult
, xPropSet
, rAny
);
2979 if( (fResult
<= -2147483649.0) || (fResult
>= 2147483648.0) )
2980 throw lang::IllegalArgumentException();
2982 rnResult
= static_cast< sal_Int32
>( fResult
);
2983 return bContainsVal
;
2986 sal_Int32
ScaAnyConverter::getInt32(
2987 const uno::Reference
< beans::XPropertySet
>& xPropSet
,
2988 const uno::Any
& rAny
,
2989 sal_Int32 nDefault
) throw( uno::RuntimeException
, lang::IllegalArgumentException
)
2992 if( !getInt32( nResult
, xPropSet
, rAny
) )
2999 //-----------------------------------------------------------------------------
3002 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */