diff options
-rw-r--r-- | sal/inc/rtl/math.h | 18 | ||||
-rw-r--r-- | sal/inc/rtl/math.hxx | 14 | ||||
-rw-r--r-- | sal/rtl/source/math.cxx | 21 | ||||
-rwxr-xr-x | sal/util/sal.map | 6 |
4 files changed, 59 insertions, 0 deletions
diff --git a/sal/inc/rtl/math.h b/sal/inc/rtl/math.h index 01df54fc6..d954e7810 100644 --- a/sal/inc/rtl/math.h +++ b/sal/inc/rtl/math.h @@ -406,6 +406,24 @@ double SAL_CALL rtl_math_pow10Exp(double fValue, int nExp) SAL_THROW_EXTERN_C(); */ double SAL_CALL rtl_math_approxValue(double fValue) SAL_THROW_EXTERN_C(); +/** Returns more accurate e^x-1 for x near 0 than calculating directly. + + expm1 is part of the C99 standard, but not provided by some compilers. + + @param fValue + The value x in the term e^x-1. + */ +double SAL_CALL rtl_math_expm1(double fValue) SAL_THROW_EXTERN_C(); + +/** Returns more accurate log(1+x) for x near 0 than calculating directly. + + log1p is part of the C99 standard, but not provided by some compilers. + + @param fValue + The value x in the term log(1+x). + */ +double SAL_CALL rtl_math_log1p(double fValue) SAL_THROW_EXTERN_C(); + #if defined __cplusplus } #endif /* __cplusplus */ diff --git a/sal/inc/rtl/math.hxx b/sal/inc/rtl/math.hxx index c93e7de4e..724d2d102 100644 --- a/sal/inc/rtl/math.hxx +++ b/sal/inc/rtl/math.hxx @@ -200,6 +200,20 @@ inline double approxValue(double fValue) return rtl_math_approxValue(fValue); } +/** A wrapper around rtl_math_expm1. + */ +inline double expm1(double fValue) +{ + return rtl_math_expm1(fValue); +} + +/** A wrapper around rtl_math_log1p. + */ +inline double log1p(double fValue) +{ + return rtl_math_log1p(fValue); +} + /** Test equality of two values with an accuracy of the magnitude of the given values scaled by 2^-48 (4 bits roundoff stripped). diff --git a/sal/rtl/source/math.cxx b/sal/rtl/source/math.cxx index fde2a16cb..6258f3faf 100644 --- a/sal/rtl/source/math.cxx +++ b/sal/rtl/source/math.cxx @@ -959,3 +959,24 @@ double SAL_CALL rtl_math_approxValue( double fValue ) SAL_THROW_EXTERN_C() return bSign ? -fValue : fValue; } + + +double SAL_CALL rtl_math_expm1( double fValue ) SAL_THROW_EXTERN_C() +{ + double fe = exp( fValue ); + if (fe == 1.0) + return fValue; + if (fe-1.0 == -1.0) + return -1.0; + return (fe-1.0) * fValue / log(fe); +} + + +double SAL_CALL rtl_math_log1p( double fValue ) SAL_THROW_EXTERN_C() +{ + double fp = 1.0 + fValue; + if (fp == 1.0) + return fValue; + else + return log(fp) * fValue / (fp-1.0); +} diff --git a/sal/util/sal.map b/sal/util/sal.map index 7173eac26..6104625d1 100755 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -575,6 +575,12 @@ UDK_3.8 { # OOo 3.0 rtl_math_approxValue; } UDK_3.7; +UDK_3.9 { # OOo 3.1 + global: + rtl_math_expm1; + rtl_math_log1p; +} UDK_3.8; + PRIVATE_1.0 { global: osl_detail_ObjectRegistry_storeAddresses; |