Added GTX_ulp implementation of scalar functions (TODO: vector ones)

This commit is contained in:
Christophe Riccio 2011-05-04 10:32:44 +01:00
parent 58d2d282f2
commit cb455f49ce

View File

@ -7,13 +7,105 @@
// File : glm/gtx/ulp.inl
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <cmath>
#include <iostream>
#if(GLM_COMPILER & GLM_COMPILER_VC)
# include <cfloat>
# define GLM_NEXT_AFTER _nextafterf
#else
# include <cmath>
# define GLM_NEXT_AFTER nextafterf
#endif
namespace glm{
namespace gtx{
namespace ulp
{
GLM_FUNC_QUALIFIER float next_float(float const & x)
{
return GLM_NEXT_AFTER(x, std::numeric_limits<float>::max());
}
GLM_FUNC_QUALIFIER double next_float(double const & x)
{
return GLM_NEXT_AFTER(x, std::numeric_limits<double>::max());
}
template<typename T, template<typename> class vecType>
GLM_FUNC_QUALIFIER vecType<T> next_float(vecType<T> const & x)
{
vecType<T> Result;
for(std::size_t i = 0; i < Result.length(); ++i)
Result[i] = next_float(x[i]);
return Result;
}
GLM_FUNC_QUALIFIER float prev_float(float const & x)
{
return GLM_NEXT_AFTER(x, std::numeric_limits<float>::min());
}
GLM_FUNC_QUALIFIER double prev_float(double const & x)
{
return GLM_NEXT_AFTER(x, std::numeric_limits<double>::min());
}
template<typename T, template<typename> class vecType>
GLM_FUNC_QUALIFIER vecType<T> prev_float(vecType<T> const & x)
{
vecType<T> Result;
for(std::size_t i = 0; i < Result.length(); ++i)
Result[i] = prev_float(x[i]);
return Result;
}
template <typename T>
GLM_FUNC_QUALIFIER T next_float(T const & x, std::size_t const & ulps)
{
T temp = x;
for(std::size_t i = 0; i < ulps; ++i)
temp = next_float(temp);
return temp;
}
template <typename T>
GLM_FUNC_QUALIFIER T prev_float(T const & x, std::size_t const & ulps)
{
T temp = x;
for(std::size_t i = 0; i < ulps; ++i)
temp = prev_float(temp);
return temp;
}
template <typename T>
GLM_FUNC_QUALIFIER std::size_t float_distance(T const & x, T const & y)
{
std::size_t ulp = 0;
if(x < y)
{
T temp = x;
while(temp != y && ulp < std::numeric_limits<std::size_t>::max())
{
++ulp;
temp = next_float(temp);
}
}
else if(y < x)
{
T temp = y;
while(temp != x && ulp < std::numeric_limits<std::size_t>::max())
{
++ulp;
temp = next_float(temp);
}
}
else // ==
{
}
return ulp;
}
inline std::size_t ulp
(
detail::thalf const & a,