summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sal/inc/rtl/math.h18
-rw-r--r--sal/inc/rtl/math.hxx14
-rw-r--r--sal/rtl/source/math.cxx21
-rwxr-xr-xsal/util/sal.map6
4 files changed, 59 insertions, 0 deletions
diff --git a/sal/inc/rtl/math.h b/sal/inc/rtl/math.h
index 96e2a02045b5..12cf825da464 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 5161294ad8b5..7dd7282449f6 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 91317d221ad5..c3b7147fb606 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 7173eac26bfa..6104625d1081 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;