Use std::exp2 to implement glm::exp2 when available

Using std::exp and then a multiplication looses a lot of precision which
can cause hard to find bugs (who would expect exp2 to fail?) because all
powers of two with integer exponents can be expressed precisely
with ieee754 floating point.

This also should be good for performance, since exp2 with
integer exponent is just shifting some bits in ieee754 and
good implementers will probably leverage that to implement exp2
efficiently.
This commit is contained in:
Kai Dietrich 2017-10-26 09:43:47 +02:00
parent 708a886bb0
commit c79dfbc925

View File

@ -90,6 +90,9 @@ namespace detail
return detail::functor1<L, T, T, Q>::call(log, x); return detail::functor1<L, T, T, Q>::call(log, x);
} }
# if GLM_HAS_CXX11_STL
using std::exp2;
# else
//exp2, ln2 = 0.69314718055994530941723212145818f //exp2, ln2 = 0.69314718055994530941723212145818f
template<typename genType> template<typename genType>
GLM_FUNC_QUALIFIER genType exp2(genType x) GLM_FUNC_QUALIFIER genType exp2(genType x)
@ -98,6 +101,7 @@ namespace detail
return std::exp(static_cast<genType>(0.69314718055994530941723212145818) * x); return std::exp(static_cast<genType>(0.69314718055994530941723212145818) * x);
} }
# endif
template<length_t L, typename T, qualifier Q> template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> exp2(vec<L, T, Q> const& x) GLM_FUNC_QUALIFIER vec<L, T, Q> exp2(vec<L, T, Q> const& x)