Kaydet (Commit) 908088f6 authored tarafından Pedro Giffuni's avatar Pedro Giffuni

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.
üst 94763a56
...@@ -396,6 +396,21 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces, ...@@ -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(); 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. /** Rounds value to 15 significant decimal digits.
@param fValue @param fValue
......
...@@ -186,6 +186,13 @@ inline double pow10Exp(double fValue, int nExp) ...@@ -186,6 +186,13 @@ inline double pow10Exp(double fValue, int nExp)
return rtl_math_pow10Exp(fValue, 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. /** A wrapper around rtl_math_approxValue.
*/ */
inline double approxValue(double fValue) inline double approxValue(double fValue)
......
...@@ -1113,6 +1113,19 @@ double SAL_CALL rtl_math_expm1( double fValue ) SAL_THROW_EXTERN_C() ...@@ -1113,6 +1113,19 @@ double SAL_CALL rtl_math_expm1( double fValue ) SAL_THROW_EXTERN_C()
return (fe-1.0) * fValue / log(fe); 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() double SAL_CALL rtl_math_log1p( double fValue ) SAL_THROW_EXTERN_C()
{ {
......
...@@ -625,10 +625,12 @@ UDK_3.11 { # AOO 3.4 ...@@ -625,10 +625,12 @@ UDK_3.11 { # AOO 3.4
osl_setThreadName; osl_setThreadName;
} UDK_3.10; } UDK_3.10;
UDK_3.12 { # AOO 3.5 UDK_3.12 { # AOO 4.0
global: global:
osl_loadAsciiModule; osl_loadAsciiModule;
osl_loadAsciiModuleRelative; osl_loadAsciiModuleRelative;
rtl_math_powr;
} UDK_3.11; } UDK_3.11;
PRIVATE_1.0 { PRIVATE_1.0 {
......
...@@ -609,13 +609,6 @@ void ScGetDate(); ...@@ -609,13 +609,6 @@ void ScGetDate();
void ScGetTime(); void ScGetTime();
void ScGetDiffDate(); void ScGetDiffDate();
void ScGetDiffDate360(); void ScGetDiffDate360();
void ScPower();
void ScAmpersand();
void ScAdd();
void ScSub();
void ScMul();
void ScDiv();
void ScPow();
void ScCurrent(); void ScCurrent();
void ScStyle(); void ScStyle();
void ScDde(); void ScDde();
...@@ -669,6 +662,13 @@ void ScIntercept(); ...@@ -669,6 +662,13 @@ void ScIntercept();
double ScGetGCD(double fx, double fy); double ScGetGCD(double fx, double fy);
void ScGCD(); void ScGCD();
void ScLCM(); void ScLCM();
void ScPower();
void ScAmpersand();
void ScAdd();
void ScSub();
void ScMul();
void ScDiv();
void ScPow();
//-------------------------- Matrixfunktionen --------------------------------- //-------------------------- Matrixfunktionen ---------------------------------
void ScMatValue(); void ScMatValue();
......
...@@ -1611,14 +1611,14 @@ void ScInterpreter::ScPow() ...@@ -1611,14 +1611,14 @@ void ScInterpreter::ScPow()
if (bFlag) if (bFlag)
{ for ( SCSIZE i = 0; i < nCount; i++ ) { for ( SCSIZE i = 0; i < nCount; i++ )
if (pMat->IsValue(i)) if (pMat->IsValue(i))
pResMat->PutDouble(pow(fVal,pMat->GetDouble(i)), i); pResMat->PutDouble(::rtl::math::powr(fVal,pMat->GetDouble(i)), i);
else else
pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
} }
else else
{ for ( SCSIZE i = 0; i < nCount; i++ ) { for ( SCSIZE i = 0; i < nCount; i++ )
if (pMat->IsValue(i)) if (pMat->IsValue(i))
pResMat->PutDouble(pow(pMat->GetDouble(i),fVal), i); pResMat->PutDouble(::rtl::math::powr(pMat->GetDouble(i),fVal), i);
else else
pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
} }
...@@ -1628,7 +1628,7 @@ void ScInterpreter::ScPow() ...@@ -1628,7 +1628,7 @@ void ScInterpreter::ScPow()
PushIllegalArgument(); PushIllegalArgument();
} }
else else
PushDouble(pow(fVal1,fVal2)); PushDouble(::rtl::math::powr(fVal1,fVal2));
} }
void ScInterpreter::ScSumProduct() void ScInterpreter::ScSumProduct()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment