summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorPedro Giffuni <pfg@apache.org>2013-02-08 15:31:55 +0000
committerPedro Giffuni <pfg@apache.org>2013-02-08 15:31:55 +0000
commit908088f614cda46d9c996e40579611df27276394 (patch)
tree5fadf95c1d1cb99eb421d90ea5d5ed4e5494159b /sal
parent94763a569193246d24935fb28f0cf10bffcea2b4 (diff)
i114430 - AOO Calc: 0^0=1 and it should be indeterminate.
Many spreadsheets and math packages set the value of POWER( 0, 0) to 1 as that sometimes is required for some calculations. This is also done by the standard C99 libc pow() function. In mathematical terms the value is an indeterminate form and in strict mathematical sense such value should at least be considered with caution. OpenFormula permits implementation defined values of 0, 1 or error in this case. We shall now return NaN. Clean some headers while here.
Notes
Notes: reject: 0^0=1 back-compat.
Diffstat (limited to 'sal')
-rw-r--r--sal/inc/rtl/math.h15
-rw-r--r--sal/inc/rtl/math.hxx7
-rw-r--r--sal/rtl/source/math.cxx13
-rw-r--r--sal/util/sal.map4
4 files changed, 38 insertions, 1 deletions
diff --git a/sal/inc/rtl/math.h b/sal/inc/rtl/math.h
index 11696258bd07..12441559e748 100644
--- a/sal/inc/rtl/math.h
+++ b/sal/inc/rtl/math.h
@@ -396,6 +396,21 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
*/
double SAL_CALL rtl_math_pow10Exp(double fValue, int nExp) SAL_THROW_EXTERN_C();
+/** Similar to pow() with stricter exception handling for indeterminate values.
+
+ powr is part of the IEEE 754 2008 Floating Point Standard.
+
+ @param fValue
+ The value to be raised.
+
+ @param fExp
+ The exponent.
+
+ @return
+ powr(fValue, fExp)
+ */
+double SAL_CALL rtl_math_powr(double fValue, double fExp) SAL_THROW_EXTERN_C();
+
/** Rounds value to 15 significant decimal digits.
@param fValue
diff --git a/sal/inc/rtl/math.hxx b/sal/inc/rtl/math.hxx
index 30b9974c4701..37e33e9f028a 100644
--- a/sal/inc/rtl/math.hxx
+++ b/sal/inc/rtl/math.hxx
@@ -186,6 +186,13 @@ inline double pow10Exp(double fValue, int nExp)
return rtl_math_pow10Exp(fValue, nExp);
}
+/** A wrapper around rtl_math_powr.
+ */
+inline double powr(double fValue, int fExp)
+{
+ return rtl_math_powr(fValue, fExp);
+}
+
/** A wrapper around rtl_math_approxValue.
*/
inline double approxValue(double fValue)
diff --git a/sal/rtl/source/math.cxx b/sal/rtl/source/math.cxx
index f5eaa446ae7a..ae2b045920db 100644
--- a/sal/rtl/source/math.cxx
+++ b/sal/rtl/source/math.cxx
@@ -1113,6 +1113,19 @@ double SAL_CALL rtl_math_expm1( double fValue ) SAL_THROW_EXTERN_C()
return (fe-1.0) * fValue / log(fe);
}
+double SAL_CALL rtl_math_powr( double fValue, double fExp ) SAL_THROW_EXTERN_C()
+{
+ if ((fValue == 0.0 && fExp == 0.0) ||
+ (rtl::math::isInf( fExp ) && !rtl::math::isSignBitSet( fExp )) ||
+ (rtl::math::isInf( fValue ) && !rtl::math::isSignBitSet( fValue )))
+ {
+ double fResult;
+ ::rtl::math::setNan( &fResult );
+ return fResult;
+ }
+ return pow(fValue, fExp);
+}
+
double SAL_CALL rtl_math_log1p( double fValue ) SAL_THROW_EXTERN_C()
{
diff --git a/sal/util/sal.map b/sal/util/sal.map
index 5a86333fbab2..671ef49be104 100644
--- a/sal/util/sal.map
+++ b/sal/util/sal.map
@@ -625,10 +625,12 @@ UDK_3.11 { # AOO 3.4
osl_setThreadName;
} UDK_3.10;
-UDK_3.12 { # AOO 3.5
+UDK_3.12 { # AOO 4.0
global:
osl_loadAsciiModule;
osl_loadAsciiModuleRelative;
+
+ rtl_math_powr;
} UDK_3.11;
PRIVATE_1.0 {