UDK 3.2.7 C/C++ API Reference
rtl/math.hxx
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /*************************************************************************
00003  *
00004  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
00005  *
00006  * Copyright 2000, 2010 Oracle and/or its affiliates.
00007  *
00008  * OpenOffice.org - a multi-platform office productivity suite
00009  *
00010  * This file is part of OpenOffice.org.
00011  *
00012  * OpenOffice.org is free software: you can redistribute it and/or modify
00013  * it under the terms of the GNU Lesser General Public License version 3
00014  * only, as published by the Free Software Foundation.
00015  *
00016  * OpenOffice.org is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Lesser General Public License version 3 for more details
00020  * (a copy is included in the LICENSE file that accompanied this code).
00021  *
00022  * You should have received a copy of the GNU Lesser General Public License
00023  * version 3 along with OpenOffice.org.  If not, see
00024  * <http://www.openoffice.org/license.html>
00025  * for a copy of the LGPLv3 License.
00026  *
00027  ************************************************************************/
00028 
00029 #if !defined INCLUDED_RTL_MATH_HXX
00030 #define INCLUDED_RTL_MATH_HXX
00031 
00032 #include "rtl/math.h"
00033 #include "rtl/string.hxx"
00034 #include "rtl/ustring.hxx"
00035 #include "rtl/ustrbuf.hxx"
00036 #include "sal/mathconf.h"
00037 #include "sal/types.h"
00038 
00039 #include <math.h>
00040 
00041 namespace rtl {
00042 
00043 namespace math {
00044 
00047 inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
00048                                    sal_Int32 nDecPlaces,
00049                                    sal_Char cDecSeparator,
00050                                    sal_Int32 const * pGroups,
00051                                    sal_Char cGroupSeparator,
00052                                    bool bEraseTrailingDecZeros = false)
00053 {
00054     rtl::OString aResult;
00055     rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
00056                             cDecSeparator, pGroups, cGroupSeparator,
00057                             bEraseTrailingDecZeros);
00058     return aResult;
00059 }
00060 
00063 inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
00064                                    sal_Int32 nDecPlaces,
00065                                    sal_Char cDecSeparator,
00066                                    bool bEraseTrailingDecZeros = false)
00067 {
00068     rtl::OString aResult;
00069     rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
00070                             cDecSeparator, 0, 0, bEraseTrailingDecZeros);
00071     return aResult;
00072 }
00073 
00076 inline rtl::OUString doubleToUString(double fValue,
00077                                      rtl_math_StringFormat eFormat,
00078                                      sal_Int32 nDecPlaces,
00079                                      sal_Unicode cDecSeparator,
00080                                      sal_Int32 const * pGroups,
00081                                      sal_Unicode cGroupSeparator,
00082                                      bool bEraseTrailingDecZeros = false)
00083 {
00084     rtl::OUString aResult;
00085     rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
00086                              cDecSeparator, pGroups, cGroupSeparator,
00087                              bEraseTrailingDecZeros);
00088     return aResult;
00089 }
00090 
00093 inline rtl::OUString doubleToUString(double fValue,
00094                                      rtl_math_StringFormat eFormat,
00095                                      sal_Int32 nDecPlaces,
00096                                      sal_Unicode cDecSeparator,
00097                                      bool bEraseTrailingDecZeros = false)
00098 {
00099     rtl::OUString aResult;
00100     rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
00101                              cDecSeparator, 0, 0, bEraseTrailingDecZeros);
00102     return aResult;
00103 }
00104 
00108 inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
00109                                    rtl_math_StringFormat eFormat,
00110                                    sal_Int32 nDecPlaces,
00111                                    sal_Unicode cDecSeparator,
00112                                    sal_Int32 const * pGroups,
00113                                    sal_Unicode cGroupSeparator,
00114                                    bool bEraseTrailingDecZeros = false)
00115 {
00116     rtl_uString ** pData;
00117     sal_Int32 * pCapacity;
00118     rBuffer.accessInternals( &pData, &pCapacity );
00119     rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
00120                               eFormat, nDecPlaces, cDecSeparator, pGroups,
00121                               cGroupSeparator, bEraseTrailingDecZeros);
00122 }
00123 
00127 inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
00128                                    rtl_math_StringFormat eFormat,
00129                                    sal_Int32 nDecPlaces,
00130                                    sal_Unicode cDecSeparator,
00131                                    bool bEraseTrailingDecZeros = false)
00132 {
00133     rtl_uString ** pData;
00134     sal_Int32 * pCapacity;
00135     rBuffer.accessInternals( &pData, &pCapacity );
00136     rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
00137                               eFormat, nDecPlaces, cDecSeparator, 0, 0,
00138                               bEraseTrailingDecZeros);
00139 }
00140 
00143 inline double stringToDouble(rtl::OString const & rString,
00144                              sal_Char cDecSeparator, sal_Char cGroupSeparator,
00145                              rtl_math_ConversionStatus * pStatus = 0,
00146                              sal_Int32 * pParsedEnd = 0)
00147 {
00148     sal_Char const * pBegin = rString.getStr();
00149     sal_Char const * pEnd;
00150     double fResult = rtl_math_stringToDouble(pBegin,
00151                                              pBegin + rString.getLength(),
00152                                              cDecSeparator, cGroupSeparator,
00153                                              pStatus, &pEnd);
00154     if (pParsedEnd != 0)
00155         *pParsedEnd = (sal_Int32)(pEnd - pBegin);
00156     return fResult;
00157 }
00158 
00161 inline double stringToDouble(rtl::OUString const & rString,
00162                              sal_Unicode cDecSeparator,
00163                              sal_Unicode cGroupSeparator,
00164                              rtl_math_ConversionStatus * pStatus = 0,
00165                              sal_Int32 * pParsedEnd = 0)
00166 {
00167     sal_Unicode const * pBegin = rString.getStr();
00168     sal_Unicode const * pEnd;
00169     double fResult = rtl_math_uStringToDouble(pBegin,
00170                                               pBegin + rString.getLength(),
00171                                               cDecSeparator, cGroupSeparator,
00172                                               pStatus, &pEnd);
00173     if (pParsedEnd != 0)
00174         *pParsedEnd = (sal_Int32)(pEnd - pBegin);
00175     return fResult;
00176 }
00177 
00180 inline double round(
00181     double fValue, int nDecPlaces = 0,
00182     rtl_math_RoundingMode eMode = rtl_math_RoundingMode_Corrected)
00183 {
00184     return rtl_math_round(fValue, nDecPlaces, eMode);
00185 }
00186 
00189 inline double pow10Exp(double fValue, int nExp)
00190 {
00191     return rtl_math_pow10Exp(fValue, nExp);
00192 }
00193 
00196 inline double approxValue(double fValue)
00197 {
00198     return rtl_math_approxValue(fValue);
00199 }
00200 
00203 inline double expm1(double fValue)
00204 {
00205     return rtl_math_expm1(fValue);
00206 }
00207 
00210 inline double log1p(double fValue)
00211 {
00212     return rtl_math_log1p(fValue);
00213 }
00214 
00217 inline double atanh(double fValue)
00218 {
00219     return rtl_math_atanh(fValue);
00220 }
00221 
00224 inline double erf(double fValue)
00225 {
00226     return rtl_math_erf(fValue);
00227 }
00228 
00231 inline double erfc(double fValue)
00232 {
00233     return rtl_math_erfc(fValue);
00234 }
00235 
00238 inline double asinh(double fValue)
00239 {
00240     return rtl_math_asinh(fValue);
00241 }
00242 
00245 inline double acosh(double fValue)
00246 {
00247     return rtl_math_acosh(fValue);
00248 }
00249 
00250 
00257 inline bool approxEqual(double a, double b)
00258 {
00259     if ( a == b )
00260         return true;
00261     double x = a - b;
00262     return (x < 0.0 ? -x : x)
00263         < ((a < 0.0 ? -a : a) * (1.0 / (16777216.0 * 16777216.0)));
00264 }
00265 
00271 inline bool approxEqual(double a, double b, sal_Int16 nPrec)
00272 {
00273     if ( a == b )
00274         return true;
00275     double x = a - b;
00276     return (x < 0.0 ? -x : x)
00277         < ((a < 0.0 ? -a : a) * (1.0 / (pow(static_cast<double>(2.0), nPrec))));
00278 }
00289 inline double approxAdd(double a, double b)
00290 {
00291     if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))
00292          && approxEqual( a, -b ) )
00293         return 0.0;
00294     return a + b;
00295 }
00296 
00302 inline double approxSub(double a, double b)
00303 {
00304     if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) )
00305         return 0.0;
00306     return a - b;
00307 }
00308 
00313 inline double approxFloor(double a)
00314 {
00315     return floor( approxValue( a ));
00316 }
00317 
00322 inline double approxCeil(double a)
00323 {
00324     return ceil( approxValue( a ));
00325 }
00326 
00329 inline bool isFinite(double d)
00330 {
00331     return SAL_MATH_FINITE(d) != 0;
00332 }
00333 
00340 inline bool isInf(double d)
00341 {
00342     // exponent==0x7ff fraction==0
00343     return (SAL_MATH_FINITE(d) == 0) &&
00344         (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0)
00345         && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
00346             == 0);
00347 }
00348 
00351 inline bool isNan(double d)
00352 {
00353     // exponent==0x7ff fraction!=0
00354     return (SAL_MATH_FINITE(d) == 0) && (
00355         (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0)
00356         || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
00357             != 0) );
00358 }
00359 
00362 inline bool isSignBitSet(double d)
00363 {
00364     return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0;
00365 }
00366 
00369 inline void setInf(double * pd, bool bNegative)
00370 {
00371     union
00372     {
00373         double sd;
00374         sal_math_Double md;
00375     };
00376     md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000;
00377     md.w32_parts.lsw = 0;
00378     *pd = sd;
00379 }
00380 
00383 inline void setNan(double * pd)
00384 {
00385     union
00386     {
00387         double sd;
00388         sal_math_Double md;
00389     };
00390     md.w32_parts.msw = 0x7FFFFFFF;
00391     md.w32_parts.lsw = 0xFFFFFFFF;
00392     *pd = sd;
00393 }
00394 
00404 inline bool isValidArcArg(double d)
00405 {
00406     return fabs(d)
00407         <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
00408             * static_cast< double >(static_cast< unsigned long >(0x80000000))
00409             * 2);
00410 }
00411 
00414 inline double sin(double d)
00415 {
00416     if ( isValidArcArg( d ) )
00417         return ::sin( d );
00418     setNan( &d );
00419     return d;
00420 }
00421 
00424 inline double cos(double d)
00425 {
00426     if ( isValidArcArg( d ) )
00427         return ::cos( d );
00428     setNan( &d );
00429     return d;
00430 }
00431 
00434 inline double tan(double d)
00435 {
00436     if ( isValidArcArg( d ) )
00437         return ::tan( d );
00438     setNan( &d );
00439     return d;
00440 }
00441 
00442 }
00443 
00444 }
00445 
00446 #endif // INCLUDED_RTL_MATH_HXX
00447 
00448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines