00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef INCLUDED_RTL_MATH_HXX
00021 #define INCLUDED_RTL_MATH_HXX
00022
00023 #include "rtl/math.h"
00024 #include "rtl/string.hxx"
00025 #include "rtl/ustring.hxx"
00026 #include "rtl/ustrbuf.hxx"
00027 #include "sal/mathconf.h"
00028 #include "sal/types.h"
00029
00030 #include <math.h>
00031
00032 namespace rtl {
00033
00034 namespace math {
00035
00038 inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
00039 sal_Int32 nDecPlaces,
00040 sal_Char cDecSeparator,
00041 sal_Int32 const * pGroups,
00042 sal_Char cGroupSeparator,
00043 bool bEraseTrailingDecZeros = false)
00044 {
00045 rtl::OString aResult;
00046 rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
00047 cDecSeparator, pGroups, cGroupSeparator,
00048 bEraseTrailingDecZeros);
00049 return aResult;
00050 }
00051
00054 inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
00055 sal_Int32 nDecPlaces,
00056 sal_Char cDecSeparator,
00057 bool bEraseTrailingDecZeros = false)
00058 {
00059 rtl::OString aResult;
00060 rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
00061 cDecSeparator, 0, 0, bEraseTrailingDecZeros);
00062 return aResult;
00063 }
00064
00067 inline rtl::OUString doubleToUString(double fValue,
00068 rtl_math_StringFormat eFormat,
00069 sal_Int32 nDecPlaces,
00070 sal_Unicode cDecSeparator,
00071 sal_Int32 const * pGroups,
00072 sal_Unicode cGroupSeparator,
00073 bool bEraseTrailingDecZeros = false)
00074 {
00075 rtl::OUString aResult;
00076 rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
00077 cDecSeparator, pGroups, cGroupSeparator,
00078 bEraseTrailingDecZeros);
00079 return aResult;
00080 }
00081
00084 inline rtl::OUString doubleToUString(double fValue,
00085 rtl_math_StringFormat eFormat,
00086 sal_Int32 nDecPlaces,
00087 sal_Unicode cDecSeparator,
00088 bool bEraseTrailingDecZeros = false)
00089 {
00090 rtl::OUString aResult;
00091 rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
00092 cDecSeparator, 0, 0, bEraseTrailingDecZeros);
00093 return aResult;
00094 }
00095
00099 inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
00100 rtl_math_StringFormat eFormat,
00101 sal_Int32 nDecPlaces,
00102 sal_Unicode cDecSeparator,
00103 sal_Int32 const * pGroups,
00104 sal_Unicode cGroupSeparator,
00105 bool bEraseTrailingDecZeros = false)
00106 {
00107 rtl_uString ** pData;
00108 sal_Int32 * pCapacity;
00109 rBuffer.accessInternals( &pData, &pCapacity );
00110 rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
00111 eFormat, nDecPlaces, cDecSeparator, pGroups,
00112 cGroupSeparator, bEraseTrailingDecZeros);
00113 }
00114
00118 inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
00119 rtl_math_StringFormat eFormat,
00120 sal_Int32 nDecPlaces,
00121 sal_Unicode cDecSeparator,
00122 bool bEraseTrailingDecZeros = false)
00123 {
00124 rtl_uString ** pData;
00125 sal_Int32 * pCapacity;
00126 rBuffer.accessInternals( &pData, &pCapacity );
00127 rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
00128 eFormat, nDecPlaces, cDecSeparator, 0, 0,
00129 bEraseTrailingDecZeros);
00130 }
00131
00134 inline double stringToDouble(rtl::OString const & rString,
00135 sal_Char cDecSeparator, sal_Char cGroupSeparator,
00136 rtl_math_ConversionStatus * pStatus = 0,
00137 sal_Int32 * pParsedEnd = 0)
00138 {
00139 sal_Char const * pBegin = rString.getStr();
00140 sal_Char const * pEnd;
00141 double fResult = rtl_math_stringToDouble(pBegin,
00142 pBegin + rString.getLength(),
00143 cDecSeparator, cGroupSeparator,
00144 pStatus, &pEnd);
00145 if (pParsedEnd != 0)
00146 *pParsedEnd = (sal_Int32)(pEnd - pBegin);
00147 return fResult;
00148 }
00149
00152 inline double stringToDouble(rtl::OUString const & rString,
00153 sal_Unicode cDecSeparator,
00154 sal_Unicode cGroupSeparator,
00155 rtl_math_ConversionStatus * pStatus = 0,
00156 sal_Int32 * pParsedEnd = 0)
00157 {
00158 sal_Unicode const * pBegin = rString.getStr();
00159 sal_Unicode const * pEnd;
00160 double fResult = rtl_math_uStringToDouble(pBegin,
00161 pBegin + rString.getLength(),
00162 cDecSeparator, cGroupSeparator,
00163 pStatus, &pEnd);
00164 if (pParsedEnd != 0)
00165 *pParsedEnd = (sal_Int32)(pEnd - pBegin);
00166 return fResult;
00167 }
00168
00171 inline double round(
00172 double fValue, int nDecPlaces = 0,
00173 rtl_math_RoundingMode eMode = rtl_math_RoundingMode_Corrected)
00174 {
00175 return rtl_math_round(fValue, nDecPlaces, eMode);
00176 }
00177
00180 inline double pow10Exp(double fValue, int nExp)
00181 {
00182 return rtl_math_pow10Exp(fValue, nExp);
00183 }
00184
00187 inline double approxValue(double fValue)
00188 {
00189 return rtl_math_approxValue(fValue);
00190 }
00191
00194 inline double expm1(double fValue)
00195 {
00196 return rtl_math_expm1(fValue);
00197 }
00198
00201 inline double log1p(double fValue)
00202 {
00203 return rtl_math_log1p(fValue);
00204 }
00205
00208 inline double atanh(double fValue)
00209 {
00210 return rtl_math_atanh(fValue);
00211 }
00212
00215 inline double erf(double fValue)
00216 {
00217 return rtl_math_erf(fValue);
00218 }
00219
00222 inline double erfc(double fValue)
00223 {
00224 return rtl_math_erfc(fValue);
00225 }
00226
00229 inline double asinh(double fValue)
00230 {
00231 return rtl_math_asinh(fValue);
00232 }
00233
00236 inline double acosh(double fValue)
00237 {
00238 return rtl_math_acosh(fValue);
00239 }
00240
00241
00248 inline bool approxEqual(double a, double b)
00249 {
00250 if ( a == b )
00251 return true;
00252 double x = a - b;
00253 return (x < 0.0 ? -x : x)
00254 < ((a < 0.0 ? -a : a) * (1.0 / (16777216.0 * 16777216.0)));
00255 }
00256
00262 inline bool approxEqual(double a, double b, sal_Int16 nPrec)
00263 {
00264 if ( a == b )
00265 return true;
00266 double x = a - b;
00267 return (x < 0.0 ? -x : x)
00268 < ((a < 0.0 ? -a : a) * (1.0 / (pow(static_cast<double>(2.0), nPrec))));
00269 }
00280 inline double approxAdd(double a, double b)
00281 {
00282 if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))
00283 && approxEqual( a, -b ) )
00284 return 0.0;
00285 return a + b;
00286 }
00287
00293 inline double approxSub(double a, double b)
00294 {
00295 if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) )
00296 return 0.0;
00297 return a - b;
00298 }
00299
00304 inline double approxFloor(double a)
00305 {
00306 return floor( approxValue( a ));
00307 }
00308
00313 inline double approxCeil(double a)
00314 {
00315 return ceil( approxValue( a ));
00316 }
00317
00320 inline bool isFinite(double d)
00321 {
00322 return SAL_MATH_FINITE(d) != 0;
00323 }
00324
00331 inline bool isInf(double d)
00332 {
00333
00334 return (SAL_MATH_FINITE(d) == 0) &&
00335 (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0)
00336 && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
00337 == 0);
00338 }
00339
00342 inline bool isNan(double d)
00343 {
00344
00345 return (SAL_MATH_FINITE(d) == 0) && (
00346 (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0)
00347 || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
00348 != 0) );
00349 }
00350
00353 inline bool isSignBitSet(double d)
00354 {
00355 return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0;
00356 }
00357
00360 inline void setInf(double * pd, bool bNegative)
00361 {
00362 union
00363 {
00364 double sd;
00365 sal_math_Double md;
00366 };
00367 md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000;
00368 md.w32_parts.lsw = 0;
00369 *pd = sd;
00370 }
00371
00374 inline void setNan(double * pd)
00375 {
00376 union
00377 {
00378 double sd;
00379 sal_math_Double md;
00380 };
00381 md.w32_parts.msw = 0x7FFFFFFF;
00382 md.w32_parts.lsw = 0xFFFFFFFF;
00383 *pd = sd;
00384 }
00385
00395 inline bool isValidArcArg(double d)
00396 {
00397 return fabs(d)
00398 <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
00399 * static_cast< double >(static_cast< unsigned long >(0x80000000))
00400 * 2);
00401 }
00402
00405 inline double sin(double d)
00406 {
00407 if ( isValidArcArg( d ) )
00408 return ::sin( d );
00409 setNan( &d );
00410 return d;
00411 }
00412
00415 inline double cos(double d)
00416 {
00417 if ( isValidArcArg( d ) )
00418 return ::cos( d );
00419 setNan( &d );
00420 return d;
00421 }
00422
00425 inline double tan(double d)
00426 {
00427 if ( isValidArcArg( d ) )
00428 return ::tan( d );
00429 setNan( &d );
00430 return d;
00431 }
00432
00433 }
00434
00435 }
00436
00437 #endif // INCLUDED_RTL_MATH_HXX
00438
00439