LCOV - code coverage report
Current view: top level - solver/unxlngi6.pro/inc/rtl - math.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 77 115 67.0 %
Date: 2012-08-25 Functions: 22 33 66.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 41 60 68.3 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #ifndef INCLUDED_RTL_MATH_HXX
      30                 :            : #define INCLUDED_RTL_MATH_HXX
      31                 :            : 
      32                 :            : #include "rtl/math.h"
      33                 :            : #include "rtl/string.hxx"
      34                 :            : #include "rtl/ustring.hxx"
      35                 :            : #include "rtl/ustrbuf.hxx"
      36                 :            : #include "sal/mathconf.h"
      37                 :            : #include "sal/types.h"
      38                 :            : 
      39                 :            : #include <math.h>
      40                 :            : 
      41                 :            : namespace rtl {
      42                 :            : 
      43                 :            : namespace math {
      44                 :            : 
      45                 :            : /** A wrapper around rtl_math_doubleToString.
      46                 :            :  */
      47                 :          0 : inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
      48                 :            :                                    sal_Int32 nDecPlaces,
      49                 :            :                                    sal_Char cDecSeparator,
      50                 :            :                                    sal_Int32 const * pGroups,
      51                 :            :                                    sal_Char cGroupSeparator,
      52                 :            :                                    bool bEraseTrailingDecZeros = false)
      53                 :            : {
      54                 :          0 :     rtl::OString aResult;
      55                 :            :     rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
      56                 :            :                             cDecSeparator, pGroups, cGroupSeparator,
      57                 :          0 :                             bEraseTrailingDecZeros);
      58                 :          0 :     return aResult;
      59                 :            : }
      60                 :            : 
      61                 :            : /** A wrapper around rtl_math_doubleToString, with no grouping.
      62                 :            :  */
      63                 :          0 : inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
      64                 :            :                                    sal_Int32 nDecPlaces,
      65                 :            :                                    sal_Char cDecSeparator,
      66                 :            :                                    bool bEraseTrailingDecZeros = false)
      67                 :            : {
      68                 :          0 :     rtl::OString aResult;
      69                 :            :     rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
      70                 :          0 :                             cDecSeparator, 0, 0, bEraseTrailingDecZeros);
      71                 :          0 :     return aResult;
      72                 :            : }
      73                 :            : 
      74                 :            : /** A wrapper around rtl_math_doubleToUString.
      75                 :            :  */
      76                 :          0 : inline rtl::OUString doubleToUString(double fValue,
      77                 :            :                                      rtl_math_StringFormat eFormat,
      78                 :            :                                      sal_Int32 nDecPlaces,
      79                 :            :                                      sal_Unicode cDecSeparator,
      80                 :            :                                      sal_Int32 const * pGroups,
      81                 :            :                                      sal_Unicode cGroupSeparator,
      82                 :            :                                      bool bEraseTrailingDecZeros = false)
      83                 :            : {
      84                 :          0 :     rtl::OUString aResult;
      85                 :            :     rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
      86                 :            :                              cDecSeparator, pGroups, cGroupSeparator,
      87                 :          0 :                              bEraseTrailingDecZeros);
      88                 :          0 :     return aResult;
      89                 :            : }
      90                 :            : 
      91                 :            : /** A wrapper around rtl_math_doubleToUString, with no grouping.
      92                 :            :  */
      93                 :      65133 : inline rtl::OUString doubleToUString(double fValue,
      94                 :            :                                      rtl_math_StringFormat eFormat,
      95                 :            :                                      sal_Int32 nDecPlaces,
      96                 :            :                                      sal_Unicode cDecSeparator,
      97                 :            :                                      bool bEraseTrailingDecZeros = false)
      98                 :            : {
      99                 :      65133 :     rtl::OUString aResult;
     100                 :            :     rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
     101                 :      65133 :                              cDecSeparator, 0, 0, bEraseTrailingDecZeros);
     102                 :      65133 :     return aResult;
     103                 :            : }
     104                 :            : 
     105                 :            : /** A wrapper around rtl_math_doubleToUString that appends to an
     106                 :            :     rtl::OUStringBuffer.
     107                 :            :  */
     108                 :            : inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
     109                 :            :                                    rtl_math_StringFormat eFormat,
     110                 :            :                                    sal_Int32 nDecPlaces,
     111                 :            :                                    sal_Unicode cDecSeparator,
     112                 :            :                                    sal_Int32 const * pGroups,
     113                 :            :                                    sal_Unicode cGroupSeparator,
     114                 :            :                                    bool bEraseTrailingDecZeros = false)
     115                 :            : {
     116                 :            :     rtl_uString ** pData;
     117                 :            :     sal_Int32 * pCapacity;
     118                 :            :     rBuffer.accessInternals( &pData, &pCapacity );
     119                 :            :     rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
     120                 :            :                               eFormat, nDecPlaces, cDecSeparator, pGroups,
     121                 :            :                               cGroupSeparator, bEraseTrailingDecZeros);
     122                 :            : }
     123                 :            : 
     124                 :            : /** A wrapper around rtl_math_doubleToUString that appends to an
     125                 :            :     rtl::OUStringBuffer, with no grouping.
     126                 :            :  */
     127                 :       1283 : inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
     128                 :            :                                    rtl_math_StringFormat eFormat,
     129                 :            :                                    sal_Int32 nDecPlaces,
     130                 :            :                                    sal_Unicode cDecSeparator,
     131                 :            :                                    bool bEraseTrailingDecZeros = false)
     132                 :            : {
     133                 :            :     rtl_uString ** pData;
     134                 :            :     sal_Int32 * pCapacity;
     135                 :       1283 :     rBuffer.accessInternals( &pData, &pCapacity );
     136                 :            :     rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
     137                 :            :                               eFormat, nDecPlaces, cDecSeparator, 0, 0,
     138                 :       1283 :                               bEraseTrailingDecZeros);
     139                 :       1283 : }
     140                 :            : 
     141                 :            : /** A wrapper around rtl_math_stringToDouble.
     142                 :            :  */
     143                 :       4327 : inline double stringToDouble(rtl::OString const & rString,
     144                 :            :                              sal_Char cDecSeparator, sal_Char cGroupSeparator,
     145                 :            :                              rtl_math_ConversionStatus * pStatus = 0,
     146                 :            :                              sal_Int32 * pParsedEnd = 0)
     147                 :            : {
     148                 :       4327 :     sal_Char const * pBegin = rString.getStr();
     149                 :            :     sal_Char const * pEnd;
     150                 :            :     double fResult = rtl_math_stringToDouble(pBegin,
     151                 :       4327 :                                              pBegin + rString.getLength(),
     152                 :            :                                              cDecSeparator, cGroupSeparator,
     153                 :       4327 :                                              pStatus, &pEnd);
     154         [ -  + ]:       4327 :     if (pParsedEnd != 0)
     155                 :          0 :         *pParsedEnd = (sal_Int32)(pEnd - pBegin);
     156                 :       4327 :     return fResult;
     157                 :            : }
     158                 :            : 
     159                 :            : /** A wrapper around rtl_math_uStringToDouble.
     160                 :            :  */
     161                 :      42390 : inline double stringToDouble(rtl::OUString const & rString,
     162                 :            :                              sal_Unicode cDecSeparator,
     163                 :            :                              sal_Unicode cGroupSeparator,
     164                 :            :                              rtl_math_ConversionStatus * pStatus = 0,
     165                 :            :                              sal_Int32 * pParsedEnd = 0)
     166                 :            : {
     167                 :      42390 :     sal_Unicode const * pBegin = rString.getStr();
     168                 :            :     sal_Unicode const * pEnd;
     169                 :            :     double fResult = rtl_math_uStringToDouble(pBegin,
     170                 :      42390 :                                               pBegin + rString.getLength(),
     171                 :            :                                               cDecSeparator, cGroupSeparator,
     172                 :      42390 :                                               pStatus, &pEnd);
     173         [ +  + ]:      42390 :     if (pParsedEnd != 0)
     174                 :       1136 :         *pParsedEnd = (sal_Int32)(pEnd - pBegin);
     175                 :      42390 :     return fResult;
     176                 :            : }
     177                 :            : 
     178                 :            : /** A wrapper around rtl_math_round.
     179                 :            :  */
     180                 :   49489603 : inline double round(
     181                 :            :     double fValue, int nDecPlaces = 0,
     182                 :            :     rtl_math_RoundingMode eMode = rtl_math_RoundingMode_Corrected)
     183                 :            : {
     184                 :   49489603 :     return rtl_math_round(fValue, nDecPlaces, eMode);
     185                 :            : }
     186                 :            : 
     187                 :            : /** A wrapper around rtl_math_pow10Exp.
     188                 :            :  */
     189                 :      26431 : inline double pow10Exp(double fValue, int nExp)
     190                 :            : {
     191                 :      26431 :     return rtl_math_pow10Exp(fValue, nExp);
     192                 :            : }
     193                 :            : 
     194                 :            : /** A wrapper around rtl_math_approxValue.
     195                 :            :  */
     196                 :      38183 : inline double approxValue(double fValue)
     197                 :            : {
     198                 :      38183 :     return rtl_math_approxValue(fValue);
     199                 :            : }
     200                 :            : 
     201                 :            : /** A wrapper around rtl_math_expm1.
     202                 :            :  */
     203                 :          0 : inline double expm1(double fValue)
     204                 :            : {
     205                 :          0 :     return rtl_math_expm1(fValue);
     206                 :            : }
     207                 :            : 
     208                 :            : /** A wrapper around rtl_math_log1p.
     209                 :            :  */
     210                 :          0 : inline double log1p(double fValue)
     211                 :            : {
     212                 :          0 :     return rtl_math_log1p(fValue);
     213                 :            : }
     214                 :            : 
     215                 :            : /** A wrapper around rtl_math_atanh.
     216                 :            :  */
     217                 :          0 : inline double atanh(double fValue)
     218                 :            : {
     219                 :          0 :     return rtl_math_atanh(fValue);
     220                 :            : }
     221                 :            : 
     222                 :            : /** A wrapper around rtl_math_erf.
     223                 :            :  */
     224                 :          0 : inline double erf(double fValue)
     225                 :            : {
     226                 :          0 :     return rtl_math_erf(fValue);
     227                 :            : }
     228                 :            : 
     229                 :            : /** A wrapper around rtl_math_erfc.
     230                 :            :  */
     231                 :          0 : inline double erfc(double fValue)
     232                 :            : {
     233                 :          0 :     return rtl_math_erfc(fValue);
     234                 :            : }
     235                 :            : 
     236                 :            : /** A wrapper around rtl_math_asinh.
     237                 :            :  */
     238                 :          0 : inline double asinh(double fValue)
     239                 :            : {
     240                 :          0 :     return rtl_math_asinh(fValue);
     241                 :            : }
     242                 :            : 
     243                 :            : /** A wrapper around rtl_math_acosh.
     244                 :            :  */
     245                 :          3 : inline double acosh(double fValue)
     246                 :            : {
     247                 :          3 :     return rtl_math_acosh(fValue);
     248                 :            : }
     249                 :            : 
     250                 :            : 
     251                 :            : /** Test equality of two values with an accuracy of the magnitude of the
     252                 :            :     given values scaled by 2^-48 (4 bits roundoff stripped).
     253                 :            : 
     254                 :            :     @attention
     255                 :            :     approxEqual( value!=0.0, 0.0 ) _never_ yields true.
     256                 :            :  */
     257                 :   28543821 : inline bool approxEqual(double a, double b)
     258                 :            : {
     259         [ +  + ]:   28543821 :     if ( a == b )
     260                 :    9859908 :         return true;
     261                 :   18683913 :     double x = a - b;
     262                 :            :     return (x < 0.0 ? -x : x)
     263 [ +  + ][ +  + ]:   28543821 :         < ((a < 0.0 ? -a : a) * (1.0 / (16777216.0 * 16777216.0)));
     264                 :            : }
     265                 :            : 
     266                 :            : /** Test equality of two values with an accuracy defined by nPrec
     267                 :            : 
     268                 :            :     @attention
     269                 :            :     approxEqual( value!=0.0, 0.0 ) _never_ yields true.
     270                 :            :  */
     271                 :          0 : inline bool approxEqual(double a, double b, sal_Int16 nPrec)
     272                 :            : {
     273         [ #  # ]:          0 :     if ( a == b )
     274                 :          0 :         return true;
     275                 :          0 :     double x = a - b;
     276                 :            :     return (x < 0.0 ? -x : x)
     277 [ #  # ][ #  # ]:          0 :         < ((a < 0.0 ? -a : a) * (1.0 / (pow(static_cast<double>(2.0), nPrec))));
     278                 :            : }
     279                 :            : /** Add two values.
     280                 :            : 
     281                 :            :     If signs differ and the absolute values are equal according to approxEqual()
     282                 :            :     the method returns 0.0 instead of calculating the sum.
     283                 :            : 
     284                 :            :     If you wanted to sum up multiple values it would be convenient not to call
     285                 :            :     approxAdd() for each value but instead remember the first value not equal to
     286                 :            :     0.0, add all other values using normal + operator, and with the result and
     287                 :            :     the remembered value call approxAdd().
     288                 :            :  */
     289                 :        416 : inline double approxAdd(double a, double b)
     290                 :            : {
     291 [ +  + ][ -  + ]:        423 :     if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))
                 [ -  + ]
           [ #  #  -  + ]
                 [ -  + ]
     292                 :          7 :          && approxEqual( a, -b ) )
     293                 :          0 :         return 0.0;
     294                 :        416 :     return a + b;
     295                 :            : }
     296                 :            : 
     297                 :            : /** Substract two values (a-b).
     298                 :            : 
     299                 :            :     If signs are identical and the values are equal according to approxEqual()
     300                 :            :     the method returns 0.0 instead of calculating the substraction.
     301                 :            :  */
     302                 :      49828 : inline double approxSub(double a, double b)
     303                 :            : {
     304 [ +  + ][ +  + ]:      49828 :     if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) )
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     305                 :       8621 :         return 0.0;
     306                 :      49828 :     return a - b;
     307                 :            : }
     308                 :            : 
     309                 :            : /** floor() method taking approxValue() into account.
     310                 :            : 
     311                 :            :     Use for expected integer values being calculated by double functions.
     312                 :            :  */
     313                 :      36847 : inline double approxFloor(double a)
     314                 :            : {
     315                 :      36847 :     return floor( approxValue( a ));
     316                 :            : }
     317                 :            : 
     318                 :            : /** ceil() method taking approxValue() into account.
     319                 :            : 
     320                 :            :     Use for expected integer values being calculated by double functions.
     321                 :            :  */
     322                 :       1336 : inline double approxCeil(double a)
     323                 :            : {
     324                 :       1336 :     return ceil( approxValue( a ));
     325                 :            : }
     326                 :            : 
     327                 :            : /** Tests whether a value is neither INF nor NAN.
     328                 :            :  */
     329                 :     252687 : inline bool isFinite(double d)
     330                 :            : {
     331                 :     252687 :     return SAL_MATH_FINITE(d) != 0;
     332                 :            : }
     333                 :            : 
     334                 :            : /** If a value represents +INF or -INF.
     335                 :            : 
     336                 :            :     The sign bit may be queried with isSignBitSet().
     337                 :            : 
     338                 :            :     If isFinite(d)==false and isInf(d)==false then NAN.
     339                 :            :  */
     340                 :     597408 : inline bool isInf(double d)
     341                 :            : {
     342                 :            :     // exponent==0x7ff fraction==0
     343                 :     597408 :     return (SAL_MATH_FINITE(d) == 0) &&
     344                 :            :         (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0)
     345                 :            :         && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
     346 [ +  + ][ +  - ]:     597408 :             == 0);
                 [ +  + ]
     347                 :            : }
     348                 :            : 
     349                 :            : /** Test on any QNAN or SNAN.
     350                 :            :  */
     351                 :     778823 : inline bool isNan(double d)
     352                 :            : {
     353                 :            :     // exponent==0x7ff fraction!=0
     354                 :     778823 :     return (SAL_MATH_FINITE(d) == 0) && (
     355                 :            :         (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0)
     356                 :            :         || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
     357 [ +  + ][ -  + ]:     778823 :             != 0) );
                 [ +  + ]
     358                 :            : }
     359                 :            : 
     360                 :            : /** If the sign bit is set.
     361                 :            :  */
     362                 :     358626 : inline bool isSignBitSet(double d)
     363                 :            : {
     364                 :     358626 :     return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0;
     365                 :            : }
     366                 :            : 
     367                 :            : /** Set to +INF if bNegative==false or -INF if bNegative==true.
     368                 :            :  */
     369                 :     289944 : inline void setInf(double * pd, bool bNegative)
     370                 :            : {
     371                 :            :     union
     372                 :            :     {
     373                 :            :         double sd;
     374                 :            :         sal_math_Double md;
     375                 :            :     };
     376         [ +  + ]:     289944 :     md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000;
     377                 :     289944 :     md.w32_parts.lsw = 0;
     378                 :     289944 :     *pd = sd;
     379                 :     289944 : }
     380                 :            : 
     381                 :            : /** Set a QNAN.
     382                 :            :  */
     383                 :     266203 : inline void setNan(double * pd)
     384                 :            : {
     385                 :            :     union
     386                 :            :     {
     387                 :            :         double sd;
     388                 :            :         sal_math_Double md;
     389                 :            :     };
     390                 :     266203 :     md.w32_parts.msw = 0x7FFFFFFF;
     391                 :     266203 :     md.w32_parts.lsw = 0xFFFFFFFF;
     392                 :     266203 :     *pd = sd;
     393                 :     266203 : }
     394                 :            : 
     395                 :            : /** If a value is a valid argument for sin(), cos(), tan().
     396                 :            : 
     397                 :            :     IEEE 754 specifies that absolute values up to 2^64 (=1.844e19) for the
     398                 :            :     radian must be supported by trigonometric functions.  Unfortunately, at
     399                 :            :     least on x86 architectures, the FPU doesn't generate an error pattern for
     400                 :            :     values >2^64 but produces erroneous results instead and sets only the
     401                 :            :     "invalid operation" (IM) flag in the status word :-(  Thus the application
     402                 :            :     has to handle it itself.
     403                 :            :  */
     404                 :       5424 : inline bool isValidArcArg(double d)
     405                 :            : {
     406                 :       5424 :     return fabs(d)
     407                 :            :         <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
     408                 :            :             * static_cast< double >(static_cast< unsigned long >(0x80000000))
     409                 :       5424 :             * 2);
     410                 :            : }
     411                 :            : 
     412                 :            : /** Safe sin(), returns NAN if not valid.
     413                 :            :  */
     414                 :       3004 : inline double sin(double d)
     415                 :            : {
     416         [ +  - ]:       3004 :     if ( isValidArcArg( d ) )
     417                 :       3004 :         return ::sin( d );
     418                 :          0 :     setNan( &d );
     419                 :       3004 :     return d;
     420                 :            : }
     421                 :            : 
     422                 :            : /** Safe cos(), returns NAN if not valid.
     423                 :            :  */
     424                 :       2420 : inline double cos(double d)
     425                 :            : {
     426         [ +  - ]:       2420 :     if ( isValidArcArg( d ) )
     427                 :       2420 :         return ::cos( d );
     428                 :          0 :     setNan( &d );
     429                 :       2420 :     return d;
     430                 :            : }
     431                 :            : 
     432                 :            : /** Safe tan(), returns NAN if not valid.
     433                 :            :  */
     434                 :          0 : inline double tan(double d)
     435                 :            : {
     436         [ #  # ]:          0 :     if ( isValidArcArg( d ) )
     437                 :          0 :         return ::tan( d );
     438                 :          0 :     setNan( &d );
     439                 :          0 :     return d;
     440                 :            : }
     441                 :            : 
     442                 :            : }
     443                 :            : 
     444                 :            : }
     445                 :            : 
     446                 :            : #endif // INCLUDED_RTL_MATH_HXX
     447                 :            : 
     448                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10