implement Inf and NaN handling for rtl_math_expm1() and rtl_math_log1p()

Change-Id: Ie424a6f038107ef8b574d0422efaf49b441c110f
diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx
index 37225f4..3ec6fe0 100644
--- a/sal/rtl/math.cxx
+++ b/sal/rtl/math.cxx
@@ -1096,6 +1096,24 @@ double SAL_CALL rtl_math_approxValue( double fValue ) SAL_THROW_EXTERN_C()

double SAL_CALL rtl_math_expm1( double fValue ) SAL_THROW_EXTERN_C()
{
    // See http://en.cppreference.com/w/cpp/numeric/math/expm1

    if (fValue == 0.0)
        return fValue;

    if (!::rtl::math::isFinite(fValue))
    {
        if (::rtl::math::isInf(fValue))
        {
            if (::rtl::math::isSignBitSet(fValue))
                return -1.0;
            else
                return fValue;
        }
        // It is a NaN.
        return fValue;
    }

    double fe = exp( fValue );
    if (fe == 1.0)
        return fValue;
@@ -1106,6 +1124,31 @@ double SAL_CALL rtl_math_expm1( double fValue ) SAL_THROW_EXTERN_C()

double SAL_CALL rtl_math_log1p( double fValue ) SAL_THROW_EXTERN_C()
{
    // See http://en.cppreference.com/w/cpp/numeric/math/log1p

    if (fValue == 0.0)
        return fValue;

    if (fValue == -1.0)
    {
        rtl::math::setInf( &fValue, true);
        return fValue;
    }

    if (fValue < -1.0)  // includes -Inf
    {
        rtl::math::setNan( &fValue);
        return fValue;
    }

    if (!::rtl::math::isFinite(fValue))
    {
        if (::rtl::math::isInf(fValue))
            return fValue;
        // It is a NaN.
        return fValue;
    }

    // Use volatile because a compiler may be too smart "optimizing" the
    // condition such that in certain cases the else path was called even if
    // (fp==1.0) was true, where the term (fp-1.0) then resulted in 0.0 and