|  |  |  | @ -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, | 
			
		
	
	
		
			
				
					|  |  |  | 
 |