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