diff --git a/glm/gtx/ulp.inl b/glm/gtx/ulp.inl index b99e8c49..dbd85a35 100644 --- a/glm/gtx/ulp.inl +++ b/glm/gtx/ulp.inl @@ -7,13 +7,105 @@ // File : glm/gtx/ulp.inl /////////////////////////////////////////////////////////////////////////////////////////////////// -#include -#include +#if(GLM_COMPILER & GLM_COMPILER_VC) +# include +# define GLM_NEXT_AFTER _nextafterf +#else +# include +# 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::max()); + } + + GLM_FUNC_QUALIFIER double next_float(double const & x) + { + return GLM_NEXT_AFTER(x, std::numeric_limits::max()); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType next_float(vecType const & x) + { + vecType 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::min()); + } + + GLM_FUNC_QUALIFIER double prev_float(double const & x) + { + return GLM_NEXT_AFTER(x, std::numeric_limits::min()); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType prev_float(vecType const & x) + { + vecType Result; + for(std::size_t i = 0; i < Result.length(); ++i) + Result[i] = prev_float(x[i]); + return Result; + } + + template + 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 + 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 + 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::max()) + { + ++ulp; + temp = next_float(temp); + } + } + else if(y < x) + { + T temp = y; + while(temp != x && ulp < std::numeric_limits::max()) + { + ++ulp; + temp = next_float(temp); + } + } + else // == + { + + } + + return ulp; + } + inline std::size_t ulp ( detail::thalf const & a,