1565d668cSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3565d668cSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4565d668cSAndrew Rist * or more contributor license agreements. See the NOTICE file 5565d668cSAndrew Rist * distributed with this work for additional information 6565d668cSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7565d668cSAndrew Rist * to you under the Apache License, Version 2.0 (the 8565d668cSAndrew Rist * "License"); you may not use this file except in compliance 9565d668cSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11565d668cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13565d668cSAndrew Rist * Unless required by applicable law or agreed to in writing, 14565d668cSAndrew Rist * software distributed under the License is distributed on an 15565d668cSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16565d668cSAndrew Rist * KIND, either express or implied. See the License for the 17565d668cSAndrew Rist * specific language governing permissions and limitations 18565d668cSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20565d668cSAndrew Rist *************************************************************/ 21565d668cSAndrew Rist 22565d668cSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #if !defined INCLUDED_RTL_MATH_HXX 25cdf0e10cSrcweir #define INCLUDED_RTL_MATH_HXX 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "rtl/math.h" 28cdf0e10cSrcweir #include "rtl/string.hxx" 29cdf0e10cSrcweir #include "rtl/ustring.hxx" 30cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 31cdf0e10cSrcweir #include "sal/mathconf.h" 32cdf0e10cSrcweir #include "sal/types.h" 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <math.h> 35cdf0e10cSrcweir 36cdf0e10cSrcweir namespace rtl { 37cdf0e10cSrcweir 38cdf0e10cSrcweir namespace math { 39cdf0e10cSrcweir 40cdf0e10cSrcweir /** A wrapper around rtl_math_doubleToString. 41cdf0e10cSrcweir */ 42cdf0e10cSrcweir inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat, 43cdf0e10cSrcweir sal_Int32 nDecPlaces, 44cdf0e10cSrcweir sal_Char cDecSeparator, 45cdf0e10cSrcweir sal_Int32 const * pGroups, 46cdf0e10cSrcweir sal_Char cGroupSeparator, 47cdf0e10cSrcweir bool bEraseTrailingDecZeros = false) 48cdf0e10cSrcweir { 49cdf0e10cSrcweir rtl::OString aResult; 50cdf0e10cSrcweir rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces, 51cdf0e10cSrcweir cDecSeparator, pGroups, cGroupSeparator, 52cdf0e10cSrcweir bEraseTrailingDecZeros); 53cdf0e10cSrcweir return aResult; 54cdf0e10cSrcweir } 55cdf0e10cSrcweir 56cdf0e10cSrcweir /** A wrapper around rtl_math_doubleToString, with no grouping. 57cdf0e10cSrcweir */ 58cdf0e10cSrcweir inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat, 59cdf0e10cSrcweir sal_Int32 nDecPlaces, 60cdf0e10cSrcweir sal_Char cDecSeparator, 61cdf0e10cSrcweir bool bEraseTrailingDecZeros = false) 62cdf0e10cSrcweir { 63cdf0e10cSrcweir rtl::OString aResult; 64cdf0e10cSrcweir rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces, 65cdf0e10cSrcweir cDecSeparator, 0, 0, bEraseTrailingDecZeros); 66cdf0e10cSrcweir return aResult; 67cdf0e10cSrcweir } 68cdf0e10cSrcweir 69cdf0e10cSrcweir /** A wrapper around rtl_math_doubleToUString. 70cdf0e10cSrcweir */ 71cdf0e10cSrcweir inline rtl::OUString doubleToUString(double fValue, 72cdf0e10cSrcweir rtl_math_StringFormat eFormat, 73cdf0e10cSrcweir sal_Int32 nDecPlaces, 74cdf0e10cSrcweir sal_Unicode cDecSeparator, 75cdf0e10cSrcweir sal_Int32 const * pGroups, 76cdf0e10cSrcweir sal_Unicode cGroupSeparator, 77cdf0e10cSrcweir bool bEraseTrailingDecZeros = false) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir rtl::OUString aResult; 80cdf0e10cSrcweir rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces, 81cdf0e10cSrcweir cDecSeparator, pGroups, cGroupSeparator, 82cdf0e10cSrcweir bEraseTrailingDecZeros); 83cdf0e10cSrcweir return aResult; 84cdf0e10cSrcweir } 85cdf0e10cSrcweir 86cdf0e10cSrcweir /** A wrapper around rtl_math_doubleToUString, with no grouping. 87cdf0e10cSrcweir */ 88cdf0e10cSrcweir inline rtl::OUString doubleToUString(double fValue, 89cdf0e10cSrcweir rtl_math_StringFormat eFormat, 90cdf0e10cSrcweir sal_Int32 nDecPlaces, 91cdf0e10cSrcweir sal_Unicode cDecSeparator, 92cdf0e10cSrcweir bool bEraseTrailingDecZeros = false) 93cdf0e10cSrcweir { 94cdf0e10cSrcweir rtl::OUString aResult; 95cdf0e10cSrcweir rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces, 96cdf0e10cSrcweir cDecSeparator, 0, 0, bEraseTrailingDecZeros); 97cdf0e10cSrcweir return aResult; 98cdf0e10cSrcweir } 99cdf0e10cSrcweir 100cdf0e10cSrcweir /** A wrapper around rtl_math_doubleToUString that appends to an 101cdf0e10cSrcweir rtl::OUStringBuffer. 102cdf0e10cSrcweir */ 103cdf0e10cSrcweir inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue, 104cdf0e10cSrcweir rtl_math_StringFormat eFormat, 105cdf0e10cSrcweir sal_Int32 nDecPlaces, 106cdf0e10cSrcweir sal_Unicode cDecSeparator, 107cdf0e10cSrcweir sal_Int32 const * pGroups, 108cdf0e10cSrcweir sal_Unicode cGroupSeparator, 109cdf0e10cSrcweir bool bEraseTrailingDecZeros = false) 110cdf0e10cSrcweir { 111cdf0e10cSrcweir rtl_uString ** pData; 112cdf0e10cSrcweir sal_Int32 * pCapacity; 113cdf0e10cSrcweir rBuffer.accessInternals( &pData, &pCapacity ); 114cdf0e10cSrcweir rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue, 115cdf0e10cSrcweir eFormat, nDecPlaces, cDecSeparator, pGroups, 116cdf0e10cSrcweir cGroupSeparator, bEraseTrailingDecZeros); 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir /** A wrapper around rtl_math_doubleToUString that appends to an 120cdf0e10cSrcweir rtl::OUStringBuffer, with no grouping. 121cdf0e10cSrcweir */ 122cdf0e10cSrcweir inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue, 123cdf0e10cSrcweir rtl_math_StringFormat eFormat, 124cdf0e10cSrcweir sal_Int32 nDecPlaces, 125cdf0e10cSrcweir sal_Unicode cDecSeparator, 126cdf0e10cSrcweir bool bEraseTrailingDecZeros = false) 127cdf0e10cSrcweir { 128cdf0e10cSrcweir rtl_uString ** pData; 129cdf0e10cSrcweir sal_Int32 * pCapacity; 130cdf0e10cSrcweir rBuffer.accessInternals( &pData, &pCapacity ); 131cdf0e10cSrcweir rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue, 132cdf0e10cSrcweir eFormat, nDecPlaces, cDecSeparator, 0, 0, 133cdf0e10cSrcweir bEraseTrailingDecZeros); 134cdf0e10cSrcweir } 135cdf0e10cSrcweir 136cdf0e10cSrcweir /** A wrapper around rtl_math_stringToDouble. 137cdf0e10cSrcweir */ 138cdf0e10cSrcweir inline double stringToDouble(rtl::OString const & rString, 139cdf0e10cSrcweir sal_Char cDecSeparator, sal_Char cGroupSeparator, 140cdf0e10cSrcweir rtl_math_ConversionStatus * pStatus, 141cdf0e10cSrcweir sal_Int32 * pParsedEnd) 142cdf0e10cSrcweir { 143cdf0e10cSrcweir sal_Char const * pBegin = rString.getStr(); 144cdf0e10cSrcweir sal_Char const * pEnd; 145cdf0e10cSrcweir double fResult = rtl_math_stringToDouble(pBegin, 146cdf0e10cSrcweir pBegin + rString.getLength(), 147cdf0e10cSrcweir cDecSeparator, cGroupSeparator, 148cdf0e10cSrcweir pStatus, &pEnd); 149cdf0e10cSrcweir if (pParsedEnd != 0) 150cdf0e10cSrcweir *pParsedEnd = (sal_Int32)(pEnd - pBegin); 151cdf0e10cSrcweir return fResult; 152cdf0e10cSrcweir } 153cdf0e10cSrcweir 154cdf0e10cSrcweir /** A wrapper around rtl_math_uStringToDouble. 155cdf0e10cSrcweir */ 156cdf0e10cSrcweir inline double stringToDouble(rtl::OUString const & rString, 157cdf0e10cSrcweir sal_Unicode cDecSeparator, 158cdf0e10cSrcweir sal_Unicode cGroupSeparator, 159cdf0e10cSrcweir rtl_math_ConversionStatus * pStatus, 160cdf0e10cSrcweir sal_Int32 * pParsedEnd) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir sal_Unicode const * pBegin = rString.getStr(); 163cdf0e10cSrcweir sal_Unicode const * pEnd; 164cdf0e10cSrcweir double fResult = rtl_math_uStringToDouble(pBegin, 165cdf0e10cSrcweir pBegin + rString.getLength(), 166cdf0e10cSrcweir cDecSeparator, cGroupSeparator, 167cdf0e10cSrcweir pStatus, &pEnd); 168cdf0e10cSrcweir if (pParsedEnd != 0) 169cdf0e10cSrcweir *pParsedEnd = (sal_Int32)(pEnd - pBegin); 170cdf0e10cSrcweir return fResult; 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir /** A wrapper around rtl_math_round. 174cdf0e10cSrcweir */ 175cdf0e10cSrcweir inline double round( 176cdf0e10cSrcweir double fValue, int nDecPlaces = 0, 177cdf0e10cSrcweir rtl_math_RoundingMode eMode = rtl_math_RoundingMode_Corrected) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir return rtl_math_round(fValue, nDecPlaces, eMode); 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir /** A wrapper around rtl_math_pow10Exp. 183cdf0e10cSrcweir */ 184cdf0e10cSrcweir inline double pow10Exp(double fValue, int nExp) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir return rtl_math_pow10Exp(fValue, nExp); 187cdf0e10cSrcweir } 188cdf0e10cSrcweir 189*cda7f8b3SPedro Giffuni /** A wrapper around rtl_math_powr. 190*cda7f8b3SPedro Giffuni */ 191*cda7f8b3SPedro Giffuni inline double powr(double fValue, double fExp) 192*cda7f8b3SPedro Giffuni { 193*cda7f8b3SPedro Giffuni return rtl_math_powr(fValue, fExp); 194*cda7f8b3SPedro Giffuni } 195*cda7f8b3SPedro Giffuni 196cdf0e10cSrcweir /** A wrapper around rtl_math_approxValue. 197cdf0e10cSrcweir */ 198cdf0e10cSrcweir inline double approxValue(double fValue) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir return rtl_math_approxValue(fValue); 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir /** A wrapper around rtl_math_expm1. 204cdf0e10cSrcweir */ 205cdf0e10cSrcweir inline double expm1(double fValue) 206cdf0e10cSrcweir { 207cdf0e10cSrcweir return rtl_math_expm1(fValue); 208cdf0e10cSrcweir } 209cdf0e10cSrcweir 210cdf0e10cSrcweir /** A wrapper around rtl_math_log1p. 211cdf0e10cSrcweir */ 212cdf0e10cSrcweir inline double log1p(double fValue) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir return rtl_math_log1p(fValue); 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir /** A wrapper around rtl_math_atanh. 218cdf0e10cSrcweir */ 219cdf0e10cSrcweir inline double atanh(double fValue) 220cdf0e10cSrcweir { 221cdf0e10cSrcweir return rtl_math_atanh(fValue); 222cdf0e10cSrcweir } 223cdf0e10cSrcweir 224cdf0e10cSrcweir /** A wrapper around rtl_math_erf. 225cdf0e10cSrcweir */ 226cdf0e10cSrcweir inline double erf(double fValue) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir return rtl_math_erf(fValue); 229cdf0e10cSrcweir } 230cdf0e10cSrcweir 231cdf0e10cSrcweir /** A wrapper around rtl_math_erfc. 232cdf0e10cSrcweir */ 233cdf0e10cSrcweir inline double erfc(double fValue) 234cdf0e10cSrcweir { 235cdf0e10cSrcweir return rtl_math_erfc(fValue); 236cdf0e10cSrcweir } 237cdf0e10cSrcweir 238cdf0e10cSrcweir /** A wrapper around rtl_math_asinh. 239cdf0e10cSrcweir */ 240cdf0e10cSrcweir inline double asinh(double fValue) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir return rtl_math_asinh(fValue); 243cdf0e10cSrcweir } 244cdf0e10cSrcweir 245cdf0e10cSrcweir /** A wrapper around rtl_math_acosh. 246cdf0e10cSrcweir */ 247cdf0e10cSrcweir inline double acosh(double fValue) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir return rtl_math_acosh(fValue); 250cdf0e10cSrcweir } 251cdf0e10cSrcweir 252cdf0e10cSrcweir 253cdf0e10cSrcweir /** Test equality of two values with an accuracy of the magnitude of the 254cdf0e10cSrcweir given values scaled by 2^-48 (4 bits roundoff stripped). 255cdf0e10cSrcweir 256cdf0e10cSrcweir @ATTENTION 257cdf0e10cSrcweir approxEqual( value!=0.0, 0.0 ) _never_ yields true. 258cdf0e10cSrcweir */ 259cdf0e10cSrcweir inline bool approxEqual(double a, double b) 260cdf0e10cSrcweir { 261cdf0e10cSrcweir if ( a == b ) 262cdf0e10cSrcweir return true; 263cdf0e10cSrcweir double x = a - b; 264cdf0e10cSrcweir return (x < 0.0 ? -x : x) 265cdf0e10cSrcweir < ((a < 0.0 ? -a : a) * (1.0 / (16777216.0 * 16777216.0))); 266cdf0e10cSrcweir } 267cdf0e10cSrcweir 268cdf0e10cSrcweir /** Add two values. 269cdf0e10cSrcweir 270cdf0e10cSrcweir If signs differ and the absolute values are equal according to approxEqual() 271cdf0e10cSrcweir the method returns 0.0 instead of calculating the sum. 272cdf0e10cSrcweir 273cdf0e10cSrcweir If you wanted to sum up multiple values it would be convenient not to call 274cdf0e10cSrcweir approxAdd() for each value but instead remember the first value not equal to 275cdf0e10cSrcweir 0.0, add all other values using normal + operator, and with the result and 276cdf0e10cSrcweir the remembered value call approxAdd(). 277cdf0e10cSrcweir */ 278cdf0e10cSrcweir inline double approxAdd(double a, double b) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0)) 281cdf0e10cSrcweir && approxEqual( a, -b ) ) 282cdf0e10cSrcweir return 0.0; 283cdf0e10cSrcweir return a + b; 284cdf0e10cSrcweir } 285cdf0e10cSrcweir 28686e1cf34SPedro Giffuni /** Subtract two values (a-b). 287cdf0e10cSrcweir 288cdf0e10cSrcweir If signs are identical and the values are equal according to approxEqual() 28986e1cf34SPedro Giffuni the method returns 0.0 instead of calculating the subtraction. 290cdf0e10cSrcweir */ 291cdf0e10cSrcweir inline double approxSub(double a, double b) 292cdf0e10cSrcweir { 293cdf0e10cSrcweir if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) ) 294cdf0e10cSrcweir return 0.0; 295cdf0e10cSrcweir return a - b; 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 298cdf0e10cSrcweir /** floor() method taking approxValue() into account. 299cdf0e10cSrcweir 300cdf0e10cSrcweir Use for expected integer values being calculated by double functions. 301cdf0e10cSrcweir */ 302cdf0e10cSrcweir inline double approxFloor(double a) 303cdf0e10cSrcweir { 304cdf0e10cSrcweir return floor( approxValue( a )); 305cdf0e10cSrcweir } 306cdf0e10cSrcweir 307cdf0e10cSrcweir /** ceil() method taking approxValue() into account. 308cdf0e10cSrcweir 309cdf0e10cSrcweir Use for expected integer values being calculated by double functions. 310cdf0e10cSrcweir */ 311cdf0e10cSrcweir inline double approxCeil(double a) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir return ceil( approxValue( a )); 314cdf0e10cSrcweir } 315cdf0e10cSrcweir 316cdf0e10cSrcweir /** Tests whether a value is neither INF nor NAN. 317cdf0e10cSrcweir */ 318cdf0e10cSrcweir inline bool isFinite(double d) 319cdf0e10cSrcweir { 320cdf0e10cSrcweir return SAL_MATH_FINITE(d) != 0; 321cdf0e10cSrcweir } 322cdf0e10cSrcweir 323cdf0e10cSrcweir /** If a value represents +INF or -INF. 324cdf0e10cSrcweir 325cdf0e10cSrcweir The sign bit may be queried with isSignBitSet(). 326cdf0e10cSrcweir 327cdf0e10cSrcweir If isFinite(d)==false and isInf(d)==false then NAN. 328cdf0e10cSrcweir */ 329cdf0e10cSrcweir inline bool isInf(double d) 330cdf0e10cSrcweir { 331cdf0e10cSrcweir // exponent==0x7ff fraction==0 332cdf0e10cSrcweir return (SAL_MATH_FINITE(d) == 0) && 333cdf0e10cSrcweir (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0) 334cdf0e10cSrcweir && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo 335cdf0e10cSrcweir == 0); 336cdf0e10cSrcweir } 337cdf0e10cSrcweir 338cdf0e10cSrcweir /** Test on any QNAN or SNAN. 339cdf0e10cSrcweir */ 340cdf0e10cSrcweir inline bool isNan(double d) 341cdf0e10cSrcweir { 342cdf0e10cSrcweir // exponent==0x7ff fraction!=0 343cdf0e10cSrcweir return (SAL_MATH_FINITE(d) == 0) && ( 344cdf0e10cSrcweir (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0) 345cdf0e10cSrcweir || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo 346cdf0e10cSrcweir != 0) ); 347cdf0e10cSrcweir } 348cdf0e10cSrcweir 349cdf0e10cSrcweir /** If the sign bit is set. 350cdf0e10cSrcweir */ 351cdf0e10cSrcweir inline bool isSignBitSet(double d) 352cdf0e10cSrcweir { 353cdf0e10cSrcweir return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0; 354cdf0e10cSrcweir } 355cdf0e10cSrcweir 356cdf0e10cSrcweir /** Set to +INF if bNegative==false or -INF if bNegative==true. 357cdf0e10cSrcweir */ 358cdf0e10cSrcweir inline void setInf(double * pd, bool bNegative) 359cdf0e10cSrcweir { 360cdf0e10cSrcweir union 361cdf0e10cSrcweir { 362cdf0e10cSrcweir double sd; 363cdf0e10cSrcweir sal_math_Double md; 364cdf0e10cSrcweir }; 365cdf0e10cSrcweir md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000; 366cdf0e10cSrcweir md.w32_parts.lsw = 0; 367cdf0e10cSrcweir *pd = sd; 368cdf0e10cSrcweir } 369cdf0e10cSrcweir 370cdf0e10cSrcweir /** Set a QNAN. 371cdf0e10cSrcweir */ 372cdf0e10cSrcweir inline void setNan(double * pd) 373cdf0e10cSrcweir { 374cdf0e10cSrcweir union 375cdf0e10cSrcweir { 376cdf0e10cSrcweir double sd; 377cdf0e10cSrcweir sal_math_Double md; 378cdf0e10cSrcweir }; 379cdf0e10cSrcweir md.w32_parts.msw = 0x7FFFFFFF; 380cdf0e10cSrcweir md.w32_parts.lsw = 0xFFFFFFFF; 381cdf0e10cSrcweir *pd = sd; 382cdf0e10cSrcweir } 383cdf0e10cSrcweir 384cdf0e10cSrcweir /** If a value is a valid argument for sin(), cos(), tan(). 385cdf0e10cSrcweir 386cdf0e10cSrcweir IEEE 754 specifies that absolute values up to 2^64 (=1.844e19) for the 387cdf0e10cSrcweir radian must be supported by trigonometric functions. Unfortunately, at 388cdf0e10cSrcweir least on x86 architectures, the FPU doesn't generate an error pattern for 389cdf0e10cSrcweir values >2^64 but produces erroneous results instead and sets only the 390cdf0e10cSrcweir "invalid operation" (IM) flag in the status word :-( Thus the application 391cdf0e10cSrcweir has to handle it itself. 392cdf0e10cSrcweir */ 393cdf0e10cSrcweir inline bool isValidArcArg(double d) 394cdf0e10cSrcweir { 395cdf0e10cSrcweir return fabs(d) 396cdf0e10cSrcweir <= (static_cast< double >(static_cast< unsigned long >(0x80000000)) 397cdf0e10cSrcweir * static_cast< double >(static_cast< unsigned long >(0x80000000)) 398cdf0e10cSrcweir * 2); 399cdf0e10cSrcweir } 400cdf0e10cSrcweir 401cdf0e10cSrcweir /** Safe sin(), returns NAN if not valid. 402cdf0e10cSrcweir */ 403cdf0e10cSrcweir inline double sin(double d) 404cdf0e10cSrcweir { 405cdf0e10cSrcweir if ( isValidArcArg( d ) ) 406cdf0e10cSrcweir return ::sin( d ); 407cdf0e10cSrcweir setNan( &d ); 408cdf0e10cSrcweir return d; 409cdf0e10cSrcweir } 410cdf0e10cSrcweir 411cdf0e10cSrcweir /** Safe cos(), returns NAN if not valid. 412cdf0e10cSrcweir */ 413cdf0e10cSrcweir inline double cos(double d) 414cdf0e10cSrcweir { 415cdf0e10cSrcweir if ( isValidArcArg( d ) ) 416cdf0e10cSrcweir return ::cos( d ); 417cdf0e10cSrcweir setNan( &d ); 418cdf0e10cSrcweir return d; 419cdf0e10cSrcweir } 420cdf0e10cSrcweir 421cdf0e10cSrcweir /** Safe tan(), returns NAN if not valid. 422cdf0e10cSrcweir */ 423cdf0e10cSrcweir inline double tan(double d) 424cdf0e10cSrcweir { 425cdf0e10cSrcweir if ( isValidArcArg( d ) ) 426cdf0e10cSrcweir return ::tan( d ); 427cdf0e10cSrcweir setNan( &d ); 428cdf0e10cSrcweir return d; 429cdf0e10cSrcweir } 430cdf0e10cSrcweir 431cdf0e10cSrcweir } 432cdf0e10cSrcweir 433cdf0e10cSrcweir } 434cdf0e10cSrcweir 435cdf0e10cSrcweir #endif // INCLUDED_RTL_MATH_HXX 436