summaryrefslogtreecommitdiff
path: root/sal/rtl/math.cxx
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-10-24 22:04:28 +0200
committerEike Rathke <erack@redhat.com>2015-10-24 22:07:08 +0200
commit04967cba8e71e178915068e237a96e32a8cb3e9e (patch)
tree31349c23ec5d146108a1485f335eb0cc4084846c /sal/rtl/math.cxx
parent9846b6ab3d36c8b2696e8829c121016f9fa81e66 (diff)
implement Inf and NaN handling for rtl_math_expm1() and rtl_math_log1p()
Change-Id: Ie424a6f038107ef8b574d0422efaf49b441c110f
Diffstat (limited to 'sal/rtl/math.cxx')
-rw-r--r--sal/rtl/math.cxx43
1 files changed, 43 insertions, 0 deletions
diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx
index 37225f4c7b46..3ec6fe0d489d 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