2001-04-06 12:59:16 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2005-09-08 22:20:16 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
2005-09-08 22:20:16 +00:00
|
|
|
* $RCSfile: analysishelper.cxx,v $
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
2007-04-26 07:10:20 +00:00
|
|
|
* $Revision: 1.54 $
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
2007-04-26 07:10:20 +00:00
|
|
|
* last change: $Author: rt $ $Date: 2007-04-26 08:10:20 $
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
2005-09-08 22:20:16 +00:00
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
|
|
|
*
|
2005-09-08 22:20:16 +00:00
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
2005-09-08 22:20:16 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
2005-09-08 22:20:16 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
2005-09-08 22:20:16 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
2001-04-06 12:59:16 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2001-10-25 10:08:29 +00:00
|
|
|
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
|
|
|
|
#include <com/sun/star/util/XNumberFormatTypes.hpp>
|
|
|
|
#endif
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2001-10-02 06:48:57 +00:00
|
|
|
#include <tools/resary.hxx>
|
2003-03-26 16:46:50 +00:00
|
|
|
#include <rtl/math.hxx>
|
2001-05-14 07:38:20 +00:00
|
|
|
#include "analysishelper.hxx"
|
2001-06-18 12:00:32 +00:00
|
|
|
#include "analysis.hrc"
|
|
|
|
|
2001-10-02 06:48:57 +00:00
|
|
|
using namespace ::rtl;
|
|
|
|
using namespace ::com::sun::star;
|
2001-06-18 12:00:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2001-10-02 06:48:57 +00:00
|
|
|
#define UNIQUE sal_False // function name does not exist in Calc
|
|
|
|
#define DOUBLE sal_True // function name exists in Calc
|
2001-06-18 12:00:32 +00:00
|
|
|
|
2001-10-02 06:48:57 +00:00
|
|
|
#define STDPAR sal_False // all parameters are described
|
|
|
|
#define INTPAR sal_True // first parameter is internal
|
|
|
|
|
|
|
|
#define FUNCDATA( FUNCNAME, DBL, OPT, NUMOFPAR, CAT ) \
|
|
|
|
{ "get" #FUNCNAME, ANALYSIS_FUNCNAME_##FUNCNAME, ANALYSIS_##FUNCNAME, DBL, OPT, ANALYSIS_DEFFUNCNAME_##FUNCNAME, NUMOFPAR, CAT }
|
2001-06-18 12:00:32 +00:00
|
|
|
|
|
|
|
const FuncDataBase pFuncDatas[] =
|
|
|
|
{
|
2001-10-02 06:48:57 +00:00
|
|
|
// UNIQUE or INTPAR or
|
|
|
|
// function name DOUBLE STDPAR # of param category
|
|
|
|
FUNCDATA( Workday, UNIQUE, INTPAR, 3, FDCat_DateTime ),
|
|
|
|
FUNCDATA( Yearfrac, UNIQUE, INTPAR, 3, FDCat_DateTime ),
|
|
|
|
FUNCDATA( Edate, UNIQUE, INTPAR, 2, FDCat_DateTime ),
|
|
|
|
FUNCDATA( Weeknum, DOUBLE, INTPAR, 2, FDCat_DateTime ),
|
|
|
|
FUNCDATA( Eomonth, UNIQUE, INTPAR, 2, FDCat_DateTime ),
|
|
|
|
FUNCDATA( Networkdays, UNIQUE, INTPAR, 3, FDCat_DateTime ),
|
|
|
|
FUNCDATA( Iseven, DOUBLE, STDPAR, 1, FDCat_Inf ),
|
|
|
|
FUNCDATA( Isodd, DOUBLE, STDPAR, 1, FDCat_Inf ),
|
|
|
|
FUNCDATA( Multinomial, UNIQUE, STDPAR, 1, FDCat_Math ),
|
|
|
|
FUNCDATA( Seriessum, UNIQUE, STDPAR, 4, FDCat_Math ),
|
|
|
|
FUNCDATA( Quotient, UNIQUE, STDPAR, 2, FDCat_Math ),
|
|
|
|
FUNCDATA( Mround, UNIQUE, STDPAR, 2, FDCat_Math ),
|
|
|
|
FUNCDATA( Sqrtpi, UNIQUE, STDPAR, 1, FDCat_Math ),
|
|
|
|
FUNCDATA( Randbetween, UNIQUE, STDPAR, 2, FDCat_Math ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Gcd, DOUBLE, INTPAR, 1, FDCat_Math ),
|
|
|
|
FUNCDATA( Lcm, DOUBLE, INTPAR, 1, FDCat_Math ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Besseli, UNIQUE, STDPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Besselj, UNIQUE, STDPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Besselk, UNIQUE, STDPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Bessely, UNIQUE, STDPAR, 2, FDCat_Tech ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Bin2Oct, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Bin2Dec, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Bin2Hex, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Oct2Bin, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Oct2Dec, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Oct2Hex, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Dec2Bin, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Dec2Hex, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Dec2Oct, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Hex2Bin, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Hex2Dec, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Hex2Oct, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Delta, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Erf, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Erfc, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Gestep, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Factdouble, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imabs, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imaginary, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Impower, UNIQUE, STDPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imargument, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imcos, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imdiv, UNIQUE, STDPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imexp, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imconjugate, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imln, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imlog10, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imlog2, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Improduct, UNIQUE, INTPAR, 2, FDCat_Tech ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Imreal, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imsin, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imsub, UNIQUE, STDPAR, 2, FDCat_Tech ),
|
|
|
|
FUNCDATA( Imsqrt, UNIQUE, STDPAR, 1, FDCat_Tech ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Imsum, UNIQUE, INTPAR, 1, FDCat_Tech ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Complex, UNIQUE, STDPAR, 3, FDCat_Tech ),
|
|
|
|
FUNCDATA( Convert, DOUBLE, STDPAR, 3, FDCat_Tech ),
|
|
|
|
FUNCDATA( Amordegrc, UNIQUE, INTPAR, 7, FDCat_Finance ),
|
|
|
|
FUNCDATA( Amorlinc, UNIQUE, INTPAR, 7, FDCat_Finance ),
|
|
|
|
FUNCDATA( Accrint, UNIQUE, INTPAR, 7, FDCat_Finance ),
|
|
|
|
FUNCDATA( Accrintm, UNIQUE, INTPAR, 5, FDCat_Finance ),
|
|
|
|
FUNCDATA( Received, UNIQUE, INTPAR, 5, FDCat_Finance ),
|
|
|
|
FUNCDATA( Disc, UNIQUE, INTPAR, 5, FDCat_Finance ),
|
|
|
|
FUNCDATA( Duration, DOUBLE, INTPAR, 6, FDCat_Finance ),
|
|
|
|
FUNCDATA( Effect, DOUBLE, STDPAR, 2, FDCat_Finance ),
|
|
|
|
FUNCDATA( Cumprinc, DOUBLE, STDPAR, 6, FDCat_Finance ),
|
|
|
|
FUNCDATA( Cumipmt, DOUBLE, STDPAR, 6, FDCat_Finance ),
|
|
|
|
FUNCDATA( Price, UNIQUE, INTPAR, 7, FDCat_Finance ),
|
|
|
|
FUNCDATA( Pricedisc, UNIQUE, INTPAR, 5, FDCat_Finance ),
|
|
|
|
FUNCDATA( Pricemat, UNIQUE, INTPAR, 6, FDCat_Finance ),
|
|
|
|
FUNCDATA( Mduration, UNIQUE, INTPAR, 6, FDCat_Finance ),
|
|
|
|
FUNCDATA( Nominal, DOUBLE, STDPAR, 2, FDCat_Finance ),
|
|
|
|
FUNCDATA( Dollarfr, UNIQUE, STDPAR, 2, FDCat_Finance ),
|
|
|
|
FUNCDATA( Dollarde, UNIQUE, STDPAR, 2, FDCat_Finance ),
|
|
|
|
FUNCDATA( Yield, UNIQUE, INTPAR, 7, FDCat_Finance ),
|
|
|
|
FUNCDATA( Yielddisc, UNIQUE, INTPAR, 5, FDCat_Finance ),
|
|
|
|
FUNCDATA( Yieldmat, UNIQUE, INTPAR, 6, FDCat_Finance ),
|
|
|
|
FUNCDATA( Tbilleq, UNIQUE, INTPAR, 3, FDCat_Finance ),
|
|
|
|
FUNCDATA( Tbillprice, UNIQUE, INTPAR, 3, FDCat_Finance ),
|
|
|
|
FUNCDATA( Tbillyield, UNIQUE, INTPAR, 3, FDCat_Finance ),
|
|
|
|
FUNCDATA( Oddfprice, UNIQUE, INTPAR, 9, FDCat_Finance ),
|
|
|
|
FUNCDATA( Oddfyield, UNIQUE, INTPAR, 9, FDCat_Finance ),
|
|
|
|
FUNCDATA( Oddlprice, UNIQUE, INTPAR, 8, FDCat_Finance ),
|
|
|
|
FUNCDATA( Oddlyield, UNIQUE, INTPAR, 8, FDCat_Finance ),
|
2001-10-09 10:09:01 +00:00
|
|
|
FUNCDATA( Xirr, UNIQUE, INTPAR, 3, FDCat_Finance ),
|
2001-10-02 06:48:57 +00:00
|
|
|
FUNCDATA( Xnpv, UNIQUE, STDPAR, 3, FDCat_Finance ),
|
|
|
|
FUNCDATA( Intrate, UNIQUE, INTPAR, 5, FDCat_Finance ),
|
|
|
|
FUNCDATA( Coupncd, UNIQUE, INTPAR, 4, FDCat_Finance ),
|
|
|
|
FUNCDATA( Coupdays, UNIQUE, INTPAR, 4, FDCat_Finance ),
|
|
|
|
FUNCDATA( Coupdaysnc, UNIQUE, INTPAR, 4, FDCat_Finance ),
|
|
|
|
FUNCDATA( Coupdaybs, UNIQUE, INTPAR, 4, FDCat_Finance ),
|
|
|
|
FUNCDATA( Couppcd, UNIQUE, INTPAR, 4, FDCat_Finance ),
|
|
|
|
FUNCDATA( Coupnum, UNIQUE, INTPAR, 4, FDCat_Finance ),
|
|
|
|
FUNCDATA( Fvschedule, UNIQUE, STDPAR, 2, FDCat_Finance )
|
2001-06-18 12:00:32 +00:00
|
|
|
};
|
2001-10-02 06:48:57 +00:00
|
|
|
#undef FUNCDATA
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
/*double _Test( sal_Int32 nMode, double f1, double f2, double f3 )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
double f = -1.0;
|
|
|
|
switch( nMode )
|
|
|
|
{
|
|
|
|
case 0: f = GammaN( f1, sal_uInt32( f2 ) ); break;
|
|
|
|
case 1: f = Gamma( f1 ); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return f;
|
2001-05-07 05:56:53 +00:00
|
|
|
}*/
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
static sal_uInt16 aDaysInMonth[ 13 ] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
|
|
|
|
|
|
|
sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
|
|
|
|
{
|
|
|
|
|
|
|
|
if( nMonth != 2 )
|
|
|
|
return aDaysInMonth[ nMonth ];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( IsLeapYear( nYear ) )
|
|
|
|
return aDaysInMonth[ nMonth ] + 1;
|
|
|
|
else
|
|
|
|
return aDaysInMonth[ nMonth ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16, sal_Bool bLeapYear )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
if( nMonth != 2 )
|
|
|
|
return aDaysInMonth[ nMonth ];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( bLeapYear )
|
|
|
|
return aDaysInMonth[ nMonth ] + 1;
|
|
|
|
else
|
|
|
|
return aDaysInMonth[ nMonth ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a date to a count of days starting from 01/01/0001
|
|
|
|
*
|
|
|
|
* The internal representation of a Date used in this Addin
|
|
|
|
* is the number of days between 01/01/0001 and the date
|
|
|
|
* this function converts a Day , Month, Year representation
|
|
|
|
* to this internal Date value.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
|
|
|
|
{
|
|
|
|
sal_Int32 nDays = ((sal_Int32)nYear-1) * 365;
|
|
|
|
nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
|
|
|
|
|
|
|
|
for( sal_uInt16 i = 1; i < nMonth; i++ )
|
|
|
|
nDays += DaysInMonth(i,nYear);
|
|
|
|
nDays += nDay;
|
|
|
|
|
|
|
|
return nDays;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a count of days starting from 01/01/0001 to a date
|
|
|
|
*
|
|
|
|
* The internal representation of a Date used in this Addin
|
|
|
|
* is the number of days between 01/01/0001 and the date
|
|
|
|
* this function converts this internal Date value
|
|
|
|
* to a Day , Month, Year representation of a Date.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
void DaysToDate( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear )
|
2003-04-28 14:14:28 +00:00
|
|
|
throw( lang::IllegalArgumentException )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2003-04-28 14:14:28 +00:00
|
|
|
if( nDays < 0 )
|
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
sal_Int32 nTempDays;
|
|
|
|
sal_Int32 i = 0;
|
|
|
|
sal_Bool bCalc;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nTempDays = nDays;
|
|
|
|
rYear = (sal_uInt16)((nTempDays / 365) - i);
|
|
|
|
nTempDays -= ((sal_Int32) rYear -1) * 365;
|
|
|
|
nTempDays -= (( rYear -1) / 4) - (( rYear -1) / 100) + ((rYear -1) / 400);
|
|
|
|
bCalc = sal_False;
|
|
|
|
if ( nTempDays < 1 )
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
bCalc = sal_True;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( nTempDays > 365 )
|
|
|
|
{
|
|
|
|
if ( (nTempDays != 366) || !IsLeapYear( rYear ) )
|
|
|
|
{
|
|
|
|
i--;
|
|
|
|
bCalc = sal_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while ( bCalc );
|
|
|
|
|
|
|
|
rMonth = 1;
|
|
|
|
while ( (sal_Int32)nTempDays > DaysInMonth( rMonth, rYear ) )
|
|
|
|
{
|
|
|
|
nTempDays -= DaysInMonth( rMonth, rYear );
|
|
|
|
rMonth++;
|
|
|
|
}
|
|
|
|
rDay = (sal_uInt16)nTempDays;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the null date used by the spreadsheet document
|
|
|
|
*
|
|
|
|
* The internal representation of a Date used in this Addin
|
|
|
|
* is the number of days between 01/01/0001 and the date
|
|
|
|
* this function returns this internal Date value for the document null date
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
sal_Int32 GetNullDate( constREFXPS& xOpt ) THROWDEF_RTE
|
|
|
|
{
|
|
|
|
if( xOpt.is() )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2001-05-09 11:33:08 +00:00
|
|
|
ANY aAny = xOpt->getPropertyValue( STRFROMASCII( "NullDate" ) );
|
2001-04-06 12:59:16 +00:00
|
|
|
util::Date aDate;
|
|
|
|
if( aAny >>= aDate )
|
|
|
|
return DateToDays( aDate.Day, aDate.Month, aDate.Year );
|
|
|
|
}
|
|
|
|
catch( uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// no null date available -> no calculations possible
|
|
|
|
throw uno::RuntimeException();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sal_Int32 GetDiffDate360(
|
|
|
|
sal_uInt16 nDay1, sal_uInt16 nMonth1, sal_uInt16 nYear1, sal_Bool bLeapYear1,
|
|
|
|
sal_uInt16 nDay2, sal_uInt16 nMonth2, sal_uInt16 nYear2,
|
|
|
|
sal_Bool bUSAMethod )
|
|
|
|
{
|
|
|
|
if( nDay1 == 31 )
|
|
|
|
nDay1--;
|
|
|
|
else if( bUSAMethod && ( nMonth1 == 2 && ( nDay1 == 29 || ( nDay1 == 28 && !bLeapYear1 ) ) ) )
|
|
|
|
nDay1 = 30;
|
|
|
|
|
|
|
|
if( nDay2 == 31 )
|
|
|
|
{
|
|
|
|
if( bUSAMethod && nDay1 != 30 )
|
|
|
|
{
|
|
|
|
//aDate2 += 1; -> 1.xx.yyyy
|
|
|
|
nDay2 = 1;
|
|
|
|
if( nMonth2 == 12 )
|
|
|
|
{
|
|
|
|
nYear2++;
|
|
|
|
nMonth2 = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nMonth2++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nDay2 = 30;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nDay2 + nMonth2 * 30 + nYear2 * 360 - nDay1 - nMonth1 * 30 - nYear1 * 360;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
sal_Int32 GetDiffDate360( sal_Int32 nNullDate, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod )
|
|
|
|
{
|
|
|
|
nDate1 += nNullDate;
|
|
|
|
nDate2 += nNullDate;
|
|
|
|
|
|
|
|
sal_uInt16 nDay1, nMonth1, nYear1, nDay2, nMonth2, nYear2;
|
|
|
|
|
|
|
|
DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
|
|
|
|
DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
|
|
|
|
|
|
|
|
return GetDiffDate360( nDay1, nMonth1, nYear1, IsLeapYear( nYear1 ), nDay2, nMonth2, nYear2, bUSAMethod );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
sal_Int32 GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 )
|
|
|
|
{
|
|
|
|
sal_uInt16 nLeaps = 0;
|
|
|
|
for( sal_uInt16 n = nYear1 ; n <= nYear2 ; n++ )
|
|
|
|
{
|
|
|
|
if( IsLeapYear( n ) )
|
|
|
|
nLeaps++;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_uInt32 nSum = 1;
|
|
|
|
nSum += nYear2;
|
|
|
|
nSum -= nYear1;
|
|
|
|
nSum *= 365;
|
|
|
|
nSum += nLeaps;
|
|
|
|
|
|
|
|
return nSum;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
void GetDiffParam( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
|
|
|
|
sal_uInt16& rYears, sal_Int32& rDayDiffPart, sal_Int32& rDaysInYear ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( nStartDate > nEndDate )
|
|
|
|
{
|
|
|
|
sal_Int32 n = nEndDate;
|
|
|
|
nEndDate = nStartDate;
|
|
|
|
nStartDate = n;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 nDate1 = nStartDate + nNullDate;
|
|
|
|
sal_Int32 nDate2 = nEndDate + nNullDate;
|
|
|
|
|
|
|
|
sal_uInt16 nDay1, nDay2;
|
|
|
|
sal_uInt16 nMonth1, nMonth2;
|
|
|
|
sal_uInt16 nYear1, nYear2;
|
|
|
|
|
|
|
|
DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
|
|
|
|
DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
|
|
|
|
|
2001-05-22 10:51:24 +00:00
|
|
|
sal_uInt16 nYears;
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
sal_Int32 nDayDiff, nDaysInYear;
|
|
|
|
|
|
|
|
switch( nMode )
|
|
|
|
{
|
|
|
|
case 0: // 0=USA (NASD) 30/360
|
|
|
|
case 4: // 4=Europe 30/360
|
|
|
|
nDaysInYear = 360;
|
2001-05-22 10:51:24 +00:00
|
|
|
nYears = nYear2 - nYear1;
|
2001-05-07 05:56:53 +00:00
|
|
|
nDayDiff = GetDiffDate360( nDay1, nMonth1, nYear1, IsLeapYear( nYear1 ),
|
|
|
|
nDay2, nMonth2, nYear2, nMode == 0 ) - nYears * nDaysInYear;
|
|
|
|
break;
|
|
|
|
case 1: // 1=exact/exact
|
2001-05-22 10:51:24 +00:00
|
|
|
nYears = nYear2 - nYear1;
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
nDaysInYear = IsLeapYear( nYear1 )? 366 : 365;
|
2001-05-22 10:51:24 +00:00
|
|
|
|
|
|
|
if( nYears && ( nMonth1 > nMonth2 || ( nMonth1 == nMonth2 && nDay1 > nDay2 ) ) )
|
|
|
|
nYears--;
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
if( nYears )
|
|
|
|
nDayDiff = nDate2 - DateToDays( nDay1, nMonth1, nYear2 );
|
|
|
|
else
|
|
|
|
nDayDiff = nDate2 - nDate1;
|
|
|
|
|
2001-08-13 09:10:54 +00:00
|
|
|
if( nDayDiff < 0 )
|
|
|
|
nDayDiff += nDaysInYear;
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
break;
|
|
|
|
case 2: // 2=exact/360
|
|
|
|
nDaysInYear = 360;
|
2001-05-22 10:51:24 +00:00
|
|
|
nYears = sal_uInt16( ( nDate2 - nDate1 ) / nDaysInYear );
|
2001-05-07 05:56:53 +00:00
|
|
|
nDayDiff = nDate2 - nDate1;
|
|
|
|
nDayDiff %= nDaysInYear;
|
|
|
|
break;
|
|
|
|
case 3: //3=exact/365
|
|
|
|
nDaysInYear = 365;
|
2001-05-22 10:51:24 +00:00
|
|
|
nYears = sal_uInt16( ( nDate2 - nDate1 ) / nDaysInYear );
|
2001-05-07 05:56:53 +00:00
|
|
|
nDayDiff = nDate2 - nDate1;
|
|
|
|
nDayDiff %= nDaysInYear;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
THROW_IAE;
|
|
|
|
}
|
|
|
|
|
|
|
|
rYears = nYears;
|
|
|
|
rDayDiffPart = nDayDiff;
|
|
|
|
rDaysInYear = nDaysInYear;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sal_Int32 GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
|
|
|
|
sal_Int32* pOptDaysIn1stYear ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
sal_Bool bNeg = nStartDate > nEndDate;
|
|
|
|
|
|
|
|
if( bNeg )
|
|
|
|
{
|
|
|
|
sal_Int32 n = nEndDate;
|
|
|
|
nEndDate = nStartDate;
|
|
|
|
nStartDate = n;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 nRet;
|
|
|
|
|
|
|
|
switch( nMode )
|
|
|
|
{
|
|
|
|
case 0: // 0=USA (NASD) 30/360
|
|
|
|
case 4: // 4=Europe 30/360
|
|
|
|
{
|
|
|
|
sal_uInt16 nD1, nM1, nY1, nD2, nM2, nY2;
|
|
|
|
|
|
|
|
nStartDate += nNullDate;
|
|
|
|
nEndDate += nNullDate;
|
|
|
|
|
|
|
|
DaysToDate( nStartDate, nD1, nM1, nY1 );
|
|
|
|
DaysToDate( nEndDate, nD2, nM2, nY2 );
|
|
|
|
|
|
|
|
sal_Bool bLeap = IsLeapYear( nY1 );
|
|
|
|
sal_Int32 nDays, nMonths/*, nYears*/;
|
|
|
|
|
|
|
|
nMonths = nM2 - nM1;
|
|
|
|
nDays = nD2 - nD1;
|
|
|
|
|
|
|
|
nMonths += ( nY2 - nY1 ) * 12;
|
|
|
|
|
|
|
|
nRet = nMonths * 30 + nDays;
|
|
|
|
if( nMode == 0 && nM1 == 2 && nM2 != 2 && nY1 == nY2 )
|
|
|
|
nRet -= bLeap? 1 : 2;
|
|
|
|
|
|
|
|
if( pOptDaysIn1stYear )
|
|
|
|
*pOptDaysIn1stYear = 360;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1: // 1=exact/exact
|
|
|
|
if( pOptDaysIn1stYear )
|
|
|
|
{
|
|
|
|
sal_uInt16 nD, nM, nY;
|
|
|
|
|
|
|
|
DaysToDate( nStartDate + nNullDate, nD, nM, nY );
|
|
|
|
|
|
|
|
*pOptDaysIn1stYear = IsLeapYear( nY )? 366 : 365;
|
|
|
|
}
|
|
|
|
nRet = nEndDate - nStartDate;
|
|
|
|
break;
|
|
|
|
case 2: // 2=exact/360
|
|
|
|
nRet = nEndDate - nStartDate;
|
|
|
|
if( pOptDaysIn1stYear )
|
|
|
|
*pOptDaysIn1stYear = 360;
|
|
|
|
break;
|
|
|
|
case 3: //3=exact/365
|
|
|
|
nRet = nEndDate - nStartDate;
|
|
|
|
if( pOptDaysIn1stYear )
|
|
|
|
*pOptDaysIn1stYear = 365;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
THROW_IAE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bNeg? -nRet : nRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
sal_Int32 nDays1stYear;
|
|
|
|
sal_Int32 nTotalDays = GetDiffDate( nNullDate, nStartDate, nEndDate, nMode, &nDays1stYear );
|
|
|
|
|
|
|
|
return double( nTotalDays ) / double( nDays1stYear );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
switch( nMode )
|
|
|
|
{
|
|
|
|
case 0: // 0=USA (NASD) 30/360
|
|
|
|
case 2: // 2=exact/360
|
|
|
|
case 4: // 4=Europe 30/360
|
|
|
|
return 360;
|
|
|
|
case 1: // 1=exact/exact
|
|
|
|
{
|
|
|
|
sal_uInt16 nD, nM, nY;
|
|
|
|
nDate += nNullDate;
|
|
|
|
DaysToDate( nDate, nD, nM, nY );
|
|
|
|
return IsLeapYear( nY )? 366 : 365;
|
|
|
|
}
|
|
|
|
case 3: //3=exact/365
|
|
|
|
return 365;
|
|
|
|
default:
|
|
|
|
THROW_IAE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( nStartDate == nEndDate )
|
|
|
|
return 0.0; // nothing to do...
|
|
|
|
|
|
|
|
sal_uInt16 nYears;
|
|
|
|
sal_Int32 nDayDiff, nDaysInYear;
|
|
|
|
|
|
|
|
GetDiffParam( nNullDate, nStartDate, nEndDate, nMode, nYears, nDayDiff, nDaysInYear );
|
|
|
|
|
|
|
|
return double( nYears ) + double( nDayDiff ) / double( nDaysInYear );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
void AddDate( sal_uInt16& rD, sal_uInt16& rM, sal_uInt16& rY, sal_Int32 /*nDD*/, sal_Int32 nDM, sal_Int32 /*nDY*/ )
|
2001-05-07 05:56:53 +00:00
|
|
|
{
|
|
|
|
sal_Int32 nD = rD;
|
|
|
|
sal_Int32 nM = rM;
|
|
|
|
sal_Int32 nY = rY;
|
|
|
|
|
|
|
|
sal_Bool bMod = sal_False;
|
|
|
|
|
|
|
|
if( nDM )
|
|
|
|
{
|
|
|
|
bMod = sal_True;
|
|
|
|
|
|
|
|
nY += nDM / 12;
|
|
|
|
nM += nDM % 12;
|
|
|
|
if( nM <= 0 )
|
|
|
|
{
|
|
|
|
nY--;
|
2001-08-13 09:10:54 +00:00
|
|
|
nM += 12;
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
else if( nM > 12 )
|
|
|
|
{
|
|
|
|
nY++;
|
|
|
|
nM -= 12;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bMod )
|
|
|
|
{
|
|
|
|
rD = sal_uInt16( nD );
|
|
|
|
rM = sal_uInt16( nM );
|
|
|
|
rY = sal_uInt16( nY );
|
|
|
|
|
|
|
|
AlignDate( rD, sal_uInt16( nM ), sal_uInt16( nY ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AddDate( sal_Int32 nND, sal_Int32& rD, sal_Int32 nDD, sal_Int32 nDM, sal_Int32 nDY )
|
|
|
|
{
|
|
|
|
sal_uInt16 nD, nM, nY;
|
|
|
|
DaysToDate( rD + nND, nD, nM, nY );
|
|
|
|
|
|
|
|
AddDate( nD, nM, nY, nDD, nDM, nDY );
|
|
|
|
|
|
|
|
rD = DateToDays( nD, nM, nY ) - nND;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-13 09:10:54 +00:00
|
|
|
// if nRefDate is last day in month and day of nDate is >= day of nRefDate,
|
|
|
|
// adjust nDate to last day in month and return
|
|
|
|
sal_Int32 AdjustLastDayInMonth( sal_Int32 nNullDate, sal_Int32 nRefDate, sal_Int32 nDate )
|
|
|
|
{
|
|
|
|
sal_uInt16 nRefDay, nRefMonth, nRefYear;
|
|
|
|
DaysToDate( nNullDate + nRefDate, nRefDay, nRefMonth, nRefYear );
|
|
|
|
if( nRefDay == DaysInMonth( nRefMonth, nRefYear ) )
|
|
|
|
{
|
|
|
|
sal_uInt16 nDay, nMonth, nYear;
|
|
|
|
DaysToDate( nNullDate + nDate, nDay, nMonth, nYear );
|
|
|
|
if( nDay >= nRefDay )
|
|
|
|
{
|
|
|
|
nDate += DaysInMonth( nMonth, nYear );
|
|
|
|
nDate -= nDay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
double Fak( sal_Int32 n )
|
|
|
|
{
|
|
|
|
if( n > 0 )
|
|
|
|
{
|
|
|
|
double fRet = n;
|
|
|
|
double f = n - 1;
|
|
|
|
|
|
|
|
while( f >= 2.0 )
|
|
|
|
{
|
|
|
|
fRet *= f;
|
|
|
|
f--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fRet;
|
|
|
|
}
|
|
|
|
else if( !n )
|
|
|
|
return 1.0;
|
|
|
|
else
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetGcd( double f1, double f2 )
|
|
|
|
{
|
|
|
|
double f = fmod( f1, f2 );
|
|
|
|
while( f > 0.0 )
|
|
|
|
{
|
|
|
|
f1 = f2;
|
|
|
|
f2 = f;
|
|
|
|
f = fmod( f1, f2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
return f2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GammaHelp( double& x, sal_Bool& bReflect )
|
|
|
|
{
|
|
|
|
double c[6] = {76.18009173, -86.50532033, 24.01409822,
|
|
|
|
-1.231739516, 0.120858003E-2, -0.536382E-5};
|
|
|
|
if (x >= 1.0)
|
|
|
|
{
|
|
|
|
bReflect = sal_False;
|
|
|
|
x -= 1.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bReflect = sal_True;
|
|
|
|
x = 1.0 - x;
|
|
|
|
}
|
|
|
|
double s, anum;
|
|
|
|
s = 1.0;
|
|
|
|
anum = x;
|
|
|
|
for (sal_uInt16 i = 0; i < 6; i++)
|
|
|
|
{
|
|
|
|
anum += 1.0;
|
|
|
|
s += c[i]/anum;
|
|
|
|
}
|
|
|
|
s *= 2.506628275; // sqrt(2*PI)
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double Gamma( double x )
|
|
|
|
{
|
|
|
|
sal_Bool bReflect;
|
|
|
|
double G = GammaHelp(x, bReflect);
|
|
|
|
G = pow(x+5.5,x+0.5)*G/exp(x+5.5);
|
|
|
|
if (bReflect)
|
|
|
|
G = PI*x/(G*sin(PI*x));
|
|
|
|
return G;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GammaN( double x, sal_uInt32 nIter )
|
|
|
|
{
|
|
|
|
double n = nIter;
|
|
|
|
double f = pow( n, x ) / x;
|
|
|
|
double c = 1.0;
|
|
|
|
|
|
|
|
while( nIter )
|
|
|
|
{
|
|
|
|
x++;
|
|
|
|
|
|
|
|
f /= x;
|
|
|
|
f *= c;
|
|
|
|
|
|
|
|
nIter--;
|
|
|
|
c++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double ConvertToDec( const STRING& aStr, sal_uInt16 nBase, sal_uInt16 nCharLim ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if ( nBase < 2 || nBase > 36 )
|
2001-05-07 05:56:53 +00:00
|
|
|
THROW_IAE;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
sal_uInt32 nStrLen = aStr.getLength();
|
|
|
|
if( nStrLen > nCharLim )
|
|
|
|
THROW_IAE;
|
|
|
|
else if( !nStrLen )
|
|
|
|
return 0.0;
|
|
|
|
|
|
|
|
double fVal = 0.0;
|
|
|
|
|
|
|
|
register const sal_Unicode* p = aStr.getStr();
|
|
|
|
|
2004-09-08 14:59:13 +00:00
|
|
|
sal_uInt16 nFirstDig = 0;
|
2001-04-06 12:59:16 +00:00
|
|
|
sal_Bool bFirstDig = sal_True;
|
|
|
|
double fBase = nBase;
|
|
|
|
|
|
|
|
while ( *p )
|
|
|
|
{
|
|
|
|
sal_uInt16 n;
|
|
|
|
|
|
|
|
if( '0' <= *p && *p <= '9' )
|
|
|
|
n = *p - '0';
|
|
|
|
else if( 'A' <= *p && *p <= 'Z' )
|
|
|
|
n = 10 + ( *p - 'A' );
|
|
|
|
else if ( 'a' <= *p && *p <= 'z' )
|
|
|
|
n = 10 + ( *p - 'a' );
|
|
|
|
else
|
|
|
|
n = nBase;
|
|
|
|
|
|
|
|
if( n < nBase )
|
|
|
|
{
|
|
|
|
if( bFirstDig )
|
|
|
|
{
|
|
|
|
bFirstDig = sal_False;
|
|
|
|
nFirstDig = n;
|
|
|
|
}
|
|
|
|
fVal = fVal * fBase + double( n );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// illegal char!
|
|
|
|
THROW_IAE;
|
|
|
|
|
|
|
|
p++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nStrLen == nCharLim && !bFirstDig && nFirstDig == nBase - 1 )
|
|
|
|
{ // handling negativ values
|
|
|
|
fVal = ( pow( double( nBase ), double( nCharLim ) ) - fVal ); // complement
|
|
|
|
fVal *= -1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline sal_Char GetMaxChar( sal_uInt16 nBase )
|
|
|
|
{
|
|
|
|
const sal_Char* c = "--123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
|
return c[ nBase ];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-02 08:29:14 +00:00
|
|
|
STRING ConvertFromDec( double fNum, double fMin, double fMax, sal_uInt16 nBase,
|
|
|
|
sal_Int32 nPlaces, sal_Int32 nMaxPlaces, sal_Bool bUsePlaces ) THROWDEF_RTE_IAE
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2004-03-02 08:29:14 +00:00
|
|
|
fNum = ::rtl::math::approxFloor( fNum );
|
|
|
|
fMin = ::rtl::math::approxFloor( fMin );
|
|
|
|
fMax = ::rtl::math::approxFloor( fMax );
|
|
|
|
|
|
|
|
if( fNum < fMin || fNum > fMax || ( bUsePlaces && ( nPlaces <= 0 || nPlaces > nMaxPlaces ) ) )
|
2001-04-06 12:59:16 +00:00
|
|
|
THROW_IAE;
|
|
|
|
|
2004-03-02 08:29:14 +00:00
|
|
|
sal_Int64 nNum = static_cast< sal_Int64 >( fNum );
|
2001-04-06 12:59:16 +00:00
|
|
|
sal_Bool bNeg = nNum < 0;
|
|
|
|
if( bNeg )
|
|
|
|
nNum = sal_Int64( pow( double( nBase ), double( nMaxPlaces ) ) ) + nNum;
|
|
|
|
|
2001-05-14 07:38:20 +00:00
|
|
|
STRING aRet( STRING::valueOf( nNum, nBase ).toAsciiUpperCase() );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-07-11 07:36:17 +00:00
|
|
|
|
|
|
|
if( bUsePlaces )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2004-03-02 08:29:14 +00:00
|
|
|
sal_Int32 nLen = aRet.getLength();
|
2001-07-11 07:36:17 +00:00
|
|
|
if( !bNeg && nLen > nPlaces )
|
2004-03-02 08:29:14 +00:00
|
|
|
{
|
2001-07-11 07:36:17 +00:00
|
|
|
THROW_IAE;
|
2004-03-02 08:29:14 +00:00
|
|
|
}
|
2001-07-11 07:36:17 +00:00
|
|
|
else if( ( bNeg && nLen < nMaxPlaces ) || ( !bNeg && nLen < nPlaces ) )
|
|
|
|
{
|
2004-03-02 08:29:14 +00:00
|
|
|
sal_Int32 nLeft = nPlaces - nLen;
|
2001-07-11 07:36:17 +00:00
|
|
|
sal_Char* p = new sal_Char[ nLeft + 1 ];
|
|
|
|
memset( p, bNeg? GetMaxChar( nBase ) : '0', nLeft );
|
|
|
|
p[ nLeft ] = 0x00;
|
|
|
|
STRING aTmp( p, nLeft, RTL_TEXTENCODING_MS_1252 );
|
|
|
|
aTmp += aRet;
|
|
|
|
aRet = aTmp;
|
|
|
|
|
|
|
|
delete[] p;
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
2006-01-13 15:41:13 +00:00
|
|
|
|
|
|
|
/** Approximation algorithm for erf for 0 < x < 0.65. */
|
|
|
|
void Erf0065( double x, double& fVal )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2006-01-13 15:41:13 +00:00
|
|
|
static const double pn[] = {
|
|
|
|
1.12837916709551256,
|
|
|
|
1.35894887627277916E-1,
|
|
|
|
4.03259488531795274E-2,
|
|
|
|
1.20339380863079457E-3,
|
|
|
|
6.49254556481904354E-5
|
|
|
|
};
|
|
|
|
static const double qn[] = {
|
|
|
|
1.00000000000000000,
|
|
|
|
4.53767041780002545E-1,
|
|
|
|
8.69936222615385890E-2,
|
|
|
|
8.49717371168693357E-3,
|
|
|
|
3.64915280629351082E-4
|
|
|
|
};
|
|
|
|
|
|
|
|
double fPSum = 0.0;
|
|
|
|
double fQSum = 0.0;
|
|
|
|
double fXPow = 1.0;
|
|
|
|
for ( unsigned int i = 0; i <= 4; ++i )
|
2005-10-25 09:58:16 +00:00
|
|
|
{
|
2006-01-13 15:41:13 +00:00
|
|
|
fPSum += pn[i]*fXPow;
|
|
|
|
fQSum += qn[i]*fXPow;
|
|
|
|
fXPow *= x*x;
|
2005-10-25 09:58:16 +00:00
|
|
|
}
|
2006-01-13 15:41:13 +00:00
|
|
|
fVal = x * fPSum / fQSum;
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
/** Approximation algorithm for erfc for 0.65 < x < 6.0. */
|
|
|
|
void Erfc0600( double x, double& fVal )
|
|
|
|
{
|
|
|
|
double fPSum = 0.0;
|
|
|
|
double fQSum = 0.0;
|
|
|
|
double fXPow = 1.0;
|
|
|
|
const double *pn;
|
|
|
|
const double *qn;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
if ( x < 2.2 )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2006-01-13 15:41:13 +00:00
|
|
|
static const double pn22[] = {
|
|
|
|
9.99999992049799098E-1,
|
|
|
|
1.33154163936765307,
|
|
|
|
8.78115804155881782E-1,
|
|
|
|
3.31899559578213215E-1,
|
|
|
|
7.14193832506776067E-2,
|
|
|
|
7.06940843763253131E-3
|
|
|
|
};
|
|
|
|
static const double qn22[] = {
|
|
|
|
1.00000000000000000,
|
|
|
|
2.45992070144245533,
|
|
|
|
2.65383972869775752,
|
|
|
|
1.61876655543871376,
|
|
|
|
5.94651311286481502E-1,
|
|
|
|
1.26579413030177940E-1,
|
|
|
|
1.25304936549413393E-2
|
|
|
|
};
|
|
|
|
pn = pn22;
|
|
|
|
qn = qn22;
|
|
|
|
}
|
|
|
|
else /* if ( x < 6.0 ) this is true, but the compiler does not know */
|
|
|
|
{
|
|
|
|
static const double pn60[] = {
|
|
|
|
9.99921140009714409E-1,
|
|
|
|
1.62356584489366647,
|
|
|
|
1.26739901455873222,
|
|
|
|
5.81528574177741135E-1,
|
|
|
|
1.57289620742838702E-1,
|
|
|
|
2.25716982919217555E-2
|
|
|
|
};
|
|
|
|
static const double qn60[] = {
|
|
|
|
1.00000000000000000,
|
|
|
|
2.75143870676376208,
|
|
|
|
3.37367334657284535,
|
|
|
|
2.38574194785344389,
|
|
|
|
1.05074004614827206,
|
|
|
|
2.78788439273628983E-1,
|
|
|
|
4.00072964526861362E-2
|
|
|
|
};
|
|
|
|
pn = pn60;
|
|
|
|
qn = qn60;
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
for ( unsigned int i = 0; i < 6; ++i )
|
|
|
|
{
|
|
|
|
fPSum += pn[i]*fXPow;
|
|
|
|
fQSum += qn[i]*fXPow;
|
|
|
|
fXPow *= x;
|
|
|
|
}
|
|
|
|
fQSum += qn[6]*fXPow;
|
|
|
|
fVal = exp( -1.0*x*x )* fPSum / fQSum;
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
/** Approximation algorithm for erfc for 6.0 < x < 26.54 (but used for all
|
|
|
|
x > 6.0). */
|
|
|
|
void Erfc2654( double x, double& fVal )
|
|
|
|
{
|
|
|
|
static const double pn[] = {
|
|
|
|
5.64189583547756078E-1,
|
|
|
|
8.80253746105525775,
|
|
|
|
3.84683103716117320E1,
|
|
|
|
4.77209965874436377E1,
|
|
|
|
8.08040729052301677
|
|
|
|
};
|
|
|
|
static const double qn[] = {
|
|
|
|
1.00000000000000000,
|
|
|
|
1.61020914205869003E1,
|
|
|
|
7.54843505665954743E1,
|
|
|
|
1.12123870801026015E2,
|
|
|
|
3.73997570145040850E1
|
|
|
|
};
|
|
|
|
|
|
|
|
double fPSum = 0.0;
|
|
|
|
double fQSum = 0.0;
|
|
|
|
double fXPow = 1.0;
|
|
|
|
|
|
|
|
for ( unsigned int i = 0; i <= 4; ++i )
|
|
|
|
{
|
|
|
|
fPSum += pn[i]*fXPow;
|
|
|
|
fQSum += qn[i]*fXPow;
|
|
|
|
fXPow /= x*x;
|
|
|
|
}
|
|
|
|
fVal = exp(-1.0*x*x)*fPSum / (x*fQSum);
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
double Erfc( double );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
/** Parent error function (erf) that calls different algorithms based on the
|
|
|
|
value of x. It takes care of cases where x is negative as erf is an odd
|
|
|
|
function i.e. erf(-x) = -erf(x).
|
2005-10-25 09:58:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
Kramer, W., and Blomquist, F., 2000, Algorithms with Guaranteed Error Bounds
|
|
|
|
for the Error Function and the Complementary Error Function
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
http://www.math.uni-wuppertal.de/wrswt/literatur_en.html
|
2005-10-25 09:58:16 +00:00
|
|
|
|
|
|
|
@author Kohei Yoshida <kohei@openoffice.org>
|
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
@see #i55735#
|
2005-10-25 09:58:16 +00:00
|
|
|
*/
|
2006-01-13 15:41:13 +00:00
|
|
|
double Erf( double x )
|
2005-10-25 09:58:16 +00:00
|
|
|
{
|
|
|
|
if( x == 0.0 )
|
2006-01-13 15:41:13 +00:00
|
|
|
return 0.0;
|
2005-10-25 09:58:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
bool bNegative = false;
|
|
|
|
if ( x < 0.0 )
|
2005-10-25 09:58:16 +00:00
|
|
|
{
|
2006-01-13 15:41:13 +00:00
|
|
|
x = fabs( x );
|
|
|
|
bNegative = true;
|
|
|
|
}
|
2005-10-25 09:58:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
double fErf = 1.0;
|
|
|
|
if ( x < 1.0e-10 )
|
2006-09-25 11:47:04 +00:00
|
|
|
fErf = (double) (x*1.1283791670955125738961589031215452L);
|
2006-01-13 15:41:13 +00:00
|
|
|
else if ( x < 0.65 )
|
|
|
|
Erf0065( x, fErf );
|
|
|
|
else
|
|
|
|
fErf = 1.0 - Erfc( x );
|
2005-10-25 09:58:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
if ( bNegative )
|
|
|
|
fErf *= -1.0;
|
2005-10-25 09:58:16 +00:00
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
return fErf;
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
/** Parent complementary error function (erfc) that calls different algorithms
|
|
|
|
based on the value of x. It takes care of cases where x is negative as erfc
|
|
|
|
satisfies relationship erfc(-x) = 2 - erfc(x). See the comment for Erf(x)
|
|
|
|
for the source publication.
|
2005-10-25 09:58:16 +00:00
|
|
|
|
|
|
|
@author Kohei Yoshida <kohei@openoffice.org>
|
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
@see #i55735#
|
2005-10-25 09:58:16 +00:00
|
|
|
*/
|
2006-01-13 15:41:13 +00:00
|
|
|
double Erfc( double x )
|
2005-10-25 09:58:16 +00:00
|
|
|
{
|
2006-01-13 15:41:13 +00:00
|
|
|
if ( x == 0.0 )
|
|
|
|
return 1.0;
|
|
|
|
|
2005-10-25 09:58:16 +00:00
|
|
|
bool bNegative = false;
|
|
|
|
if ( x < 0.0 )
|
|
|
|
{
|
|
|
|
x = fabs( x );
|
|
|
|
bNegative = true;
|
|
|
|
}
|
|
|
|
|
2006-01-13 15:41:13 +00:00
|
|
|
double fErfc = 0.0;
|
|
|
|
if ( x > 0.65 )
|
|
|
|
{
|
|
|
|
if ( x < 6.0 )
|
|
|
|
Erfc0600( x, fErfc );
|
|
|
|
else
|
|
|
|
Erfc2654( x, fErfc );
|
|
|
|
}
|
2005-10-25 09:58:16 +00:00
|
|
|
else
|
2006-01-13 15:41:13 +00:00
|
|
|
fErfc = 1.0 - Erf( x );
|
2005-10-25 09:58:16 +00:00
|
|
|
|
|
|
|
if ( bNegative )
|
2006-01-13 15:41:13 +00:00
|
|
|
fErfc = 2.0 - fErfc;
|
|
|
|
|
|
|
|
return fErfc;
|
2005-10-25 09:58:16 +00:00
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
inline sal_Bool IsNum( sal_Unicode c )
|
|
|
|
{
|
|
|
|
return c >= '0' && c <= '9';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline sal_Bool IsComma( sal_Unicode c )
|
|
|
|
{
|
|
|
|
return c == '.' || c == ',';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline sal_Bool IsExpStart( sal_Unicode c )
|
|
|
|
{
|
|
|
|
return c == 'e' || c == 'E';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline sal_Bool IsImagUnit( sal_Unicode c )
|
|
|
|
{
|
|
|
|
return c == 'i' || c == 'j';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline sal_uInt16 GetVal( sal_Unicode c )
|
|
|
|
{
|
|
|
|
return sal_uInt16( c - '0' );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sal_Bool ParseDouble( const sal_Unicode*& rp, double& rRet )
|
|
|
|
{
|
|
|
|
double fInt = 0.0;
|
|
|
|
double fFrac = 0.0;
|
|
|
|
double fMult = 0.1; // multiplier to multiply digits with, when adding fractional ones
|
|
|
|
sal_Int32 nExp = 0;
|
|
|
|
sal_Int32 nMaxExp = 307;
|
|
|
|
sal_uInt16 nDigCnt = 18; // max. number of digits to read in, rest doesn't matter
|
|
|
|
|
|
|
|
enum State { S_End = 0, S_Sign, S_IntStart, S_Int, S_IgnoreIntDigs, S_Frac, S_IgnoreFracDigs, S_ExpSign, S_Exp };
|
|
|
|
|
|
|
|
State eS = S_Sign;
|
|
|
|
|
|
|
|
sal_Bool bNegNum = sal_False;
|
|
|
|
sal_Bool bNegExp = sal_False;
|
|
|
|
|
|
|
|
const sal_Unicode* p = rp;
|
|
|
|
sal_Unicode c;
|
|
|
|
|
|
|
|
while( eS )
|
|
|
|
{
|
|
|
|
c = *p;
|
|
|
|
switch( eS )
|
|
|
|
{
|
|
|
|
case S_Sign:
|
|
|
|
if( IsNum( c ) )
|
|
|
|
{
|
|
|
|
fInt = GetVal( c );
|
|
|
|
nDigCnt--;
|
|
|
|
eS = S_Int;
|
|
|
|
}
|
|
|
|
else if( c == '-' )
|
|
|
|
{
|
|
|
|
bNegNum = sal_True;
|
|
|
|
eS = S_IntStart;
|
|
|
|
}
|
|
|
|
else if( c == '+' )
|
|
|
|
eS = S_IntStart;
|
|
|
|
else if( IsComma( c ) )
|
|
|
|
eS = S_Frac;
|
|
|
|
else
|
|
|
|
return sal_False;
|
|
|
|
break;
|
|
|
|
case S_IntStart:
|
|
|
|
if( IsNum( c ) )
|
|
|
|
{
|
|
|
|
fInt = GetVal( c );
|
|
|
|
nDigCnt--;
|
|
|
|
eS = S_Int;
|
|
|
|
}
|
|
|
|
else if( IsComma( c ) )
|
|
|
|
eS = S_Frac;
|
|
|
|
else if( IsImagUnit( c ) )
|
|
|
|
{
|
2004-07-30 15:14:13 +00:00
|
|
|
rRet = 0.0;
|
2001-04-06 12:59:16 +00:00
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return sal_False;
|
|
|
|
break;
|
|
|
|
case S_Int:
|
|
|
|
if( IsNum( c ) )
|
|
|
|
{
|
|
|
|
fInt *= 10.0;
|
|
|
|
fInt += double( GetVal( c ) );
|
|
|
|
nDigCnt--;
|
|
|
|
if( !nDigCnt )
|
|
|
|
eS = S_IgnoreIntDigs;
|
|
|
|
}
|
|
|
|
else if( IsComma( c ) )
|
|
|
|
eS = S_Frac;
|
|
|
|
else if( IsExpStart( c ) )
|
|
|
|
eS = S_ExpSign;
|
|
|
|
else
|
|
|
|
eS = S_End;
|
|
|
|
break;
|
|
|
|
case S_IgnoreIntDigs:
|
|
|
|
if( IsNum( c ) )
|
|
|
|
nExp++; // just multiply num with 10... ;-)
|
|
|
|
else if( IsComma( c ) )
|
|
|
|
eS = S_Frac;
|
|
|
|
else if( IsExpStart( c ) )
|
|
|
|
eS = S_ExpSign;
|
|
|
|
else
|
|
|
|
eS = S_End;
|
|
|
|
break;
|
|
|
|
case S_Frac:
|
|
|
|
if( IsNum( c ) )
|
|
|
|
{
|
|
|
|
fFrac += double( GetVal( c ) ) * fMult;
|
|
|
|
nDigCnt--;
|
|
|
|
if( nDigCnt )
|
|
|
|
fMult *= 0.1;
|
|
|
|
else
|
|
|
|
eS = S_IgnoreFracDigs;
|
|
|
|
}
|
|
|
|
else if( IsExpStart( c ) )
|
|
|
|
eS = S_ExpSign;
|
|
|
|
else
|
|
|
|
eS = S_End;
|
|
|
|
break;
|
|
|
|
case S_IgnoreFracDigs:
|
|
|
|
if( IsExpStart( c ) )
|
|
|
|
eS = S_ExpSign;
|
|
|
|
else if( !IsNum( c ) )
|
|
|
|
eS = S_End;
|
|
|
|
break;
|
|
|
|
case S_ExpSign:
|
|
|
|
if( IsNum( c ) )
|
|
|
|
{
|
|
|
|
nExp = GetVal( c );
|
|
|
|
eS = S_Exp;
|
|
|
|
}
|
|
|
|
else if( c == '-' )
|
|
|
|
{
|
|
|
|
bNegExp = sal_True;
|
|
|
|
eS = S_Exp;
|
|
|
|
}
|
|
|
|
else if( c != '+' )
|
|
|
|
eS = S_End;
|
|
|
|
break;
|
|
|
|
case S_Exp:
|
|
|
|
if( IsNum( c ) )
|
|
|
|
{
|
|
|
|
nExp *= 10;
|
|
|
|
nExp += GetVal( c );
|
|
|
|
if( nExp > nMaxExp )
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
eS = S_End;
|
|
|
|
break;
|
2006-06-19 22:11:26 +00:00
|
|
|
case S_End: // to avoid compiler warning
|
|
|
|
break; // loop exits anyway
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
p--; // set pointer back to last
|
|
|
|
rp = p;
|
|
|
|
|
|
|
|
fInt += fFrac;
|
2001-08-01 08:14:22 +00:00
|
|
|
sal_Int32 nLog10 = sal_Int32( log10( fInt ) );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
if( bNegExp )
|
|
|
|
nExp = -nExp;
|
|
|
|
|
|
|
|
if( nLog10 + nExp > nMaxExp )
|
|
|
|
return sal_False;
|
|
|
|
|
2003-03-26 16:46:50 +00:00
|
|
|
fInt = ::rtl::math::pow10Exp( fInt, nExp );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
if( bNegNum )
|
|
|
|
fInt = -fInt;
|
|
|
|
|
|
|
|
rRet = fInt;
|
|
|
|
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
STRING GetString( double f, sal_Bool bLeadingSign, sal_uInt16 nMaxDig )
|
|
|
|
{
|
|
|
|
const int nBuff = 256;
|
2003-03-26 16:46:50 +00:00
|
|
|
sal_Char aBuff[ nBuff + 1 ];
|
2001-04-06 12:59:16 +00:00
|
|
|
const char* pFormStr = bLeadingSign? "%+.*g" : "%.*g";
|
2003-03-26 16:46:50 +00:00
|
|
|
int nLen = snprintf( aBuff, nBuff, pFormStr, int( nMaxDig ), f );
|
|
|
|
// you never know which underlying implementation you get ...
|
|
|
|
aBuff[nBuff] = 0;
|
|
|
|
if ( nLen < 0 || nLen > nBuff )
|
|
|
|
nLen = strlen( aBuff );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2003-03-26 16:46:50 +00:00
|
|
|
STRING aRet( aBuff, nLen, RTL_TEXTENCODING_MS_1252 );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
double GetAmordegrc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
|
|
|
|
double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2001-08-13 09:10:54 +00:00
|
|
|
if( nBase == 2 )
|
|
|
|
THROW_IAE;
|
|
|
|
|
|
|
|
sal_uInt32 nPer = sal_uInt32( fPer );
|
|
|
|
double fUsePer = 1.0 / fRate;
|
|
|
|
double fAmorCoeff;
|
|
|
|
|
|
|
|
if( fUsePer < 3.0 )
|
|
|
|
fAmorCoeff = 1.0;
|
|
|
|
else if( fUsePer < 5.0 )
|
|
|
|
fAmorCoeff = 1.5;
|
|
|
|
else if( fUsePer <= 6.0 )
|
|
|
|
fAmorCoeff = 2.0;
|
|
|
|
else
|
|
|
|
fAmorCoeff = 2.5;
|
|
|
|
|
|
|
|
fRate *= fAmorCoeff;
|
2003-03-26 16:46:50 +00:00
|
|
|
double fNRate = ::rtl::math::round( GetYearFrac( nNullDate, nDate, nFirstPer, nBase ) * fRate * fCost, 0 );
|
2001-08-13 09:10:54 +00:00
|
|
|
fCost -= fNRate;
|
|
|
|
double fRest = fCost - fRestVal; // Anschaffungskosten - Restwert - Summe aller Abschreibungen
|
|
|
|
|
|
|
|
for( sal_uInt32 n = 0 ; n < nPer ; n++ )
|
|
|
|
{
|
2003-03-26 16:46:50 +00:00
|
|
|
fNRate = ::rtl::math::round( fRate * fCost, 0 );
|
2001-08-13 09:10:54 +00:00
|
|
|
fRest -= fNRate;
|
|
|
|
|
|
|
|
if( fRest < 0.0 )
|
|
|
|
{
|
|
|
|
switch( nPer - n )
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 1:
|
2003-03-26 16:46:50 +00:00
|
|
|
return ::rtl::math::round( fCost * 0.5, 0 );
|
2001-08-13 09:10:54 +00:00
|
|
|
default:
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fCost -= fNRate;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fNRate;
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetAmorlinc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
|
|
|
|
double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2001-08-13 09:10:54 +00:00
|
|
|
if( nBase == 2 )
|
|
|
|
THROW_IAE;
|
|
|
|
|
|
|
|
sal_uInt32 nPer = sal_uInt32( fPer );
|
|
|
|
double fOneRate = fCost * fRate;
|
|
|
|
double fCostDelta = fCost - fRestVal;
|
|
|
|
double f0Rate = GetYearFrac( nNullDate, nDate, nFirstPer, nBase ) * fRate * fCost;
|
|
|
|
sal_uInt32 nNumOfFullPeriods = sal_uInt32( ( fCost - fRestVal - f0Rate) / fOneRate );
|
|
|
|
|
|
|
|
if( nPer == 0 )
|
|
|
|
return f0Rate;
|
|
|
|
else if( nPer <= nNumOfFullPeriods )
|
|
|
|
return fOneRate;
|
|
|
|
else if( nPer == nNumOfFullPeriods + 1 )
|
|
|
|
return fCostDelta - fOneRate * nNumOfFullPeriods - f0Rate;
|
|
|
|
else
|
|
|
|
return 0.0;
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetDuration( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup,
|
|
|
|
double fYield, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2001-08-13 09:10:54 +00:00
|
|
|
double fYearfrac = GetYearFrac( nNullDate, nSettle, nMat, nBase );
|
|
|
|
double fNumOfCoups = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase );
|
|
|
|
double fDur = 0.0;
|
|
|
|
const double f100 = 100.0;
|
|
|
|
fCoup *= f100 / double( nFreq ); // fCoup is used as cash flow
|
|
|
|
fYield /= nFreq;
|
|
|
|
fYield += 1.0;
|
|
|
|
|
2004-11-18 16:03:19 +00:00
|
|
|
double nDiff = fYearfrac * nFreq - fNumOfCoups;
|
|
|
|
|
2001-08-13 09:10:54 +00:00
|
|
|
double t;
|
|
|
|
|
|
|
|
for( t = 1.0 ; t < fNumOfCoups ; t++ )
|
2004-11-18 16:03:19 +00:00
|
|
|
fDur += ( t + nDiff ) * ( fCoup ) / pow( fYield, t + nDiff );
|
2001-08-13 09:10:54 +00:00
|
|
|
|
2004-11-18 16:03:19 +00:00
|
|
|
fDur += ( fNumOfCoups + nDiff ) * ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );
|
2001-08-13 09:10:54 +00:00
|
|
|
|
|
|
|
double p = 0.0;
|
|
|
|
for( t = 1.0 ; t < fNumOfCoups ; t++ )
|
2004-11-18 16:03:19 +00:00
|
|
|
p += fCoup / pow( fYield, t + nDiff );
|
2001-08-13 09:10:54 +00:00
|
|
|
|
2004-11-18 16:03:19 +00:00
|
|
|
p += ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );
|
2001-08-13 09:10:54 +00:00
|
|
|
|
|
|
|
fDur /= p;
|
|
|
|
fDur /= double( nFreq );
|
|
|
|
|
|
|
|
return fDur;
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetYieldmat( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
|
|
|
|
double fRate, double fPrice, sal_Int32 nBase ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2001-08-23 15:13:18 +00:00
|
|
|
double fIssMat = GetYearFrac( nNullDate, nIssue, nMat, nBase );
|
|
|
|
double fIssSet = GetYearFrac( nNullDate, nIssue, nSettle, nBase );
|
|
|
|
double fSetMat = GetYearFrac( nNullDate, nSettle, nMat, nBase );
|
|
|
|
|
|
|
|
double y = 1.0 + fIssMat * fRate;
|
|
|
|
y /= fPrice / 100.0 + fIssSet * fRate;
|
|
|
|
y--;
|
|
|
|
y /= fSetMat;
|
|
|
|
|
|
|
|
return y;
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
double GetOddfprice( sal_Int32 /*nNullDate*/, sal_Int32 /*nSettle*/, sal_Int32 /*nMat*/, sal_Int32 /*nIssue*/,
|
|
|
|
sal_Int32 /*nFirstCoup*/, double /*fRate*/, double /*fYield*/, double /*fRedemp*/, sal_Int32 /*nFreq*/,
|
|
|
|
sal_Int32 /*nBase*/ ) THROWDEF_RTE_IAE
|
2001-08-17 06:22:24 +00:00
|
|
|
{
|
2001-09-26 12:22:24 +00:00
|
|
|
THROW_RTE; // #87380#
|
|
|
|
/*
|
2001-08-17 06:22:24 +00:00
|
|
|
double fN = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase ) - 1.0;
|
|
|
|
double fNq = GetCoupnum( nNullDate, nSettle, nFirstCoup, nFreq, nBase ) - 1.0;
|
2001-08-24 06:16:52 +00:00
|
|
|
double fDSC = GetCoupdaysnc( nNullDate, nSettle, nFirstCoup, nFreq, nBase );
|
|
|
|
double fDSC_E = fDSC / GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase );
|
2001-08-17 06:22:24 +00:00
|
|
|
double fNC = GetCoupnum( nNullDate, nIssue, nFirstCoup, nFreq, nBase );
|
|
|
|
sal_uInt32 nNC = sal_uInt32( fNC );
|
2001-08-24 06:16:52 +00:00
|
|
|
sal_uInt16 nMonthDelta = 12 / sal_uInt16( nFreq );
|
2001-08-17 06:22:24 +00:00
|
|
|
|
|
|
|
sal_uInt32 i;
|
|
|
|
double f1YieldFreq = 1.0 + fYield / double( nFreq );
|
|
|
|
double f100RateFreq = 100.0 * fRate / double( nFreq );
|
|
|
|
|
2001-08-24 06:16:52 +00:00
|
|
|
double* pDC = new double[ nNC + 1 ];
|
|
|
|
double* pNL = new double[ nNC + 1 ];
|
|
|
|
double* pA = new double[ nNC + 1 ];
|
|
|
|
|
|
|
|
pDC[ 0 ] = pNL[ 0 ] = pA[ 0 ] = 1.0;
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDate aStartDate( nNullDate, nSettle, nBase );
|
|
|
|
ScaDate aNextCoup( nNullDate, nFirstCoup, nBase );
|
2001-08-24 06:16:52 +00:00
|
|
|
if( nNC )
|
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
pDC[ 1 ] = ScaDate::GetDiff( aStartDate, aNextCoup );
|
2001-08-24 06:16:52 +00:00
|
|
|
pNL[ 1 ] = GetCoupdays( nNullDate, nSettle, nFirstCoup, nFreq, nBase );
|
|
|
|
pA[ 1 ] = pDC[ 1 ];
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDate aPre;
|
2001-08-24 06:16:52 +00:00
|
|
|
for( i = 1 ; i <= nNC ; i++ )
|
|
|
|
{
|
|
|
|
aPre = aStartDate;
|
2001-10-12 08:27:13 +00:00
|
|
|
aStartDate.addMonths( nMonthDelta );
|
|
|
|
aNextCoup.addMonths( nMonthDelta );
|
2001-10-09 10:09:01 +00:00
|
|
|
pDC[ i ] = ScaDate::GetDiff( aPre, aStartDate );
|
2001-08-24 06:16:52 +00:00
|
|
|
pNL[ i ] = GetCoupdays( nNullDate, aStartDate.GetDate( nNullDate ), aNextCoup.GetDate( nNullDate ),
|
|
|
|
nFreq, nBase );
|
2001-10-09 10:09:01 +00:00
|
|
|
pA[ i ] = ScaDate::GetDiff( aStartDate, aNextCoup );
|
2001-08-24 06:16:52 +00:00
|
|
|
}
|
|
|
|
}
|
2001-08-17 06:22:24 +00:00
|
|
|
|
|
|
|
double fT1 = fRedemp / pow( f1YieldFreq, fN + fNq + fDSC_E );
|
|
|
|
|
|
|
|
double fT2 = 0.0;
|
|
|
|
for( i = 1 ; i <= nNC ; i++ )
|
|
|
|
fT2 += pDC[ i ] / pNL[ i ];
|
|
|
|
fT2 *= f100RateFreq / pow( f1YieldFreq, fNq + fDSC_E );
|
|
|
|
|
|
|
|
double fT3 = 0.0;
|
|
|
|
for( double k = 2.0 ; k <= fN ; k++ )
|
|
|
|
fT3 += 1.0 / pow( f1YieldFreq, k - fNq + fDSC_E );
|
|
|
|
fT3 *= f100RateFreq;
|
|
|
|
|
|
|
|
double fT4 = 0.0;
|
|
|
|
for( i = 1 ; i <= nNC ; i++ )
|
|
|
|
fT4 += pA[ i ] / pNL[ i ];
|
|
|
|
fT4 *= f100RateFreq;
|
|
|
|
|
|
|
|
if( nNC )
|
|
|
|
{
|
|
|
|
delete pDC;
|
|
|
|
delete pNL;
|
|
|
|
delete pA;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fT1 + fT2 + fT3 - fT4;
|
2001-09-26 12:22:24 +00:00
|
|
|
*/
|
2001-08-17 06:22:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double getYield_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice,
|
|
|
|
double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
double fRate = fCoup;
|
|
|
|
double fPriceN = 0.0;
|
|
|
|
double fYield1 = 0.0;
|
|
|
|
double fYield2 = 1.0;
|
|
|
|
double fPrice1 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield1, fRedemp, nFreq, nBase );
|
|
|
|
double fPrice2 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield2, fRedemp, nFreq, nBase );
|
|
|
|
double fYieldN = ( fYield2 - fYield1 ) * 0.5;
|
|
|
|
|
|
|
|
for( sal_uInt32 nIter = 0 ; nIter < 100 && fPriceN != fPrice ; nIter++ )
|
|
|
|
{
|
|
|
|
fPriceN = getPrice_( nNullDate, nSettle, nMat, fRate, fYieldN, fRedemp, nFreq, nBase );
|
|
|
|
|
|
|
|
if( fPrice == fPrice1 )
|
|
|
|
return fYield1;
|
|
|
|
else if( fPrice == fPrice2 )
|
|
|
|
return fYield2;
|
|
|
|
else if( fPrice == fPriceN )
|
|
|
|
return fYieldN;
|
|
|
|
else if( fPrice < fPrice2 )
|
|
|
|
{
|
|
|
|
fYield2 *= 2.0;
|
|
|
|
fPrice2 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield2, fRedemp, nFreq, nBase );
|
|
|
|
|
|
|
|
fYieldN = ( fYield2 - fYield1 ) * 0.5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( fPrice < fPriceN )
|
|
|
|
{
|
|
|
|
fYield1 = fYieldN;
|
|
|
|
fPrice1 = fPriceN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fYield2 = fYieldN;
|
|
|
|
fPrice2 = fPriceN;
|
|
|
|
}
|
|
|
|
|
|
|
|
fYieldN = fYield2 - ( fYield2 - fYield1 ) * ( ( fPrice - fPrice2 ) / ( fPrice1 - fPrice2 ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fabs( fPrice - fPriceN ) > fPrice / 100.0 )
|
|
|
|
THROW_IAE; // result not precise enough
|
|
|
|
|
|
|
|
return fYieldN;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double getPrice_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield,
|
|
|
|
double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
double fFreq = nFreq;
|
|
|
|
|
|
|
|
double fE = GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase );
|
|
|
|
double fDSC_E = GetCoupdaysnc( nNullDate, nSettle, nMat, nFreq, nBase ) / fE;
|
|
|
|
double fN = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase );
|
2001-08-17 09:00:19 +00:00
|
|
|
double fA = GetCoupdaybs( nNullDate, nSettle, nMat, nFreq, nBase );
|
2001-08-17 06:22:24 +00:00
|
|
|
|
|
|
|
double fRet = fRedemp / ( pow( 1.0 + fYield / fFreq, fN - 1.0 + fDSC_E ) );
|
|
|
|
fRet -= 100.0 * fRate / fFreq * fA / fE;
|
|
|
|
|
|
|
|
double fT1 = 100.0 * fRate / fFreq;
|
|
|
|
double fT2 = 1.0 + fYield / fFreq;
|
|
|
|
|
|
|
|
for( double fK = 0.0 ; fK < fN ; fK++ )
|
|
|
|
fRet += fT1 / pow( fT2, fK + fDSC_E );
|
|
|
|
|
|
|
|
return fRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
double GetOddfyield( sal_Int32 /*nNullDate*/, sal_Int32 /*nSettle*/, sal_Int32 /*nMat*/, sal_Int32 /*nIssue*/,
|
|
|
|
sal_Int32 /*nFirstCoup*/, double /*fRate*/, double /*fPrice*/, double /*fRedemp*/, sal_Int32 /*nFreq*/,
|
|
|
|
sal_Int32 /*nBase*/ ) THROWDEF_RTE_IAE
|
2001-05-07 05:56:53 +00:00
|
|
|
{
|
2001-09-26 12:22:24 +00:00
|
|
|
THROW_RTE; // #87380#
|
|
|
|
/*
|
2001-08-24 06:16:52 +00:00
|
|
|
//GetOddfprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
|
|
|
|
//sal_Int32 nFirstCoup, double fRate, double fYield, double fRedemp, sal_Int32 nFreq,
|
|
|
|
//sal_Int32 nBase )
|
|
|
|
double fPriceN = 0.0;
|
|
|
|
double fYield1 = 0.0;
|
|
|
|
double fYield2 = 1.0;
|
|
|
|
double fPrice1 = GetOddfprice( nNullDate, nSettle, nMat, nIssue, nFirstCoup, fRate, fYield1, fRedemp, nFreq, nBase );
|
|
|
|
double fPrice2 = GetOddfprice( nNullDate, nSettle, nMat, nIssue, nFirstCoup, fRate, fYield2, fRedemp, nFreq, nBase );
|
|
|
|
double fYieldN = ( fYield2 - fYield1 ) * 0.5;
|
|
|
|
|
|
|
|
for( sal_uInt32 nIter = 0 ; nIter < 100 && fPriceN != fPrice ; nIter++ )
|
|
|
|
{
|
|
|
|
fPriceN = GetOddfprice( nNullDate, nSettle, nMat, nIssue, nFirstCoup, fRate, fYieldN, fRedemp, nFreq, nBase );
|
|
|
|
|
|
|
|
if( fPrice == fPrice1 )
|
|
|
|
return fYield1;
|
|
|
|
else if( fPrice == fPrice2 )
|
|
|
|
return fYield2;
|
|
|
|
else if( fPrice == fPriceN )
|
|
|
|
return fYieldN;
|
|
|
|
else if( fPrice < fPrice2 )
|
|
|
|
{
|
|
|
|
fYield2 *= 2.0;
|
|
|
|
fPrice2 = GetOddfprice( nNullDate, nSettle, nMat, nIssue, nFirstCoup, fRate, fYield2, fRedemp, nFreq, nBase );
|
|
|
|
|
|
|
|
fYieldN = ( fYield2 - fYield1 ) * 0.5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( fPrice < fPriceN )
|
|
|
|
{
|
|
|
|
fYield1 = fYieldN;
|
|
|
|
fPrice1 = fPriceN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fYield2 = fYieldN;
|
|
|
|
fPrice2 = fPriceN;
|
|
|
|
}
|
|
|
|
|
|
|
|
fYieldN = fYield2 - ( fYield2 - fYield1 ) * ( ( fPrice - fPrice2 ) / ( fPrice1 - fPrice2 ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fabs( fPrice - fPriceN ) > fPrice / 100.0 )
|
|
|
|
THROW_IAE; // result not precise enough
|
|
|
|
|
|
|
|
return fYieldN;
|
2001-09-26 12:22:24 +00:00
|
|
|
*/
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-23 15:13:18 +00:00
|
|
|
double GetOddlprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastCoup,
|
2001-05-07 05:56:53 +00:00
|
|
|
double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2001-08-23 15:13:18 +00:00
|
|
|
double fFreq = double( nFreq );
|
|
|
|
double fDCi = GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;
|
|
|
|
double fDSCi = GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;
|
|
|
|
double fAi = GetYearFrac( nNullDate, nLastCoup, nSettle, nBase ) * fFreq;
|
|
|
|
|
|
|
|
double p = fRedemp + fDCi * 100.0 * fRate / fFreq;
|
2001-08-31 07:23:29 +00:00
|
|
|
p /= fDSCi * fYield / fFreq + 1.0;
|
|
|
|
p -= fAi * 100.0 * fRate / fFreq;
|
2001-08-23 15:13:18 +00:00
|
|
|
|
|
|
|
return p;
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-23 15:13:18 +00:00
|
|
|
double GetOddlyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastCoup,
|
2001-05-07 05:56:53 +00:00
|
|
|
double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2001-08-23 15:13:18 +00:00
|
|
|
double fFreq = double( nFreq );
|
|
|
|
double fDCi = GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;
|
|
|
|
double fDSCi = GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;
|
|
|
|
double fAi = GetYearFrac( nNullDate, nLastCoup, nSettle, nBase ) * fFreq;
|
|
|
|
|
|
|
|
double y = fRedemp + fDCi * 100.0 * fRate / fFreq;
|
|
|
|
y /= fPrice + fAi * 100.0 * fRate / fFreq;
|
|
|
|
y--;
|
|
|
|
y *= fFreq / fDSCi;
|
|
|
|
|
|
|
|
return y;
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetRmz( double fZins, double fZzr, double fBw, double fZw, sal_Int32 nF )
|
|
|
|
{
|
|
|
|
double fRmz;
|
|
|
|
if( fZins == 0.0 )
|
|
|
|
fRmz = ( fBw + fZw ) / fZzr;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double fTerm = pow( 1.0 + fZins, fZzr );
|
|
|
|
if( nF > 0 )
|
|
|
|
fRmz = ( fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins / ( 1.0 - 1.0 / fTerm ) ) / ( 1.0 + fZins );
|
|
|
|
else
|
|
|
|
fRmz = fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins / ( 1.0 - 1.0 / fTerm );
|
|
|
|
}
|
|
|
|
|
|
|
|
return -fRmz;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetZw( double fZins, double fZzr, double fRmz, double fBw, sal_Int32 nF )
|
|
|
|
{
|
|
|
|
double fZw;
|
|
|
|
if( fZins == 0.0 )
|
|
|
|
fZw = fBw + fRmz * fZzr;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double fTerm = pow( 1.0 + fZins, fZzr );
|
|
|
|
if( nF > 0 )
|
|
|
|
fZw = fBw * fTerm + fRmz * ( 1.0 + fZins ) * ( fTerm - 1.0 ) / fZins;
|
|
|
|
else
|
|
|
|
fZw = fBw * fTerm + fRmz * ( fTerm - 1.0 ) / fZins;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -fZw;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*double TBillYield( constREFXPS& xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
sal_Int32 nDiff = GetDiffDate360( xOpt, nSettle, nMat, sal_True );
|
|
|
|
|
|
|
|
if( fPrice <= 0.0 || nSettle >= nMat || nDiff > 360 )
|
|
|
|
THROW_IAE;
|
|
|
|
|
|
|
|
double fRet = 100.0;
|
|
|
|
fRet /= fPrice;
|
|
|
|
fRet--;
|
|
|
|
fRet *= double( nDiff );
|
|
|
|
fRet /= 360.0;
|
|
|
|
|
|
|
|
return fRet;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
2001-08-16 10:10:37 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// financial functions COUP***
|
|
|
|
|
|
|
|
|
|
|
|
//-------
|
|
|
|
// COUPPCD: find last coupon date before settlement (can be equal to settlement)
|
2001-10-09 10:09:01 +00:00
|
|
|
void lcl_GetCouppcd( ScaDate& rDate, const ScaDate& rSettle, const ScaDate& rMat, sal_Int32 nFreq )
|
2001-10-12 08:27:13 +00:00
|
|
|
throw( lang::IllegalArgumentException )
|
2001-08-16 10:10:37 +00:00
|
|
|
{
|
|
|
|
rDate = rMat;
|
2001-10-25 10:08:29 +00:00
|
|
|
rDate.setYear( rSettle.getYear() );
|
2001-08-16 10:10:37 +00:00
|
|
|
if( rDate < rSettle )
|
2001-10-09 10:09:01 +00:00
|
|
|
rDate.addYears( 1 );
|
2001-08-16 10:10:37 +00:00
|
|
|
while( rDate > rSettle )
|
2001-10-12 08:27:13 +00:00
|
|
|
rDate.addMonths( -12 / nFreq );
|
2001-08-16 10:10:37 +00:00
|
|
|
}
|
2001-05-07 05:56:53 +00:00
|
|
|
|
|
|
|
double GetCouppcd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
|
|
|
|
THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( nSettle >= nMat || CHK_Freq )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDate aDate;
|
|
|
|
lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
|
|
|
|
return aDate.getDate( nNullDate );
|
2001-08-16 10:10:37 +00:00
|
|
|
}
|
2001-05-07 05:56:53 +00:00
|
|
|
|
|
|
|
|
2001-08-16 10:10:37 +00:00
|
|
|
//-------
|
|
|
|
// COUPNCD: find first coupon date after settlement (is never equal to settlement)
|
2001-10-09 10:09:01 +00:00
|
|
|
void lcl_GetCoupncd( ScaDate& rDate, const ScaDate& rSettle, const ScaDate& rMat, sal_Int32 nFreq )
|
2001-10-12 08:27:13 +00:00
|
|
|
throw( lang::IllegalArgumentException )
|
2001-08-16 10:10:37 +00:00
|
|
|
{
|
|
|
|
rDate = rMat;
|
2001-10-25 10:08:29 +00:00
|
|
|
rDate.setYear( rSettle.getYear() );
|
2001-08-16 10:10:37 +00:00
|
|
|
if( rDate > rSettle )
|
2001-10-12 08:27:13 +00:00
|
|
|
rDate.addYears( -1 );
|
2001-08-16 10:10:37 +00:00
|
|
|
while( rDate <= rSettle )
|
2001-10-12 08:27:13 +00:00
|
|
|
rDate.addMonths( 12 / nFreq );
|
2001-08-16 10:10:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double GetCoupncd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
|
|
|
|
THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( nSettle >= nMat || CHK_Freq )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDate aDate;
|
|
|
|
lcl_GetCoupncd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
|
|
|
|
return aDate.getDate( nNullDate );
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-16 10:10:37 +00:00
|
|
|
//-------
|
2001-08-17 09:00:19 +00:00
|
|
|
// COUPDAYBS: get day count: coupon date before settlement <-> settlement
|
|
|
|
double GetCoupdaybs( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
|
2001-05-07 05:56:53 +00:00
|
|
|
THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( nSettle >= nMat || CHK_Freq )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDate aSettle( nNullDate, nSettle, nBase );
|
|
|
|
ScaDate aDate;
|
|
|
|
lcl_GetCouppcd( aDate, aSettle, ScaDate( nNullDate, nMat, nBase ), nFreq );
|
|
|
|
return ScaDate::getDiff( aDate, aSettle );
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-16 10:10:37 +00:00
|
|
|
//-------
|
|
|
|
// COUPDAYSNC: get day count: settlement <-> coupon date after settlement
|
2001-05-07 05:56:53 +00:00
|
|
|
double GetCoupdaysnc( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
|
|
|
|
THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( nSettle >= nMat || CHK_Freq )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2001-08-17 09:00:19 +00:00
|
|
|
if( (nBase != 0) && (nBase != 4) )
|
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDate aSettle( nNullDate, nSettle, nBase );
|
|
|
|
ScaDate aDate;
|
|
|
|
lcl_GetCoupncd( aDate, aSettle, ScaDate( nNullDate, nMat, nBase ), nFreq );
|
|
|
|
return ScaDate::getDiff( aSettle, aDate );
|
2001-08-17 09:00:19 +00:00
|
|
|
}
|
|
|
|
return GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase ) - GetCoupdaybs( nNullDate, nSettle, nMat, nFreq, nBase );
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-16 10:10:37 +00:00
|
|
|
//-------
|
|
|
|
// COUPDAYS: get day count: coupon date before settlement <-> coupon date after settlement
|
|
|
|
double GetCoupdays( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
|
2001-05-07 05:56:53 +00:00
|
|
|
THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( nSettle >= nMat || CHK_Freq )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2001-08-17 09:00:19 +00:00
|
|
|
if( nBase == 1 )
|
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDate aDate;
|
|
|
|
lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
|
|
|
|
ScaDate aNextDate( aDate );
|
2001-10-12 08:27:13 +00:00
|
|
|
aNextDate.addMonths( 12 / nFreq );
|
2001-10-09 10:09:01 +00:00
|
|
|
return ScaDate::getDiff( aDate, aNextDate );
|
2001-08-17 09:00:19 +00:00
|
|
|
}
|
|
|
|
return static_cast< double >( GetDaysInYear( 0, 0, nBase ) ) / nFreq;
|
2001-08-16 10:10:37 +00:00
|
|
|
}
|
|
|
|
|
2001-05-07 05:56:53 +00:00
|
|
|
|
2001-08-16 10:10:37 +00:00
|
|
|
//-------
|
|
|
|
// COUPNUM: get count of coupon dates
|
|
|
|
double GetCoupnum( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
|
|
|
|
THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( nSettle >= nMat || CHK_Freq )
|
|
|
|
THROW_IAE;
|
2001-05-07 05:56:53 +00:00
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDate aMat( nNullDate, nMat, nBase );
|
|
|
|
ScaDate aDate;
|
|
|
|
lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), aMat, nFreq );
|
2001-10-25 10:08:29 +00:00
|
|
|
sal_uInt16 nMonths = (aMat.getYear() - aDate.getYear()) * 12 + aMat.getMonth() - aDate.getMonth();
|
2001-08-16 10:10:37 +00:00
|
|
|
return static_cast< double >( nMonths * nFreq / 12 );
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
2001-08-16 10:10:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
const sal_uInt32 MyList::nStartSize = 16;
|
|
|
|
const sal_uInt32 MyList::nIncrSize = 16;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
void MyList::_Grow( void )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
nSize += nIncrSize;
|
|
|
|
|
|
|
|
void** pNewData = new void*[ nSize ];
|
|
|
|
memcpy( pNewData, pData, nNew * sizeof( void* ) );
|
|
|
|
|
2001-10-02 06:48:57 +00:00
|
|
|
delete[] pData;
|
2001-04-06 12:59:16 +00:00
|
|
|
pData = pNewData;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
MyList::MyList( void )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
nSize = nStartSize;
|
|
|
|
pData = new void*[ nSize ];
|
|
|
|
nNew = nAct = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
MyList::~MyList()
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-02 06:48:57 +00:00
|
|
|
delete[] pData;
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
void MyList::Insert( void* p, sal_uInt32 n )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
if( n >= nNew )
|
|
|
|
Append( p );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Grow();
|
|
|
|
|
|
|
|
void** pIns = pData + n;
|
2001-07-19 13:14:44 +00:00
|
|
|
memmove( pIns + 1, pIns, ( nNew - n ) * sizeof( void* ) );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
*pIns = p;
|
|
|
|
|
|
|
|
nNew++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
StringList::~StringList()
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-06-18 12:00:32 +00:00
|
|
|
for( STRING* p = ( STRING* ) First() ; p ; p = ( STRING* ) Next() )
|
|
|
|
delete p;
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
sal_Bool StringList::Contains( const STRING& r ) const
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-06-18 12:00:32 +00:00
|
|
|
sal_uInt32 n = 0;
|
|
|
|
const STRING* p = Get( n );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
while( p )
|
2001-05-10 14:27:43 +00:00
|
|
|
{
|
2001-06-18 12:00:32 +00:00
|
|
|
if( *p == r )
|
|
|
|
return sal_True;
|
|
|
|
|
|
|
|
n++;
|
|
|
|
p = Get( n );
|
2001-05-10 14:27:43 +00:00
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
return sal_False;
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
class AnalysisRscStrArrLoader : public Resource
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-06-18 12:00:32 +00:00
|
|
|
private:
|
|
|
|
ResStringArray aStrArray;
|
|
|
|
public:
|
|
|
|
AnalysisRscStrArrLoader( sal_uInt16 nRsc, sal_uInt16 nArrayId, ResMgr& rResMgr ) :
|
|
|
|
Resource( AnalysisResId( nRsc, rResMgr ) ),
|
|
|
|
aStrArray( AnalysisResId( nArrayId, rResMgr ) )
|
|
|
|
{
|
|
|
|
FreeResource();
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
const ResStringArray& GetStringArray() const { return aStrArray; }
|
|
|
|
};
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
FuncData::FuncData( const FuncDataBase& r, ResMgr& rResMgr ) :
|
|
|
|
aIntName( OUString::createFromAscii( r.pIntName ) ),
|
|
|
|
nUINameID( r.nUINameID ),
|
|
|
|
nDescrID( r.nDescrID ),
|
|
|
|
bDouble( r.bDouble ),
|
|
|
|
bWithOpt( r.bWithOpt ),
|
|
|
|
nParam( r.nNumOfParams ),
|
|
|
|
nCompID( r.nCompListID ),
|
|
|
|
eCat( r.eCat )
|
|
|
|
{
|
|
|
|
AnalysisRscStrArrLoader aArrLoader( RID_ANALYSIS_DEFFUNCTION_NAMES, nCompID, rResMgr );
|
|
|
|
// ResStringArray aDefFuncNameArray( AnalysisResId( nCompID, rResMgr ) );
|
|
|
|
const ResStringArray& rArr = aArrLoader.GetStringArray();
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( rArr.Count() );
|
2001-06-18 12:00:32 +00:00
|
|
|
sal_uInt16 n;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
for( n = 0 ; n < nCount ; n++ )
|
|
|
|
aCompList.Append( rArr.GetString( n ) );
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
FuncData::~FuncData()
|
|
|
|
{
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
sal_uInt16 FuncData::GetStrIndex( sal_uInt16 nParamNum ) const
|
|
|
|
{
|
|
|
|
if( !bWithOpt )
|
|
|
|
nParamNum++;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
if( nParamNum > nParam )
|
2001-06-28 11:49:49 +00:00
|
|
|
return nParam * 2;
|
2001-06-18 12:00:32 +00:00
|
|
|
else
|
|
|
|
return nParamNum * 2;
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
FuncDataList::FuncDataList( ResMgr& rResMgr )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-06-18 12:00:32 +00:00
|
|
|
const sal_uInt32 nNum = sizeof( pFuncDatas ) / sizeof( FuncDataBase );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-06-18 12:00:32 +00:00
|
|
|
for( sal_uInt16 n = 0 ; n < nNum ; n++ )
|
|
|
|
Append( new FuncData( pFuncDatas[ n ], rResMgr ) );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FuncDataList::~FuncDataList()
|
|
|
|
{
|
|
|
|
for( FuncData* p = ( FuncData* ) First() ; p ; p = ( FuncData* ) Next() )
|
|
|
|
delete p;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const FuncData* FuncDataList::Get( const OUString& aProgrammaticName ) const
|
|
|
|
{
|
|
|
|
if( aLastName == aProgrammaticName )
|
|
|
|
return Get( nLast );
|
|
|
|
|
|
|
|
( ( FuncDataList* ) this )->aLastName = aProgrammaticName;
|
|
|
|
|
|
|
|
sal_uInt32 nE = Count();
|
|
|
|
for( sal_uInt32 n = 0 ; n < nE ; n++ )
|
|
|
|
{
|
|
|
|
const FuncData* p = Get( n );
|
2001-06-18 12:00:32 +00:00
|
|
|
if( p->Is( aProgrammaticName ) )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
( ( FuncDataList* ) this )->nLast = n;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
( ( FuncDataList* ) this )->nLast = 0xFFFFFFFF;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 07:10:20 +00:00
|
|
|
AnalysisResId::AnalysisResId( sal_uInt16 nId, ResMgr& rResMgr ) : ResId( nId, rResMgr )
|
2001-06-18 12:00:32 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
SortedIndividualInt32List::SortedIndividualInt32List()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SortedIndividualInt32List::~SortedIndividualInt32List()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void SortedIndividualInt32List::Insert( sal_Int32 nDay )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
sal_uInt32 nIndex = Count();
|
|
|
|
while( nIndex )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
nIndex--;
|
|
|
|
sal_Int32 nRef = Get( nIndex );
|
|
|
|
if( nDay == nRef )
|
2001-04-06 12:59:16 +00:00
|
|
|
return;
|
2001-10-09 10:09:01 +00:00
|
|
|
else if( nDay > nRef )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
MyList::Insert( (void*) nDay, nIndex + 1 );
|
2001-04-06 12:59:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2001-10-09 10:09:01 +00:00
|
|
|
MyList::Insert( (void*) nDay, 0UL );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SortedIndividualInt32List::Insert( sal_Int32 nDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend )
|
|
|
|
{
|
|
|
|
if( !nDay )
|
|
|
|
return;
|
|
|
|
|
|
|
|
nDay += nNullDate;
|
|
|
|
if( bInsertOnWeekend || (GetDayOfWeek( nDay ) < 5) )
|
|
|
|
Insert( nDay );
|
|
|
|
}
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void SortedIndividualInt32List::Insert(
|
|
|
|
double fDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
if( (fDay < -2147483648.0) || (fDay > 2147483649.0) )
|
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
Insert( static_cast< sal_Int32 >( fDay ), nNullDate, bInsertOnWeekend );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sal_Int32 SortedIndividualInt32List::CountCondition( sal_Int32 nMinVal, sal_Int32 nMaxVal ) const
|
|
|
|
{
|
|
|
|
sal_uInt32 nE = Count();
|
|
|
|
|
|
|
|
if( !nE || nMaxVal < Get( 0 ) || nMinVal > Get( nE - 1 ) )
|
|
|
|
// don't care if list is empty
|
2001-10-09 10:09:01 +00:00
|
|
|
// ~ if nMaxVal is smaller than smallest value in list
|
2001-04-06 12:59:16 +00:00
|
|
|
// ~ if nMinVal is bigger than biggest value in list
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
sal_uInt32 n;
|
|
|
|
sal_Int32 nCnt = 0;
|
|
|
|
|
|
|
|
for( n = 0 ; n < nE && Get( n ) < nMinVal ; n++); // skip values less than nMinVal
|
|
|
|
|
|
|
|
for( ; n < nE ; n++ )
|
|
|
|
{
|
|
|
|
if( Get( n ) <= nMaxVal )
|
|
|
|
nCnt++;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nCnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sal_Bool SortedIndividualInt32List::Find( sal_Int32 nVal ) const
|
|
|
|
{
|
|
|
|
sal_uInt32 nE = Count();
|
|
|
|
|
|
|
|
if( !nE || nVal < Get( 0 ) || nVal > Get( nE - 1 ) )
|
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
// linear search
|
|
|
|
|
|
|
|
for( sal_uInt32 n = 0 ; n < nE ; n++ )
|
|
|
|
{
|
|
|
|
sal_Int32 nRef = Get( n );
|
|
|
|
|
|
|
|
if( nRef == nVal )
|
|
|
|
return sal_True;
|
|
|
|
else if( nRef > nVal )
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void SortedIndividualInt32List::InsertHolidayList(
|
|
|
|
const uno::Sequence< uno::Sequence< sal_Int32 > >& rHolidaySeq,
|
|
|
|
sal_Int32 nNullDate, sal_Bool bInsertOnWeekend )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
const uno::Sequence< sal_Int32 >* pSeqArray = rHolidaySeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex1 = 0; nIndex1 < rHolidaySeq.getLength(); nIndex1++ )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
const uno::Sequence< sal_Int32 >& rSubSeq = pSeqArray[ nIndex1 ];
|
|
|
|
const sal_Int32* pArray = rSubSeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
|
|
|
|
Insert( pArray[ nIndex2 ], nNullDate, bInsertOnWeekend );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void SortedIndividualInt32List::InsertHolidayList(
|
|
|
|
const uno::Sequence< double >& rHolidaySeq,
|
|
|
|
sal_Int32 nNullDate,
|
|
|
|
sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-05-07 05:56:53 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
const double* pArray = rHolidaySeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex = 0; nIndex < rHolidaySeq.getLength(); nIndex++ )
|
|
|
|
Insert( pArray[ nIndex ], nNullDate, bInsertOnWeekend );
|
|
|
|
}
|
2001-05-07 05:56:53 +00:00
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void SortedIndividualInt32List::InsertHolidayList(
|
|
|
|
const ScaAnyConverter& rAnyConv,
|
|
|
|
const uno::Any& rHolAny,
|
|
|
|
sal_Int32 nNullDate,
|
|
|
|
sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
double fDay;
|
|
|
|
if( rAnyConv.getDouble( fDay, rHolAny ) )
|
|
|
|
Insert( fDay, nNullDate, bInsertOnWeekend );
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SortedIndividualInt32List::InsertHolidayList(
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaAnyConverter& rAnyConv,
|
|
|
|
const uno::Reference< beans::XPropertySet >& xOptions,
|
|
|
|
const uno::Any& rHolAny,
|
|
|
|
sal_Int32 nNullDate,
|
|
|
|
sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-05-07 05:56:53 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
rAnyConv.init( xOptions );
|
|
|
|
if( rHolAny.getValueTypeClass() == uno::TypeClass_SEQUENCE )
|
2001-05-07 05:56:53 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
uno::Sequence< uno::Sequence< uno::Any > > aAnySeq;
|
|
|
|
if( rHolAny >>= aAnySeq )
|
|
|
|
{
|
|
|
|
const uno::Sequence< uno::Any >* pSeqArray = aAnySeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex1 = 0; nIndex1 < aAnySeq.getLength(); nIndex1++ )
|
2001-05-08 08:53:38 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
const uno::Sequence< uno::Any >& rSubSeq = pSeqArray[ nIndex1 ];
|
|
|
|
const uno::Any* pAnyArray = rSubSeq.getConstArray();
|
2001-05-08 08:53:38 +00:00
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
|
|
|
|
InsertHolidayList( rAnyConv, pAnyArray[ nIndex2 ], nNullDate, bInsertOnWeekend );
|
2001-05-08 08:53:38 +00:00
|
|
|
}
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
throw lang::IllegalArgumentException();
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
2001-10-09 10:09:01 +00:00
|
|
|
else
|
|
|
|
InsertHolidayList( rAnyConv, rHolAny, nNullDate, bInsertOnWeekend );
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
ScaDoubleList::~ScaDoubleList()
|
2001-05-09 11:33:08 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
for( double* pDbl = const_cast< double* >( First() ); pDbl; pDbl = const_cast< double* >( Next() ) )
|
|
|
|
delete pDbl;
|
2001-05-09 11:33:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void ScaDoubleList::Append(
|
|
|
|
const uno::Sequence< uno::Sequence< double > >& rValueSeq ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-05-09 11:33:08 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
const uno::Sequence< double >* pSeqArray = rValueSeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex1 = 0; nIndex1 < rValueSeq.getLength(); nIndex1++ )
|
|
|
|
{
|
|
|
|
const uno::Sequence< double >& rSubSeq = pSeqArray[ nIndex1 ];
|
|
|
|
const double* pArray = rSubSeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
|
|
|
|
Append( pArray[ nIndex2 ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScaDoubleList::Append(
|
|
|
|
const uno::Sequence< uno::Sequence< sal_Int32 > >& rValueSeq ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
const uno::Sequence< sal_Int32 >* pSeqArray = rValueSeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex1 = 0; nIndex1 < rValueSeq.getLength(); nIndex1++ )
|
|
|
|
{
|
|
|
|
const uno::Sequence< sal_Int32 >& rSubSeq = pSeqArray[ nIndex1 ];
|
|
|
|
const sal_Int32* pArray = rSubSeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
|
|
|
|
Append( pArray[ nIndex2 ] );
|
|
|
|
}
|
2001-05-09 11:33:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
|
|
|
|
void ScaDoubleList::Append(
|
|
|
|
const ScaAnyConverter& rAnyConv,
|
|
|
|
const uno::Any& rAny,
|
|
|
|
sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-05-09 11:33:08 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
if( rAny.getValueTypeClass() == uno::TypeClass_SEQUENCE )
|
|
|
|
Append( rAnyConv, *static_cast< const uno::Sequence< uno::Sequence< uno::Any > >* >( rAny.getValue() ), bIgnoreEmpty );
|
2001-05-09 11:33:08 +00:00
|
|
|
else
|
2001-10-09 10:09:01 +00:00
|
|
|
{
|
|
|
|
double fValue;
|
|
|
|
if( rAnyConv.getDouble( fValue, rAny ) )
|
|
|
|
Append( fValue );
|
|
|
|
else if( !bIgnoreEmpty )
|
|
|
|
Append( 0.0 );
|
|
|
|
}
|
2001-05-09 11:33:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void ScaDoubleList::Append(
|
|
|
|
const ScaAnyConverter& rAnyConv,
|
|
|
|
const uno::Sequence< uno::Any >& rAnySeq,
|
|
|
|
sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-05-09 11:33:08 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
const uno::Any* pArray = rAnySeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex = 0; nIndex < rAnySeq.getLength(); nIndex++ )
|
|
|
|
Append( rAnyConv, pArray[ nIndex ], bIgnoreEmpty );
|
2001-05-09 11:33:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void ScaDoubleList::Append(
|
|
|
|
const ScaAnyConverter& rAnyConv,
|
|
|
|
const uno::Sequence< uno::Sequence< uno::Any > >& rAnySeq,
|
|
|
|
sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-05-09 11:33:08 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
const uno::Sequence< uno::Any >* pArray = rAnySeq.getConstArray();
|
|
|
|
for( sal_Int32 nIndex = 0; nIndex < rAnySeq.getLength(); nIndex++ )
|
|
|
|
Append( rAnyConv, pArray[ nIndex ], bIgnoreEmpty );
|
2001-05-09 11:33:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
|
|
|
|
void ScaDoubleList::Append(
|
|
|
|
ScaAnyConverter& rAnyConv,
|
|
|
|
const uno::Reference< beans::XPropertySet >& xOpt,
|
|
|
|
const uno::Any& rAny,
|
|
|
|
sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
rAnyConv.init( xOpt );
|
|
|
|
Append( rAnyConv, rAny, bIgnoreEmpty );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void ScaDoubleList::Append(
|
|
|
|
ScaAnyConverter& rAnyConv,
|
|
|
|
const uno::Reference< beans::XPropertySet >& xOpt,
|
|
|
|
const uno::Sequence< uno::Any >& rAnySeq,
|
|
|
|
sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
rAnyConv.init( xOpt );
|
|
|
|
Append( rAnyConv, rAnySeq, bIgnoreEmpty );
|
2001-05-22 10:51:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
void ScaDoubleList::Append(
|
|
|
|
ScaAnyConverter& rAnyConv,
|
|
|
|
const uno::Reference< beans::XPropertySet >& xOpt,
|
|
|
|
const uno::Sequence< uno::Sequence< uno::Any > >& rAnySeq,
|
|
|
|
sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-05-07 05:56:53 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
rAnyConv.init( xOpt );
|
|
|
|
Append( rAnyConv, rAnySeq, bIgnoreEmpty );
|
2001-05-07 05:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-09 11:33:08 +00:00
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
sal_Bool ScaDoubleList::CheckInsert( double ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2001-05-09 11:33:08 +00:00
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
sal_Bool ScaDoubleListGT0::CheckInsert( double fValue ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
if( fValue < 0.0 )
|
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
return fValue > 0.0;
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
sal_Bool ScaDoubleListGE0::CheckInsert( double fValue ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
|
2001-05-09 11:33:08 +00:00
|
|
|
{
|
2001-10-09 10:09:01 +00:00
|
|
|
if( fValue < 0.0 )
|
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
return sal_True;
|
2001-05-09 11:33:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2001-05-09 11:33:08 +00:00
|
|
|
|
2005-04-13 07:38:38 +00:00
|
|
|
Complex::Complex( const STRING& rStr ) THROWDEF_RTE_IAE
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2005-04-13 07:38:38 +00:00
|
|
|
if( !ParseString( rStr, *this ) )
|
2001-04-06 12:59:16 +00:00
|
|
|
THROW_IAE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-11 09:09:35 +00:00
|
|
|
inline sal_Bool Complex::IsImagUnit( sal_Unicode c )
|
|
|
|
{
|
|
|
|
return c == 'i' || c == 'j';
|
|
|
|
}
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
sal_Bool Complex::ParseString( const STRING& rStr, Complex& rCompl )
|
|
|
|
{
|
2004-12-23 09:42:01 +00:00
|
|
|
rCompl.c = '\0'; // do not force a symbol, if only real part present
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
const sal_Unicode* pStr = ( const sal_Unicode * ) rStr;
|
2001-05-11 09:09:35 +00:00
|
|
|
|
2004-07-30 15:14:13 +00:00
|
|
|
if( IsImagUnit( *pStr ) && rStr.getLength() == 1)
|
2001-05-11 09:09:35 +00:00
|
|
|
{
|
|
|
|
rCompl.r = 0.0;
|
|
|
|
rCompl.i = 1.0;
|
2004-07-30 15:14:13 +00:00
|
|
|
rCompl.c = *pStr;
|
2001-05-11 09:09:35 +00:00
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
double f;
|
|
|
|
|
|
|
|
if( !ParseDouble( pStr, f ) )
|
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
switch( *pStr )
|
|
|
|
{
|
|
|
|
case '-': // imag part follows
|
|
|
|
case '+':
|
|
|
|
{
|
2001-05-11 10:55:58 +00:00
|
|
|
double r = f;
|
2001-05-11 09:09:35 +00:00
|
|
|
if( IsImagUnit( pStr[ 1 ] ) )
|
|
|
|
{
|
2004-07-30 15:14:13 +00:00
|
|
|
rCompl.c = pStr[ 1 ];
|
2001-05-11 09:09:35 +00:00
|
|
|
if( pStr[ 2 ] == 0 )
|
|
|
|
{
|
|
|
|
rCompl.r = f;
|
2001-07-11 12:32:01 +00:00
|
|
|
rCompl.i = ( *pStr == '+' )? 1.0 : -1.0;
|
2001-05-11 09:09:35 +00:00
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( ParseDouble( pStr, f ) && IsImagUnit( *pStr ) )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2004-07-30 15:14:13 +00:00
|
|
|
rCompl.c = *pStr;
|
2001-04-06 12:59:16 +00:00
|
|
|
pStr++;
|
|
|
|
if( *pStr == 0 )
|
|
|
|
{
|
|
|
|
rCompl.r = r;
|
|
|
|
rCompl.i = f;
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'j':
|
|
|
|
case 'i':
|
2004-07-30 15:14:13 +00:00
|
|
|
rCompl.c = *pStr;
|
2001-04-06 12:59:16 +00:00
|
|
|
pStr++;
|
|
|
|
if( *pStr == 0 )
|
|
|
|
{
|
|
|
|
rCompl.i = f;
|
|
|
|
rCompl.r = 0.0;
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0: // only real-part
|
|
|
|
rCompl.r = f;
|
|
|
|
rCompl.i = 0.0;
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-30 15:14:13 +00:00
|
|
|
STRING Complex::GetString() const THROWDEF_RTE_IAE
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
2005-04-13 07:38:38 +00:00
|
|
|
static const String aI( 'i' );
|
|
|
|
static const String aJ( 'j' );
|
|
|
|
static const String aPlus( '+' );
|
|
|
|
static const String aMinus( '-' );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-09-26 08:51:58 +00:00
|
|
|
CHK_FINITE(r);
|
|
|
|
CHK_FINITE(i);
|
2004-07-30 15:14:13 +00:00
|
|
|
STRING aRet;
|
2004-12-23 09:42:01 +00:00
|
|
|
|
|
|
|
bool bHasImag = i != 0.0;
|
|
|
|
bool bHasReal = !bHasImag || (r != 0.0);
|
2004-07-30 15:14:13 +00:00
|
|
|
|
|
|
|
if( bHasReal )
|
|
|
|
aRet = ::GetString( r );
|
2004-12-23 09:42:01 +00:00
|
|
|
if( bHasImag )
|
2004-07-30 15:14:13 +00:00
|
|
|
{
|
2004-12-23 09:42:01 +00:00
|
|
|
if( i == 1.0 )
|
|
|
|
{
|
|
|
|
if( bHasReal )
|
|
|
|
aRet += aPlus;
|
|
|
|
}
|
|
|
|
else if( i == -1.0 )
|
|
|
|
aRet += aMinus;
|
|
|
|
else
|
|
|
|
aRet += ::GetString( i, bHasReal );
|
|
|
|
aRet += (c != 'j') ? aI : aJ;
|
2004-07-30 15:14:13 +00:00
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double Complex::Arg( void ) const THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( r == 0.0 && i == 0.0 )
|
|
|
|
THROW_IAE;
|
|
|
|
|
|
|
|
double phi = acos( r / Abs() );
|
|
|
|
|
|
|
|
if( i < 0.0 )
|
|
|
|
phi = -phi;
|
|
|
|
|
|
|
|
return phi;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Complex::Power( double fPower ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( r == 0.0 && i == 0.0 )
|
|
|
|
{
|
|
|
|
if( fPower > 0 )
|
2001-07-11 07:36:17 +00:00
|
|
|
{
|
2001-04-06 12:59:16 +00:00
|
|
|
r = i = 0.0;
|
2001-07-11 07:36:17 +00:00
|
|
|
return;
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
else
|
|
|
|
THROW_IAE;
|
|
|
|
}
|
|
|
|
|
|
|
|
double p, phi;
|
|
|
|
|
|
|
|
p = Abs();
|
|
|
|
|
|
|
|
phi = acos( r / p );
|
|
|
|
if( i < 0.0 )
|
|
|
|
phi = -phi;
|
|
|
|
|
|
|
|
p = pow( p, fPower );
|
|
|
|
phi *= fPower;
|
|
|
|
|
|
|
|
r = cos( phi ) * p;
|
|
|
|
i = sin( phi ) * p;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-11 12:32:01 +00:00
|
|
|
void Complex::Sqrt( void )
|
|
|
|
{
|
|
|
|
static const double fMultConst = 0.7071067811865475; // ...2440084436210485 = 1/sqrt(2)
|
|
|
|
double p = Abs();
|
|
|
|
double i_ = sqrt( p - r ) * fMultConst;
|
|
|
|
|
|
|
|
r = sqrt( p + r ) * fMultConst;
|
|
|
|
i = ( i < 0.0 )? -i_ : i_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-13 09:10:54 +00:00
|
|
|
inline BOOL SinOverflow( double f )
|
|
|
|
{
|
|
|
|
return fabs( f ) >= 134217728;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
void Complex::Sin( void ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2001-08-13 09:10:54 +00:00
|
|
|
if( SinOverflow( r ) )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2001-07-11 12:32:01 +00:00
|
|
|
if( i )
|
|
|
|
{
|
|
|
|
double r_;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-07-11 12:32:01 +00:00
|
|
|
r_ = sin( r ) * cosh( i );
|
|
|
|
i = cos( r ) * sinh( i );
|
|
|
|
r = r_;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
r = sin( r );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Complex::Cos( void ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2001-08-13 09:10:54 +00:00
|
|
|
if( SinOverflow( r ) )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2001-07-11 12:32:01 +00:00
|
|
|
if( i )
|
|
|
|
{
|
|
|
|
double r_;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-07-11 12:32:01 +00:00
|
|
|
r_ = cos( r ) * cosh( i );
|
|
|
|
i = -( sin( r ) * sinh( i ) );
|
|
|
|
r = r_;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
r = cos( r );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Complex::Div( const Complex& z ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( z.r == 0 && z.i == 0 )
|
|
|
|
THROW_IAE;
|
|
|
|
|
|
|
|
double a1 = r;
|
|
|
|
double a2 = z.r;
|
|
|
|
double b1 = i;
|
|
|
|
double b2 = z.i;
|
|
|
|
|
|
|
|
double f = 1.0 / ( a2 * a2 + b2 * b2 );
|
|
|
|
|
|
|
|
r = ( a1 * a2 + b1 * b2 ) * f;
|
|
|
|
i = ( a2 * b1 - a1 * b2 ) * f;
|
2004-12-23 09:42:01 +00:00
|
|
|
|
|
|
|
if( !c ) c = z.c;
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Complex::Exp( void )
|
|
|
|
{
|
2001-05-11 10:55:58 +00:00
|
|
|
double fE = exp( r );
|
|
|
|
r = fE * cos( i );
|
|
|
|
i = fE * sin( i );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Complex::Ln( void ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( r == 0.0 && i == 0.0 )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2001-07-19 08:00:42 +00:00
|
|
|
double fAbs = Abs();
|
|
|
|
sal_Bool bNegi = i < 0.0;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-07-19 08:00:42 +00:00
|
|
|
i = acos( r / fAbs );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
2001-07-19 08:00:42 +00:00
|
|
|
if( bNegi )
|
|
|
|
i = -i;
|
|
|
|
|
|
|
|
r = log( fAbs );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Complex::Log10( void ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
Ln();
|
|
|
|
Mult( 0.434294481903251828 ); // * log10( e )
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Complex::Log2( void ) THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
Ln();
|
|
|
|
Mult( 1.442695040888963407 ); // * log2( e )
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ComplexList::~ComplexList()
|
|
|
|
{
|
|
|
|
for( Complex* p = ( Complex* ) First() ; p ; p = ( Complex* ) Next() )
|
|
|
|
delete p;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-18 08:16:23 +00:00
|
|
|
void ComplexList::Append( const SEQSEQ( STRING )& r, ComplListAppendHandl eAH ) THROWDEF_RTE_IAE
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
sal_Int32 n1, n2;
|
|
|
|
sal_Int32 nE1 = r.getLength();
|
|
|
|
sal_Int32 nE2;
|
2001-07-18 08:16:23 +00:00
|
|
|
sal_Bool bEmpty0 = eAH == AH_EmpyAs0;
|
|
|
|
sal_Bool bErrOnEmpty = eAH == AH_EmptyAsErr;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
for( n1 = 0 ; n1 < nE1 ; n1++ )
|
|
|
|
{
|
|
|
|
const SEQ( STRING )& rList = r[ n1 ];
|
|
|
|
nE2 = rList.getLength();
|
|
|
|
|
|
|
|
for( n2 = 0 ; n2 < nE2 ; n2++ )
|
2001-05-08 11:20:21 +00:00
|
|
|
{
|
|
|
|
const STRING& rStr = rList[ n2 ];
|
|
|
|
|
2001-05-14 07:38:20 +00:00
|
|
|
if( rStr.getLength() )
|
2001-05-08 11:20:21 +00:00
|
|
|
Append( new Complex( rStr ) );
|
|
|
|
else if( bEmpty0 )
|
|
|
|
Append( new Complex( 0.0 ) );
|
2001-07-18 08:16:23 +00:00
|
|
|
else if( bErrOnEmpty )
|
2001-05-08 11:20:21 +00:00
|
|
|
THROW_IAE;
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-18 08:16:23 +00:00
|
|
|
void ComplexList::Append( const SEQ( ANY )& aMultPars, ComplListAppendHandl eAH ) THROWDEF_RTE_IAE
|
2001-05-07 05:56:53 +00:00
|
|
|
{
|
2006-06-19 22:11:26 +00:00
|
|
|
sal_Int32 nEle = aMultPars.getLength();
|
2001-07-18 08:16:23 +00:00
|
|
|
sal_Bool bEmpty0 = eAH == AH_EmpyAs0;
|
|
|
|
sal_Bool bErrOnEmpty = eAH == AH_EmptyAsErr;
|
2001-05-07 05:56:53 +00:00
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
for( sal_Int32 i = 0 ; i < nEle ; i++ )
|
2001-05-07 05:56:53 +00:00
|
|
|
{
|
2006-06-19 22:11:26 +00:00
|
|
|
const ANY& r = aMultPars[ i ];
|
2001-05-07 05:56:53 +00:00
|
|
|
switch( r.getValueTypeClass() )
|
|
|
|
{
|
|
|
|
case uno::TypeClass_VOID: break;
|
2001-05-08 08:53:38 +00:00
|
|
|
case uno::TypeClass_STRING:
|
2001-05-08 11:20:21 +00:00
|
|
|
{
|
|
|
|
const STRING* pStr = ( const STRING* ) r.getValue();
|
|
|
|
|
2001-05-14 07:38:20 +00:00
|
|
|
if( pStr->getLength() )
|
2001-05-08 11:20:21 +00:00
|
|
|
Append( new Complex( *( STRING* ) r.getValue() ) );
|
|
|
|
else if( bEmpty0 )
|
|
|
|
Append( new Complex( 0.0 ) );
|
2001-07-18 08:16:23 +00:00
|
|
|
else if( bErrOnEmpty )
|
2001-05-08 11:20:21 +00:00
|
|
|
THROW_IAE;
|
|
|
|
}
|
2001-05-08 08:53:38 +00:00
|
|
|
break;
|
|
|
|
case uno::TypeClass_DOUBLE:
|
|
|
|
Append( new Complex( *( double* ) r.getValue(), 0.0 ) );
|
|
|
|
break;
|
|
|
|
case uno::TypeClass_SEQUENCE:
|
|
|
|
{
|
2001-05-09 11:33:08 +00:00
|
|
|
SEQSEQ( ANY ) aValArr;
|
2001-05-08 08:53:38 +00:00
|
|
|
if( r >>= aValArr )
|
|
|
|
{
|
2001-05-09 11:33:08 +00:00
|
|
|
sal_Int32 nE = aValArr.getLength();
|
|
|
|
const SEQ( ANY )* pArr = aValArr.getConstArray();
|
2001-05-08 08:53:38 +00:00
|
|
|
for( sal_Int32 n = 0 ; n < nE ; n++ )
|
2001-07-18 08:16:23 +00:00
|
|
|
Append( pArr[ n ], eAH );
|
2001-05-08 08:53:38 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
THROW_IAE;
|
|
|
|
}
|
|
|
|
break;
|
2001-05-07 05:56:53 +00:00
|
|
|
default:
|
|
|
|
THROW_IAE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
ConvertData::ConvertData( const sal_Char p[], double fC, ConvertDataClass e ) : aName( p, strlen( p ), RTL_TEXTENCODING_MS_1252 )
|
|
|
|
{
|
|
|
|
fConst = fC;
|
|
|
|
eClass = e;
|
|
|
|
}
|
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
ConvertData::~ConvertData()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
sal_Int16 ConvertData::GetMatchingLevel( const STRING& rRef ) const
|
|
|
|
{
|
|
|
|
if( aName.equals( rRef ) )
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const sal_Unicode* p = rRef.getStr();
|
|
|
|
|
2001-05-08 14:27:45 +00:00
|
|
|
if ( aName == p + 1 )
|
2001-04-06 12:59:16 +00:00
|
|
|
{
|
|
|
|
sal_Int16 n;
|
|
|
|
switch( *p )
|
|
|
|
{
|
|
|
|
case 'y': n = -24; break; // yocto
|
|
|
|
case 'z': n = -21; break; // zepto
|
|
|
|
case 'a': n = -18; break;
|
|
|
|
case 'f': n = -15; break;
|
|
|
|
case 'p': n = -12; break;
|
|
|
|
case 'n': n = -9; break;
|
|
|
|
case 'u': n = -6; break;
|
|
|
|
case 'm': n = -3; break;
|
|
|
|
case 'c': n = -2; break;
|
|
|
|
case 'd': n = -1; break;
|
|
|
|
case 'e': n = 1; break;
|
|
|
|
case 'h': n = 2; break;
|
|
|
|
case 'k': n = 3; break;
|
|
|
|
case 'M': n = 6; break;
|
|
|
|
case 'G': n = 9; break;
|
|
|
|
case 'T': n = 12; break;
|
|
|
|
case 'P': n = 15; break;
|
|
|
|
case 'E': n = 18; break;
|
|
|
|
case 'Z': n = 21; break; // zetta
|
|
|
|
case 'Y': n = 24; break; // yotta
|
|
|
|
default:
|
|
|
|
n = INV_MATCHLEV;
|
|
|
|
}
|
|
|
|
|
2002-08-08 10:28:10 +00:00
|
|
|
//! <HACK> #100616# "cm3" is not 10^-2 m^3 but 10^-6 m^3 !!! ------------------
|
|
|
|
if( n != INV_MATCHLEV )
|
|
|
|
{
|
|
|
|
sal_Unicode cLast = p[ rRef.getLength() - 1 ];
|
|
|
|
if( cLast == '2' )
|
|
|
|
n *= 2;
|
|
|
|
else if( cLast == '3' )
|
|
|
|
n *= 3;
|
|
|
|
}
|
|
|
|
//! </HACK> -------------------------------------------------------------------
|
|
|
|
|
2001-04-06 12:59:16 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return INV_MATCHLEV;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double ConvertData::Convert(
|
|
|
|
double f, const ConvertData& r, sal_Int16 nLevFrom, sal_Int16 nLevTo ) const THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( Class() != r.Class() )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
nLevFrom = sal::static_int_cast<sal_Int16>( nLevFrom - nLevTo ); // effective level
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
f *= r.fConst / fConst;
|
|
|
|
|
|
|
|
if( nLevFrom )
|
2003-03-26 16:46:50 +00:00
|
|
|
f = ::rtl::math::pow10Exp( f, nLevFrom );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double ConvertData::ConvertToBase( double f, sal_Int16 n ) const
|
|
|
|
{
|
2003-03-26 16:46:50 +00:00
|
|
|
return ::rtl::math::pow10Exp( f / fConst, n );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double ConvertData::ConvertFromBase( double f, sal_Int16 n ) const
|
|
|
|
{
|
2003-03-26 16:46:50 +00:00
|
|
|
return ::rtl::math::pow10Exp( f * fConst, -n );
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-06-19 22:11:26 +00:00
|
|
|
ConvertDataLinear::~ConvertDataLinear()
|
|
|
|
{
|
|
|
|
}
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
double ConvertDataLinear::Convert(
|
|
|
|
double f, const ConvertData& r, sal_Int16 nLevFrom, sal_Int16 nLevTo ) const THROWDEF_RTE_IAE
|
|
|
|
{
|
|
|
|
if( Class() != r.Class() )
|
|
|
|
THROW_IAE;
|
|
|
|
|
2003-03-26 16:46:50 +00:00
|
|
|
// return ::rtl::math::round( r.ConvertFromBase( ConvertToBase( f, nLevFrom ), nLevTo ), 13 );
|
2001-04-06 12:59:16 +00:00
|
|
|
return r.ConvertFromBase( ConvertToBase( f, nLevFrom ), nLevTo );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double ConvertDataLinear::ConvertToBase( double f, sal_Int16 n ) const
|
|
|
|
{
|
|
|
|
if( n )
|
2003-03-26 16:46:50 +00:00
|
|
|
f = ::rtl::math::pow10Exp( f, n );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
f /= fConst;
|
|
|
|
f -= fOffs;
|
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double ConvertDataLinear::ConvertFromBase( double f, sal_Int16 n ) const
|
|
|
|
{
|
|
|
|
f += fOffs;
|
|
|
|
f *= fConst;
|
|
|
|
|
|
|
|
if( n )
|
2003-03-26 16:46:50 +00:00
|
|
|
f = ::rtl::math::pow10Exp( f, -n );
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConvertDataList::ConvertDataList( void )
|
|
|
|
{
|
|
|
|
#define NEWD(str,unit,cl) Append(new ConvertData(str,unit,cl))
|
|
|
|
#define NEWL(str,unit,offs,cl) Append(new ConvertDataLinear(str,unit,offs,cl))
|
|
|
|
|
|
|
|
// *** are extra and not standard Excel Analysis Addin!
|
|
|
|
|
2002-07-09 12:03:17 +00:00
|
|
|
// MASS: 1 Gram is...
|
|
|
|
NEWD( "g", 1.0000000000000000E00, CDC_Mass ); // Gram
|
|
|
|
NEWD( "sg", 6.8522050005347800E-05, CDC_Mass ); // Pieces
|
|
|
|
NEWD( "lbm", 2.2046229146913400E-03, CDC_Mass ); // Pound (commercial weight)
|
|
|
|
NEWD( "u", 6.0221370000000000E23, CDC_Mass ); // U (atomic mass)
|
|
|
|
NEWD( "ozm", 3.5273971800362700E-02, CDC_Mass ); // Ounce (commercial weight)
|
|
|
|
NEWD( "stone", 1.574730e-04, CDC_Mass ); // *** Stone
|
|
|
|
NEWD( "ton", 1.102311e-06, CDC_Mass ); // *** Ton
|
|
|
|
NEWD( "grain", 1.543236E01, CDC_Mass ); // *** Grain
|
|
|
|
NEWD( "pweight", 7.054792E-01, CDC_Mass ); // *** Pennyweight
|
|
|
|
NEWD( "hweight", 1.968413E-05, CDC_Mass ); // *** Hundredweight
|
|
|
|
NEWD( "shweight", 2.204623E-05, CDC_Mass ); // *** Shorthundredweight
|
|
|
|
NEWD( "brton", 9.842065E-07, CDC_Mass ); // *** Gross Registered Ton
|
|
|
|
|
|
|
|
// LENGTH: 1 Meter is...
|
|
|
|
NEWD( "m", 1.0000000000000000E00, CDC_Length ); // Meter
|
|
|
|
NEWD( "mi", 6.2137119223733397E-04, CDC_Length ); // Britsh Mile 6,21371192237333969617434184363e-4
|
|
|
|
NEWD( "Nmi", 5.3995680345572354E-04, CDC_Length ); // Nautical Mile 5,39956803455723542116630669546e-4
|
|
|
|
NEWD( "in", 3.9370078740157480E01, CDC_Length ); // Inch 39,37007874015748031496062992126
|
|
|
|
NEWD( "ft", 3.2808398950131234E00, CDC_Length ); // Foot 3,2808398950131233595800524934383
|
|
|
|
NEWD( "yd", 1.0936132983377078E00, CDC_Length ); // Yard 1,0936132983377077865266841644794
|
|
|
|
NEWD( "ang", 1.0000000000000000E10, CDC_Length ); // Angstroem
|
|
|
|
NEWD( "Pica", 2.8346456692913386E03, CDC_Length ); // Pica (1/72 Inch) 2834,6456692913385826771653543307
|
|
|
|
NEWD( "ell", 8.748906E-01, CDC_Length ); // *** Ell
|
|
|
|
NEWD( "parsec", 3.240779E-17, CDC_Length ); // *** Parsec
|
|
|
|
NEWD( "lightyear", 1.0570234557732930E-16, CDC_Length ); // *** Light Year
|
|
|
|
|
|
|
|
// TIME: 1 Second is...
|
|
|
|
NEWD( "yr", 3.1688087814028950E-08, CDC_Time ); // Year
|
|
|
|
NEWD( "day", 1.1574074074074074E-05, CDC_Time ); // Day
|
|
|
|
NEWD( "hr", 2.7777777777777778E-04, CDC_Time ); // Hour
|
|
|
|
NEWD( "mn", 1.6666666666666667E-02, CDC_Time ); // Minute
|
|
|
|
NEWD( "sec", 1.0000000000000000E00, CDC_Time ); // Second
|
|
|
|
|
|
|
|
// PRESSURE: 1 Pascal is...
|
|
|
|
NEWD( "Pa", 1.0000000000000000E00, CDC_Pressure ); // Pascal
|
|
|
|
NEWD( "atm", 9.8692329999819300E-06, CDC_Pressure ); // Atmoshpere
|
|
|
|
NEWD( "mmHg", 7.5006170799862700E-03, CDC_Pressure ); // mm Hg (Mercury)
|
|
|
|
NEWD( "Torr", 7.5006380000000000E-03, CDC_Pressure ); // *** Torr
|
|
|
|
NEWD( "psi", 1.4503770000000000E-04, CDC_Pressure ); // *** Psi
|
|
|
|
|
|
|
|
// FORCE: 1 Newton is...
|
|
|
|
NEWD( "N", 1.0000000000000000E00, CDC_Force ); // Newton
|
|
|
|
NEWD( "dyn", 1.0000000000000000E05, CDC_Force ); // Dyn
|
2006-01-31 17:28:05 +00:00
|
|
|
NEWD( "lbf", 2.24808923655339E-01, CDC_Force ); // Pound-Force
|
|
|
|
NEWD( "pond", 1.019716E02, CDC_Force ); // *** Pond
|
2002-07-09 12:03:17 +00:00
|
|
|
|
|
|
|
// ENERGY: 1 Joule is...
|
|
|
|
NEWD( "J", 1.0000000000000000E00, CDC_Energy ); // Joule
|
|
|
|
NEWD( "e", 1.0000000000000000E07, CDC_Energy ); // Erg -> http://www.chemie.fu-berlin.de/chemistry/general/si.html
|
|
|
|
// NEWD( "e", 9.99999519343231E06, CDC_Energy ); // Erg
|
|
|
|
NEWD( "c", 2.3900624947346700E-01, CDC_Energy ); // Thermodynamical Calorie
|
|
|
|
NEWD( "cal", 2.3884619064201700E-01, CDC_Energy ); // Calorie
|
|
|
|
NEWD( "eV", 6.2414570000000000E18, CDC_Energy ); // Electronvolt
|
|
|
|
NEWD( "HPh", 3.7250611111111111E-07, CDC_Energy ); // Horsepower Hours
|
|
|
|
// NEWD( "HPh", 3.72506430801000E-07, CDC_Energy ); // Horsepower Hours
|
|
|
|
NEWD( "Wh", 2.7777777777777778E-04, CDC_Energy ); // Watt Hours
|
2006-01-31 17:28:05 +00:00
|
|
|
NEWD( "flb", 2.37304222192651E01, CDC_Energy ); // Foot Pound
|
|
|
|
NEWD( "BTU", 9.4781506734901500E-04, CDC_Energy ); // British Thermal Unit
|
2002-07-09 12:03:17 +00:00
|
|
|
|
|
|
|
// POWER: 1 Watt is...
|
|
|
|
NEWD( "W", 1.0000000000000000E00, CDC_Power ); // Watt
|
|
|
|
NEWD( "HP", 1.341022E-03, CDC_Power ); // Horsepower
|
|
|
|
NEWD( "PS", 1.359622E-03, CDC_Power ); // *** German Pferdestaerke
|
|
|
|
// NEWD( "HP", 1.4102006031908E-03, CDC_Power ); // Excel seams to be a little bit wrong... either this doesn't fit to J -> HPh
|
|
|
|
|
|
|
|
// MAGNETISM: 1 Tesla is...
|
|
|
|
NEWD( "T", 1.0000000000000000E00, CDC_Magnetism ); // Tesla
|
|
|
|
NEWD( "ga", 1.0000000000000000E04, CDC_Magnetism ); // Gauss
|
|
|
|
|
|
|
|
// TEMERATURE: 1 Kelvin is...
|
|
|
|
NEWL( "C", 1.0000000000000000E00, -2.7315000000000000E02, CDC_Temperature ); // Celsius
|
|
|
|
NEWL( "F", 1.8000000000000000E00, -2.5537222222222222E02, CDC_Temperature ); // Fahrenheit
|
|
|
|
NEWL( "K", 1.0000000000000000E00, +0.0000000000000000E00, CDC_Temperature ); // Kelvin
|
|
|
|
NEWL( "Reau", 8.0000000000000000E-01, -2.7315000000000000E02, CDC_Temperature ); // *** Reaumur
|
|
|
|
NEWL( "Rank", 1.8000000000000000E00, +0.0000000000000000E00, CDC_Temperature ); // *** Rankine
|
|
|
|
|
|
|
|
// VOLUMNE: 1 Liter is...
|
|
|
|
NEWD( "tsp", 2.0284000000000000E02, CDC_Volume ); // Teaspoon
|
|
|
|
NEWD( "tbs", 6.7613333333333333E01, CDC_Volume ); // Tablespoon
|
|
|
|
NEWD( "oz", 3.3806666666666667E01, CDC_Volume ); // Ounce Liquid
|
|
|
|
NEWD( "cup", 4.2258333333333333E00, CDC_Volume ); // Cup
|
2006-01-31 17:28:05 +00:00
|
|
|
NEWD( "pt", 2.1129166666666667E00, CDC_Volume ); // US Pint
|
|
|
|
NEWD( "uk_pt", 1.75975569552166E00, CDC_Volume ); // UK Pint
|
2002-07-09 12:03:17 +00:00
|
|
|
NEWD( "qt", 1.0564583333333333E00, CDC_Volume ); // Quart
|
|
|
|
NEWD( "gal", 2.6411458333333333E-01, CDC_Volume ); // Gallone
|
|
|
|
NEWD( "l", 1.0000000000000000E00, CDC_Volume ); // Liter
|
|
|
|
NEWD( "m3", 1.0000000000000000E-03, CDC_Volume ); // *** Cubic Meter
|
|
|
|
NEWD( "mi3", 2.3991275857892772E-13, CDC_Volume ); // *** Cubic Britsh Mile
|
|
|
|
NEWD( "Nmi3", 1.5742621468581148E-13, CDC_Volume ); // *** Cubic Nautical Mile
|
|
|
|
NEWD( "in3", 6.1023744094732284E01, CDC_Volume ); // *** Cubic Inch
|
|
|
|
NEWD( "ft3", 3.5314666721488590E-02, CDC_Volume ); // *** Cubic Foot
|
2004-07-30 15:14:13 +00:00
|
|
|
NEWD( "yd3", 1.3079506193143922E-03, CDC_Volume ); // *** Cubic Yard
|
2002-07-09 12:03:17 +00:00
|
|
|
NEWD( "ang3", 1.0000000000000000E27, CDC_Volume ); // *** Cubic Angstroem
|
|
|
|
NEWD( "Pica3", 2.2776990435870636E07, CDC_Volume ); // *** Cubic Pica
|
|
|
|
NEWD( "barrel", 6.289811E-03, CDC_Volume ); // *** Barrel (=42gal?)
|
|
|
|
NEWD( "bushel", 2.837759E-02, CDC_Volume ); // *** Bushel
|
|
|
|
NEWD( "regton", 3.531467E-04, CDC_Volume ); // *** Register ton
|
|
|
|
NEWD( "Schooner", 2.3529411764705882E00, CDC_Volume ); // *** austr. Schooner
|
|
|
|
NEWD( "Middy", 3.5087719298245614E00, CDC_Volume ); // *** austr. Middy
|
|
|
|
NEWD( "Glass", 5.0000000000000000E00, CDC_Volume ); // *** austr. Glass
|
|
|
|
NEWD( "Sixpack", 0.5, CDC_Volume ); // ***
|
|
|
|
NEWD( "Humpen", 2.0, CDC_Volume ); // ***
|
|
|
|
|
|
|
|
// 1 Square Meter is...
|
|
|
|
NEWD( "m2", 1.0000000000000000E00, CDC_Area ); // *** Square Meter
|
|
|
|
NEWD( "mi2", 3.8610215854244585E-07, CDC_Area ); // *** Square Britsh Mile
|
|
|
|
NEWD( "Nmi2", 2.9155334959812286E-07, CDC_Area ); // *** Square Nautical Mile
|
|
|
|
NEWD( "in2", 1.5500031000062000E03, CDC_Area ); // *** Square Inch
|
|
|
|
NEWD( "ft2", 1.0763910416709722E01, CDC_Area ); // *** Square Foot
|
2006-01-31 17:28:05 +00:00
|
|
|
NEWD( "yd2", 1.1959900463010803E00, CDC_Area ); // *** Square Yard
|
2002-07-09 12:03:17 +00:00
|
|
|
NEWD( "ang2", 1.0000000000000000E20, CDC_Area ); // *** Square Angstroem
|
|
|
|
NEWD( "Pica2", 8.0352160704321409E06, CDC_Area ); // *** Square Pica
|
2006-01-31 17:28:05 +00:00
|
|
|
NEWD( "Morgen", 4.0000000000000000E-04, CDC_Area ); // *** Morgen
|
|
|
|
NEWD( "ar", 1.000000E-02, CDC_Area ); // *** Ar
|
|
|
|
NEWD( "acre", 2.471053815E-04, CDC_Area ); // *** Acre
|
|
|
|
NEWD( "ha", 1.000000E-04, CDC_Area ); // *** Hectare
|
2002-07-09 12:03:17 +00:00
|
|
|
NEWD( "Quadratlatschen",5.6689342403628117914,CDC_Area ); // ***
|
|
|
|
|
|
|
|
// SPEED: 1 Meter per Second is...
|
|
|
|
NEWD( "m/s", 1.0000000000000000E00, CDC_Speed ); // *** Meters per Second
|
|
|
|
NEWD( "m/h", 3.6000000000000000E03, CDC_Speed ); // *** Meters per Hour
|
|
|
|
NEWD( "mph", 2.2369362920544023E00, CDC_Speed ); // *** Britsh Miles per Hour
|
|
|
|
NEWD( "kn", 1.9438444924406048E00, CDC_Speed ); // *** Knot = Nautical Miles per Hour
|
|
|
|
NEWD( "admkn", 1.9438446603753486E00, CDC_Speed ); // *** Admiralty Knot
|
|
|
|
NEWD( "wahnsinnige Geschwindigkeit", 2.0494886343432328E-14, CDC_Speed ); // ***
|
|
|
|
NEWD( "ludicrous speed", 2.0494886343432328E-14, CDC_Speed ); // ***
|
|
|
|
NEWD( "laecherliche Geschwindigkeit", 4.0156958471424288E-06, CDC_Speed); // ***
|
|
|
|
NEWD( "ridiculous speed", 4.0156958471424288E-06, CDC_Speed); // ***
|
2001-04-06 12:59:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ConvertDataList::~ConvertDataList()
|
|
|
|
{
|
|
|
|
for( ConvertData* p = First() ; p ; p = Next() )
|
|
|
|
delete p;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double ConvertDataList::Convert( double fVal, const STRING& rFrom, const STRING& rTo ) THROWDEF_RTE_IAE
|
|
|
|
{
|
2006-01-31 17:28:05 +00:00
|
|
|
// This will not catch illegal units
|
|
|
|
// if( rFrom == rTo )
|
|
|
|
// return fVal;
|
2001-04-06 12:59:16 +00:00
|
|
|
|
|
|
|
ConvertData* pFrom = NULL;
|
|
|
|
ConvertData* pTo = NULL;
|
|
|
|
sal_Bool bSearchFrom = sal_True;
|
|
|
|
sal_Bool bSearchTo = sal_True;
|
|
|
|
sal_Int16 nLevelFrom = 0;
|
|
|
|
sal_Int16 nLevelTo = 0;
|
|
|
|
|
|
|
|
ConvertData* p = First();
|
|
|
|
while( p && ( bSearchFrom || bSearchTo ) )
|
|
|
|
{
|
|
|
|
if( bSearchFrom )
|
|
|
|
{
|
|
|
|
sal_Int16 n = p->GetMatchingLevel( rFrom );
|
|
|
|
if( n != INV_MATCHLEV )
|
|
|
|
{
|
|
|
|
if( n )
|
|
|
|
{ // only first match for partial equality rulz a little bit more
|
|
|
|
pFrom = p;
|
|
|
|
nLevelFrom = n;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // ... but exact match rulz most
|
|
|
|
pFrom = p;
|
|
|
|
bSearchFrom = sal_False;
|
|
|
|
nLevelFrom = n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bSearchTo )
|
|
|
|
{
|
|
|
|
sal_Int16 n = p->GetMatchingLevel( rTo );
|
|
|
|
if( n != INV_MATCHLEV )
|
|
|
|
{
|
|
|
|
if( n )
|
|
|
|
{ // only first match for partial equality rulz a little bit more
|
|
|
|
pTo = p;
|
|
|
|
nLevelTo = n;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // ... but exact match rulz most
|
|
|
|
pTo = p;
|
|
|
|
bSearchTo = sal_False;
|
|
|
|
nLevelTo = n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p = Next();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pFrom && pTo )
|
|
|
|
return pFrom->Convert( fVal, *pTo, nLevelFrom, nLevelTo );
|
|
|
|
else
|
|
|
|
THROW_IAE;
|
|
|
|
}
|
|
|
|
|
2001-10-09 10:09:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ScaDate::ScaDate() :
|
|
|
|
nOrigDay( 1 ),
|
|
|
|
nDay( 1 ),
|
|
|
|
nMonth( 1 ),
|
|
|
|
nYear( 1900 ),
|
2001-10-12 08:27:13 +00:00
|
|
|
bLastDayMode( sal_True ),
|
2001-10-09 10:09:01 +00:00
|
|
|
bLastDay( sal_False ),
|
|
|
|
b30Days( sal_False ),
|
|
|
|
bUSMode( sal_False )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ScaDate::ScaDate( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nBase )
|
|
|
|
{
|
|
|
|
DaysToDate( nNullDate + nDate, nOrigDay, nMonth, nYear );
|
2001-10-12 08:27:13 +00:00
|
|
|
bLastDayMode = (nBase != 5);
|
2001-10-25 10:08:29 +00:00
|
|
|
bLastDay = (nOrigDay >= ::DaysInMonth( nMonth, nYear ));
|
2001-10-09 10:09:01 +00:00
|
|
|
b30Days = (nBase == 0) || (nBase == 4);
|
|
|
|
bUSMode = (nBase == 0);
|
|
|
|
setDay();
|
|
|
|
}
|
|
|
|
|
|
|
|
ScaDate::ScaDate( const ScaDate& rCopy ) :
|
|
|
|
nOrigDay( rCopy.nOrigDay ),
|
|
|
|
nDay( rCopy.nDay ),
|
|
|
|
nMonth( rCopy.nMonth ),
|
|
|
|
nYear( rCopy.nYear ),
|
2001-10-12 08:27:13 +00:00
|
|
|
bLastDayMode( rCopy.bLastDayMode ),
|
2001-10-09 10:09:01 +00:00
|
|
|
bLastDay( rCopy.bLastDay ),
|
|
|
|
b30Days( rCopy.b30Days ),
|
|
|
|
bUSMode( rCopy.bUSMode )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ScaDate& ScaDate::operator=( const ScaDate& rCopy )
|
|
|
|
{
|
2001-10-25 10:08:29 +00:00
|
|
|
if( this != &rCopy )
|
|
|
|
{
|
|
|
|
nOrigDay = rCopy.nOrigDay;
|
|
|
|
nDay = rCopy.nDay;
|
|
|
|
nMonth = rCopy.nMonth;
|
|
|
|
nYear = rCopy.nYear;
|
|
|
|
bLastDayMode = rCopy.bLastDayMode;
|
|
|
|
bLastDay = rCopy.bLastDay;
|
|
|
|
b30Days = rCopy.b30Days;
|
|
|
|
bUSMode = rCopy.bUSMode;
|
|
|
|
}
|
2001-10-09 10:09:01 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScaDate::setDay()
|
|
|
|
{
|
|
|
|
if( b30Days )
|
|
|
|
{
|
2001-10-25 10:08:29 +00:00
|
|
|
// 30-days-mode: set nDay to 30 if original was last day in month
|
2001-10-09 10:09:01 +00:00
|
|
|
nDay = Min( nOrigDay, static_cast< sal_uInt16 >( 30 ) );
|
2001-10-25 10:08:29 +00:00
|
|
|
if( bLastDay || (nDay >= ::DaysInMonth( nMonth, nYear )) )
|
2001-10-09 10:09:01 +00:00
|
|
|
nDay = 30;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-10-25 10:08:29 +00:00
|
|
|
// set nDay to last day in this month if original was last day
|
|
|
|
sal_uInt16 nLastDay = ::DaysInMonth( nMonth, nYear );
|
2001-10-09 10:09:01 +00:00
|
|
|
nDay = bLastDay ? nLastDay : Min( nOrigDay, nLastDay );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 ScaDate::getDaysInMonthRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const
|
|
|
|
{
|
|
|
|
if( nFrom > nTo )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
sal_Int32 nRet = 0;
|
|
|
|
if( b30Days )
|
|
|
|
nRet = (nTo - nFrom + 1) * 30;
|
|
|
|
else
|
|
|
|
{
|
2001-10-25 10:08:29 +00:00
|
|
|
for( sal_uInt16 nMonthIx = nFrom; nMonthIx <= nTo; ++nMonthIx )
|
2001-10-09 10:09:01 +00:00
|
|
|
nRet += getDaysInMonth( nMonthIx );
|
|
|
|
}
|
|
|
|
return nRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 ScaDate::getDaysInYearRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const
|
|
|
|
{
|
|
|
|
if( nFrom > nTo )
|
|
|
|
return 0;
|
|
|
|
|
2001-10-25 10:08:29 +00:00
|
|
|
return b30Days ? ((nTo - nFrom + 1) * 360) : ::GetDaysInYears( nFrom, nTo );
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
|
2001-10-12 08:27:13 +00:00
|
|
|
void ScaDate::doAddYears( sal_Int32 nYearCount ) throw( lang::IllegalArgumentException )
|
2001-10-09 10:09:01 +00:00
|
|
|
{
|
2001-10-12 08:27:13 +00:00
|
|
|
sal_Int32 nNewYear = nYearCount + nYear;
|
|
|
|
if( (nNewYear < 0) || (nNewYear > 0x7FFF) )
|
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
nYear = static_cast< sal_uInt16 >( nNewYear );
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
|
2001-10-12 08:27:13 +00:00
|
|
|
void ScaDate::addMonths( sal_Int32 nMonthCount ) throw( lang::IllegalArgumentException )
|
2001-10-09 10:09:01 +00:00
|
|
|
{
|
2001-10-12 08:27:13 +00:00
|
|
|
sal_Int32 nNewMonth = nMonthCount + nMonth;
|
|
|
|
if( nNewMonth > 12 )
|
|
|
|
{
|
2001-10-25 10:08:29 +00:00
|
|
|
--nNewMonth;
|
|
|
|
doAddYears( nNewMonth / 12 );
|
|
|
|
nMonth = static_cast< sal_uInt16 >( nNewMonth % 12 ) + 1;
|
2001-10-12 08:27:13 +00:00
|
|
|
}
|
|
|
|
else if( nNewMonth < 1 )
|
2001-10-09 10:09:01 +00:00
|
|
|
{
|
2001-10-12 08:27:13 +00:00
|
|
|
doAddYears( nNewMonth / 12 - 1 );
|
|
|
|
nMonth = static_cast< sal_uInt16 >( nNewMonth % 12 + 12 );
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
else
|
2001-10-12 08:27:13 +00:00
|
|
|
nMonth = static_cast< sal_uInt16 >( nNewMonth );
|
2001-10-09 10:09:01 +00:00
|
|
|
setDay();
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 ScaDate::getDate( sal_Int32 nNullDate ) const
|
|
|
|
{
|
2001-10-25 10:08:29 +00:00
|
|
|
sal_uInt16 nLastDay = ::DaysInMonth( nMonth, nYear );
|
2001-10-12 08:27:13 +00:00
|
|
|
sal_uInt16 nRealDay = (bLastDayMode && bLastDay) ? nLastDay : Min( nLastDay, nOrigDay );
|
2001-10-25 10:08:29 +00:00
|
|
|
return ::DateToDays( nRealDay, nMonth, nYear ) - nNullDate;
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
|
2001-10-12 08:27:13 +00:00
|
|
|
sal_Int32 ScaDate::getDiff( const ScaDate& rFrom, const ScaDate& rTo ) throw( lang::IllegalArgumentException )
|
2001-10-09 10:09:01 +00:00
|
|
|
{
|
|
|
|
if( rFrom > rTo )
|
|
|
|
return getDiff( rTo, rFrom );
|
|
|
|
|
|
|
|
sal_Int32 nDiff = 0;
|
|
|
|
ScaDate aFrom( rFrom );
|
|
|
|
ScaDate aTo( rTo );
|
|
|
|
|
|
|
|
if( rTo.b30Days )
|
|
|
|
{
|
|
|
|
// corrections for base 0 (US NASD)
|
|
|
|
if( rTo.bUSMode )
|
|
|
|
{
|
|
|
|
if( ((rFrom.nMonth == 2) || (rFrom.nDay < 30)) && (aTo.nOrigDay == 31) )
|
|
|
|
aTo.nDay = 31;
|
|
|
|
else if( (aTo.nMonth == 2) && aTo.bLastDay )
|
2001-10-25 10:08:29 +00:00
|
|
|
aTo.nDay = ::DaysInMonth( 2, aTo.nYear );
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
// corrections for base 4 (Europe)
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( (aFrom.nMonth == 2) && (aFrom.nDay == 30) )
|
2001-10-25 10:08:29 +00:00
|
|
|
aFrom.nDay = ::DaysInMonth( 2, aFrom.nYear );
|
2001-10-09 10:09:01 +00:00
|
|
|
if( (aTo.nMonth == 2) && (aTo.nDay == 30) )
|
2001-10-25 10:08:29 +00:00
|
|
|
aTo.nDay = ::DaysInMonth( 2, aTo.nYear );
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( (aFrom.nYear < aTo.nYear) || ((aFrom.nYear == aTo.nYear) && (aFrom.nMonth < aTo.nMonth)) )
|
|
|
|
{
|
|
|
|
// move aFrom to 1st day of next month
|
|
|
|
nDiff = aFrom.getDaysInMonth() - aFrom.nDay + 1;
|
|
|
|
aFrom.nOrigDay = aFrom.nDay = 1;
|
|
|
|
aFrom.bLastDay = sal_False;
|
|
|
|
aFrom.addMonths( 1 );
|
|
|
|
|
|
|
|
if( aFrom.nYear < aTo.nYear )
|
|
|
|
{
|
|
|
|
// move aFrom to 1st day of next year
|
|
|
|
nDiff += aFrom.getDaysInMonthRange( aFrom.nMonth, 12 );
|
|
|
|
aFrom.addMonths( 13 - aFrom.nMonth );
|
|
|
|
|
|
|
|
// move aFrom to 1st day of this year
|
|
|
|
nDiff += aFrom.getDaysInYearRange( aFrom.nYear, aTo.nYear - 1 );
|
|
|
|
aFrom.addYears( aTo.nYear - aFrom.nYear );
|
|
|
|
}
|
|
|
|
|
|
|
|
// move aFrom to 1st day of this month
|
|
|
|
nDiff += aFrom.getDaysInMonthRange( aFrom.nMonth, aTo.nMonth - 1 );
|
|
|
|
aFrom.addMonths( aTo.nMonth - aFrom.nMonth );
|
|
|
|
}
|
|
|
|
// finally add remaining days in this month
|
|
|
|
nDiff += aTo.nDay - aFrom.nDay;
|
2004-02-04 13:11:40 +00:00
|
|
|
return nDiff > 0 ? nDiff : 0;
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool ScaDate::operator<( const ScaDate& rCmp ) const
|
|
|
|
{
|
|
|
|
if( nYear != rCmp.nYear )
|
|
|
|
return nYear < rCmp.nYear;
|
|
|
|
if( nMonth != rCmp.nMonth )
|
|
|
|
return nMonth < rCmp.nMonth;
|
|
|
|
if( nDay != rCmp.nDay )
|
|
|
|
return nDay < rCmp.nDay;
|
|
|
|
if( bLastDay || rCmp.bLastDay )
|
|
|
|
return !bLastDay && rCmp.bLastDay;
|
|
|
|
return nOrigDay < rCmp.nOrigDay;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ScaAnyConverter::ScaAnyConverter( const uno::Reference< lang::XMultiServiceFactory >& xServiceFact ) :
|
2001-10-25 10:08:29 +00:00
|
|
|
bHasValidFormat( sal_False )
|
2001-10-09 10:09:01 +00:00
|
|
|
{
|
2001-10-25 10:08:29 +00:00
|
|
|
if( xServiceFact.is() )
|
|
|
|
{
|
|
|
|
uno::Reference< uno::XInterface > xInstance = xServiceFact->createInstance(
|
|
|
|
OUString::createFromAscii( "com.sun.star.util.NumberFormatter" ) );
|
|
|
|
xFormatter = uno::Reference< util::XNumberFormatter >( xInstance, uno::UNO_QUERY );
|
|
|
|
}
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ScaAnyConverter::~ScaAnyConverter()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScaAnyConverter::init( const uno::Reference< beans::XPropertySet >& xPropSet ) throw( uno::RuntimeException )
|
|
|
|
{
|
2001-10-25 10:08:29 +00:00
|
|
|
// try to get default number format
|
|
|
|
bHasValidFormat = sal_False;
|
|
|
|
if( xFormatter.is() )
|
|
|
|
{
|
|
|
|
// get XFormatsSupplier from outer XPropertySet
|
|
|
|
uno::Reference< util::XNumberFormatsSupplier > xFormatsSupp( xPropSet, uno::UNO_QUERY );
|
|
|
|
if( xFormatsSupp.is() )
|
|
|
|
{
|
|
|
|
// get XNumberFormatTypes from XNumberFormatsSupplier to get standard index
|
|
|
|
uno::Reference< util::XNumberFormats > xFormats( xFormatsSupp->getNumberFormats() );
|
|
|
|
uno::Reference< util::XNumberFormatTypes > xFormatTypes( xFormats, uno::UNO_QUERY );
|
|
|
|
if( xFormatTypes.is() )
|
|
|
|
{
|
|
|
|
lang::Locale eLocale;
|
|
|
|
nDefaultFormat = xFormatTypes->getStandardIndex( eLocale );
|
|
|
|
xFormatter->attachNumberFormatsSupplier( xFormatsSupp );
|
|
|
|
bHasValidFormat = sal_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-10-09 10:09:01 +00:00
|
|
|
|
2001-10-25 10:08:29 +00:00
|
|
|
double ScaAnyConverter::convertToDouble( const OUString& rString ) const throw( lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
double fValue = 0.0;
|
|
|
|
if( bHasValidFormat )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
fValue = xFormatter->convertStringToNumber( nDefaultFormat, rString );
|
|
|
|
}
|
|
|
|
catch( uno::Exception& )
|
|
|
|
{
|
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-03-26 16:46:50 +00:00
|
|
|
rtl_math_ConversionStatus eStatus;
|
|
|
|
sal_Int32 nEnd;
|
|
|
|
fValue = ::rtl::math::stringToDouble( rString, '.', ',', &eStatus, &nEnd );
|
|
|
|
if( (eStatus != rtl_math_ConversionStatus_Ok) || (nEnd < rString.getLength()) )
|
2001-10-25 10:08:29 +00:00
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
}
|
|
|
|
return fValue;
|
2001-10-09 10:09:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool ScaAnyConverter::getDouble(
|
|
|
|
double& rfResult,
|
|
|
|
const uno::Any& rAny ) const throw( lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
rfResult = 0.0;
|
|
|
|
sal_Bool bContainsVal = sal_True;
|
|
|
|
switch( rAny.getValueTypeClass() )
|
|
|
|
{
|
|
|
|
case uno::TypeClass_VOID:
|
|
|
|
bContainsVal = sal_False;
|
|
|
|
break;
|
|
|
|
case uno::TypeClass_DOUBLE:
|
|
|
|
rAny >>= rfResult;
|
|
|
|
break;
|
|
|
|
case uno::TypeClass_STRING:
|
|
|
|
{
|
|
|
|
const OUString* pString = static_cast< const OUString* >( rAny.getValue() );
|
|
|
|
if( pString->getLength() )
|
2001-10-25 10:08:29 +00:00
|
|
|
rfResult = convertToDouble( *pString );
|
2001-10-09 10:09:01 +00:00
|
|
|
else
|
|
|
|
bContainsVal = sal_False;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
}
|
|
|
|
return bContainsVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool ScaAnyConverter::getDouble(
|
|
|
|
double& rfResult,
|
|
|
|
const uno::Reference< beans::XPropertySet >& xPropSet,
|
|
|
|
const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
init( xPropSet );
|
|
|
|
return getDouble( rfResult, rAny );
|
|
|
|
}
|
|
|
|
|
|
|
|
double ScaAnyConverter::getDouble(
|
|
|
|
const uno::Reference< beans::XPropertySet >& xPropSet,
|
|
|
|
const uno::Any& rAny,
|
|
|
|
double fDefault ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
double fResult;
|
|
|
|
if( !getDouble( fResult, xPropSet, rAny ) )
|
|
|
|
fResult = fDefault;
|
|
|
|
return fResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool ScaAnyConverter::getInt32(
|
|
|
|
sal_Int32& rnResult,
|
|
|
|
const uno::Reference< beans::XPropertySet >& xPropSet,
|
|
|
|
const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
double fResult;
|
|
|
|
sal_Bool bContainsVal = getDouble( fResult, xPropSet, rAny );
|
|
|
|
if( (fResult <= -2147483649.0) || (fResult >= 2147483648.0) )
|
|
|
|
throw lang::IllegalArgumentException();
|
|
|
|
|
|
|
|
rnResult = static_cast< sal_Int32 >( fResult );
|
|
|
|
return bContainsVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 ScaAnyConverter::getInt32(
|
|
|
|
const uno::Reference< beans::XPropertySet >& xPropSet,
|
|
|
|
const uno::Any& rAny,
|
|
|
|
sal_Int32 nDefault ) throw( uno::RuntimeException, lang::IllegalArgumentException )
|
|
|
|
{
|
|
|
|
sal_Int32 nResult;
|
|
|
|
if( !getInt32( nResult, xPropSet, rAny ) )
|
|
|
|
nResult = nDefault;
|
|
|
|
return nResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|