diff options
author | Gael Guennebaud <g.gael@free.fr> | 2014-10-20 11:38:51 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2014-10-20 11:38:51 +0200 |
commit | aa5f79206fb632d141c3555338f89f59d1bb4633 (patch) | |
tree | a16506f4dcb277c129301dac1a8408cba1136a1d | |
parent | b4a9b3f4960657bf2fc156ba5c25a3a32417b861 (diff) |
Fix bug #859: pexp(NaN) returned Inf instead of NaN
-rw-r--r-- | Eigen/src/Core/arch/SSE/MathFunctions.h | 2 | ||||
-rw-r--r-- | test/main.h | 20 | ||||
-rw-r--r-- | test/packetmath.cpp | 6 | ||||
-rw-r--r-- | test/stable_norm.cpp | 20 |
4 files changed, 27 insertions, 21 deletions
diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h index 8f78b3a6c..b549e4870 100644 --- a/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -167,7 +167,7 @@ Packet4f pexp<Packet4f>(const Packet4f& _x) emm0 = _mm_cvttps_epi32(fx); emm0 = _mm_add_epi32(emm0, p4i_0x7f); emm0 = _mm_slli_epi32(emm0, 23); - return pmul(y, Packet4f(_mm_castsi128_ps(emm0))); + return pmax(pmul(y, Packet4f(_mm_castsi128_ps(emm0))), _x); } template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet2d pexp<Packet2d>(const Packet2d& _x) diff --git a/test/main.h b/test/main.h index 371c7e602..adf4adb31 100644 --- a/test/main.h +++ b/test/main.h @@ -432,6 +432,26 @@ void randomPermutationVector(PermutationVectorType& v, typename PermutationVecto } } +template<typename T> bool isNotNaN(const T& x) +{ + return x==x; +} + +template<typename T> bool isNaN(const T& x) +{ + return x!=x; +} + +template<typename T> bool isInf(const T& x) +{ + return x > NumTraits<T>::highest(); +} + +template<typename T> bool isMinusInf(const T& x) +{ + return x < NumTraits<T>::lowest(); +} + } // end namespace Eigen template<typename T> struct GetDifferentType; diff --git a/test/packetmath.cpp b/test/packetmath.cpp index e716d6d9a..a4166d868 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -297,6 +297,12 @@ template<typename Scalar> void packetmath_real() data2[i] = internal::random<Scalar>(-87,88); } CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasExp, std::exp, internal::pexp); + { + data1[0] = std::numeric_limits<Scalar>::quiet_NaN(); + packet_helper<internal::packet_traits<Scalar>::HasExp,Packet> h; + h.store(data2, internal::pexp(h.load(data1))); + VERIFY(isNaN(data2[0])); + } for (int i=0; i<size; ++i) { diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp index 6cd65c64a..650f62a8a 100644 --- a/test/stable_norm.cpp +++ b/test/stable_norm.cpp @@ -9,26 +9,6 @@ #include "main.h" -template<typename T> bool isNotNaN(const T& x) -{ - return x==x; -} - -template<typename T> bool isNaN(const T& x) -{ - return x!=x; -} - -template<typename T> bool isInf(const T& x) -{ - return x > NumTraits<T>::highest(); -} - -template<typename T> bool isMinusInf(const T& x) -{ - return x < NumTraits<T>::lowest(); -} - // workaround aggressive optimization in ICC template<typename T> EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; } |