diff --git a/glm/gtx/ulp.inl b/glm/gtx/ulp.inl index 3f8cbedb..e86c44ce 100644 --- a/glm/gtx/ulp.inl +++ b/glm/gtx/ulp.inl @@ -7,12 +7,19 @@ // File : glm/gtx/ulp.inl /////////////////////////////////////////////////////////////////////////////////////////////////// +#include +#include + #if(GLM_COMPILER & GLM_COMPILER_VC) -# include -# define GLM_NEXT_AFTER _nextafterf +# if(GLM_MODEL == GLM_MODEL_32) +# define GLM_NEXT_AFTER_FLT(x, toward) (float)_nextafter(x, float(toward)) +# else +# define GLM_NEXT_AFTER_FLT(x, toward) _nextafterf(x, toward) +# endif +# define GLM_NEXT_AFTER_DBL(x, toward) _nextafter(x, toward) #else -# include -# define GLM_NEXT_AFTER nextafterf +# define GLM_NEXT_AFTER_FLT(x, toward) nextafterf(x, toward) +# define GLM_NEXT_AFTER_DBL(x, toward) nextafter(x, toward) #endif namespace glm{ @@ -21,12 +28,12 @@ namespace ulp { GLM_FUNC_QUALIFIER float next_float(float const & x) { - return GLM_NEXT_AFTER(x, std::numeric_limits::max()); + return GLM_NEXT_AFTER_FLT(x, std::numeric_limits::max()); } GLM_FUNC_QUALIFIER double next_float(double const & x) { - return GLM_NEXT_AFTER(x, std::numeric_limits::max()); + return GLM_NEXT_AFTER_DBL(x, std::numeric_limits::max()); } template class vecType> @@ -40,12 +47,12 @@ namespace ulp GLM_FUNC_QUALIFIER float prev_float(float const & x) { - return GLM_NEXT_AFTER(x, std::numeric_limits::min()); + return GLM_NEXT_AFTER_FLT(x, std::numeric_limits::min()); } GLM_FUNC_QUALIFIER double prev_float(double const & x) { - return GLM_NEXT_AFTER(x, std::numeric_limits::min()); + return GLM_NEXT_AFTER_DBL(x, std::numeric_limits::min()); } template class vecType> diff --git a/test/gtx/gtx-ulp.cpp b/test/gtx/gtx-ulp.cpp index 54512d5c..348a09ce 100644 --- a/test/gtx/gtx-ulp.cpp +++ b/test/gtx/gtx-ulp.cpp @@ -12,124 +12,41 @@ #include #include -namespace -{ - template - T next_float(T const & x); - -#if(GLM_COMPILER & GLM_COMPILER_VC) -# include -# define GLM_NEXT_AFTER _nextafterf -#else -# include -# define GLM_NEXT_AFTER nextafterf -#endif - - 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()); - } - - 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 - 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; - } -}//namespace - int test_ulp_float() { std::cout.precision(std::numeric_limits::digits10 + 1); float W = 1.0f; - float X = next_float(W); + float X = glm::next_float(W); double Y = 1.0; - double Z = next_float(Y); + double Z = glm::next_float(Y); bool TestX = W != X; bool TestZ = Y != Z; - std::cout << "1.0f, Next: " << float_distance(W, X)<< std::endl; - std::cout << "1.0f, Next(1000): " << float_distance(W, next_float(W, 1000)) << std::endl; + std::cout << "1.0f, Next: " << glm::float_distance(W, X)<< std::endl; + std::cout << "1.0f, Next(1000): " << glm::float_distance(W, glm::next_float(W, 1000)) << std::endl; - std::cout << "1.0f, Next: " << float_distance(X, W)<< std::endl; - std::cout << "1.0f, Next(1000): " << float_distance(next_float(W, 1000), W) << std::endl; + std::cout << "1.0f, Next: " << glm::float_distance(X, W)<< std::endl; + std::cout << "1.0f, Next(1000): " << glm::float_distance(glm::next_float(W, 1000), W) << std::endl; - std::cout << "1.0, Next: " << float_distance(Y, Z) << std::endl; - std::cout << "1.0, Next(1000): " << float_distance(next_float(Y, 1000), Y) << std::endl; + std::cout << "1.0, Next: " << glm::float_distance(Y, Z) << std::endl; + std::cout << "1.0, Next(1000): " << glm::float_distance(glm::next_float(Y, 1000), Y) << std::endl; std::cout << Z << " 0.01, 0.011" << std::endl; - std::cout << " 1.0, Next(1000000): " << next_float(Y, 1000000)<< std::endl; + std::cout << " 1.0, Next(1000000): " << glm::next_float(Y, 1000000)<< std::endl; - std::size_t A = glm::ulp(0.01, 0.02); - std::size_t B = glm::ulp(glm::vec2(0.01), glm::vec2(0.02)); - std::size_t C = glm::ulp(glm::vec3(0.01), glm::vec3(0.02)); - std::size_t D = glm::ulp(glm::vec4(0.01), glm::vec4(0.02)); - std::cout << "glm::ulp test: " << A << std::endl; - std::cout << "glm::ulp test: " << B << std::endl; - std::cout << "glm::ulp test: " << C << std::endl; - std::cout << "glm::ulp test: " << D << std::endl; + //std::size_t A = glm::ulp(0.01, 0.02); + //std::size_t B = glm::ulp(glm::vec2(0.01), glm::vec2(0.02)); + //std::size_t C = glm::ulp(glm::vec3(0.01), glm::vec3(0.02)); + //std::size_t D = glm::ulp(glm::vec4(0.01), glm::vec4(0.02)); + //std::cout << "glm::ulp test: " << A << std::endl; + //std::cout << "glm::ulp test: " << B << std::endl; + //std::cout << "glm::ulp test: " << C << std::endl; + //std::cout << "glm::ulp test: " << D << std::endl; return 0; }