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