commit
						f433049bca
					
				
				 5 changed files with 582 additions and 0 deletions
			
			
		@ -0,0 +1,73 @@ | 
				
			|||||||
 | 
					///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Created : 2011-02-21
 | 
				
			||||||
 | 
					// Updated : 2009-02-21
 | 
				
			||||||
 | 
					// Licence : This source is under MIT License
 | 
				
			||||||
 | 
					// File    : glm/gtx/ulp.hpp
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Dependency:
 | 
				
			||||||
 | 
					// - GLM core
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef glm_gtx_ulp | 
				
			||||||
 | 
					#define glm_gtx_ulp | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Dependency:
 | 
				
			||||||
 | 
					#include "../glm.hpp" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if(defined(GLM_MESSAGES) && !defined(glm_ext)) | 
				
			||||||
 | 
					#	pragma message("GLM: GLM_GTX_ulp extension included") | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace glm | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						namespace gtx{ | 
				
			||||||
 | 
						//! GLM_GTX_ulp extension: Precision calculation functions
 | 
				
			||||||
 | 
						namespace ulp | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							/// \addtogroup gtx_ulp
 | 
				
			||||||
 | 
							///@{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//! Return the next ULP value(s) after the input value(s).
 | 
				
			||||||
 | 
							//! From GLM_GTX_ulp extension.
 | 
				
			||||||
 | 
					        template <typename genType> | 
				
			||||||
 | 
					        genType next_float(genType const & x); | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
							//! Return the previous ULP value(s) before the input value(s).
 | 
				
			||||||
 | 
							//! From GLM_GTX_ulp extension.
 | 
				
			||||||
 | 
					        template <typename genType> | 
				
			||||||
 | 
					        genType prev_float(genType const & x); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//! Return the value(s) ULP distance after the input value(s).
 | 
				
			||||||
 | 
							//! From GLM_GTX_ulp extension.
 | 
				
			||||||
 | 
					        template <typename genType> | 
				
			||||||
 | 
					        genType next_float(genType const & x, uint const & Distance); | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        //! Return the value(s) ULP distance before the input value(s).
 | 
				
			||||||
 | 
							//! From GLM_GTX_ulp extension.
 | 
				
			||||||
 | 
					        template <typename genType> | 
				
			||||||
 | 
					        genType prev_float(genType const & x, uint const & Distance); | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        //! Return the distance in the number of ULP between 2 scalars.
 | 
				
			||||||
 | 
							//! From GLM_GTX_ulp extension.
 | 
				
			||||||
 | 
					        template <typename T> | 
				
			||||||
 | 
					        uint float_distance(T const & x, T const & y); | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        //! Return the distance in the number of ULP between 2 vectors.
 | 
				
			||||||
 | 
							//! From GLM_GTX_ulp extension.
 | 
				
			||||||
 | 
					        template<typename T, template<typename> class vecType> | 
				
			||||||
 | 
					        vecType<uint> float_distance(vecType<T> const & x, vecType<T> const & y); | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
							///@}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}//namespace ulp
 | 
				
			||||||
 | 
						}//namespace gtx
 | 
				
			||||||
 | 
					}//namespace glm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ulp.inl" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace glm{using namespace gtx::ulp;} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif//glm_gtx_ulp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,400 @@ | 
				
			|||||||
 | 
					/////////////////////////////////////////////////////////////////////////////////////////////////// | 
				
			||||||
 | 
					// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net) | 
				
			||||||
 | 
					/////////////////////////////////////////////////////////////////////////////////////////////////// | 
				
			||||||
 | 
					// Created : 2011-03-07 | 
				
			||||||
 | 
					// Updated : 2011-04-26 | 
				
			||||||
 | 
					// Licence : This source is under MIT License | 
				
			||||||
 | 
					// File    : glm/gtx/ulp.inl | 
				
			||||||
 | 
					/////////////////////////////////////////////////////////////////////////////////////////////////// | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cmath> | 
				
			||||||
 | 
					#include <cfloat> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* | 
				
			||||||
 | 
					 * ==================================================== | 
				
			||||||
 | 
					 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * Developed at SunPro, a Sun Microsystems, Inc. business. | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this | 
				
			||||||
 | 
					 * software is freely granted, provided that this notice | 
				
			||||||
 | 
					 * is preserved. | 
				
			||||||
 | 
					 * ==================================================== | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef union | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						float value; | 
				
			||||||
 | 
						/* FIXME: Assumes 32 bit int.  */ | 
				
			||||||
 | 
						unsigned int word; | 
				
			||||||
 | 
					} ieee_float_shape_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef union | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						double value; | 
				
			||||||
 | 
						struct | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							glm::detail::int32 lsw; | 
				
			||||||
 | 
							glm::detail::int32 msw; | 
				
			||||||
 | 
						} parts; | 
				
			||||||
 | 
					} ieee_double_shape_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GLM_EXTRACT_WORDS(ix0,ix1,d)                                \ | 
				
			||||||
 | 
					do {                                                            \ | 
				
			||||||
 | 
					  ieee_double_shape_type ew_u;                                  \ | 
				
			||||||
 | 
					  ew_u.value = (d);                                             \ | 
				
			||||||
 | 
					  (ix0) = ew_u.parts.msw;                                       \ | 
				
			||||||
 | 
					  (ix1) = ew_u.parts.lsw;                                       \ | 
				
			||||||
 | 
					} while (0) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GLM_GET_FLOAT_WORD(i,d)                                     \ | 
				
			||||||
 | 
					do {                                                            \ | 
				
			||||||
 | 
					  ieee_float_shape_type gf_u;                                   \ | 
				
			||||||
 | 
					  gf_u.value = (d);                                             \ | 
				
			||||||
 | 
					  (i) = gf_u.word;                                              \ | 
				
			||||||
 | 
					} while (0) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GLM_SET_FLOAT_WORD(d,i)                                     \ | 
				
			||||||
 | 
					do {                                                            \ | 
				
			||||||
 | 
					  ieee_float_shape_type sf_u;                                   \ | 
				
			||||||
 | 
					  sf_u.word = (i);                                              \ | 
				
			||||||
 | 
					  (d) = sf_u.value;                                             \ | 
				
			||||||
 | 
					} while (0) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GLM_INSERT_WORDS(d,ix0,ix1)                                 \ | 
				
			||||||
 | 
					do {                                                            \ | 
				
			||||||
 | 
					  ieee_double_shape_type iw_u;                                  \ | 
				
			||||||
 | 
					  iw_u.parts.msw = (ix0);                                       \ | 
				
			||||||
 | 
					  iw_u.parts.lsw = (ix1);                                       \ | 
				
			||||||
 | 
					  (d) = iw_u.value;                                             \ | 
				
			||||||
 | 
					} while (0) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace glm{ | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						GLM_FUNC_QUALIFIER float nextafterf(float x, float y) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							volatile float t; | 
				
			||||||
 | 
							glm::detail::int32 hx, hy, ix, iy; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							GLM_GET_FLOAT_WORD(hx,x); | 
				
			||||||
 | 
							GLM_GET_FLOAT_WORD(hy,y); | 
				
			||||||
 | 
							ix = hx&0x7fffffff;             // |x| | 
				
			||||||
 | 
							iy = hy&0x7fffffff;             // |y| | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if((ix>0x7f800000) ||   // x is nan  | 
				
			||||||
 | 
								(iy>0x7f800000))     // y is nan  | 
				
			||||||
 | 
								return x+y; | 
				
			||||||
 | 
							if(x==y) return y;              // x=y, return y | 
				
			||||||
 | 
							if(ix==0) {                             // x == 0 | 
				
			||||||
 | 
								GLM_SET_FLOAT_WORD(x,(hy&0x80000000)|1);// return +-minsubnormal | 
				
			||||||
 | 
								t = x*x; | 
				
			||||||
 | 
								if(t==x) return t; else return x;   // raise underflow flag | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							if(hx>=0) {                             // x > 0  | 
				
			||||||
 | 
								if(hx>hy) {                         // x > y, x -= ulp | 
				
			||||||
 | 
									hx -= 1; | 
				
			||||||
 | 
								} else {                            // x < y, x += ulp | 
				
			||||||
 | 
									hx += 1; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} else {                                // x < 0 | 
				
			||||||
 | 
								if(hy>=0||hx>hy){                   // x < y, x -= ulp | 
				
			||||||
 | 
									hx -= 1; | 
				
			||||||
 | 
								} else {                            // x > y, x += ulp | 
				
			||||||
 | 
									hx += 1; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							hy = hx&0x7f800000; | 
				
			||||||
 | 
							if(hy>=0x7f800000) return x+x;  // overflow | 
				
			||||||
 | 
							if(hy<0x00800000) {             // underflow | 
				
			||||||
 | 
								t = x*x; | 
				
			||||||
 | 
								if(t!=x) {          // raise underflow flag | 
				
			||||||
 | 
									GLM_SET_FLOAT_WORD(y,hx); | 
				
			||||||
 | 
									return y; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							GLM_SET_FLOAT_WORD(x,hx); | 
				
			||||||
 | 
							return x; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GLM_FUNC_QUALIFIER double nextafter(double x, double y) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							volatile double t; | 
				
			||||||
 | 
							glm::detail::int32 hx, hy, ix, iy; | 
				
			||||||
 | 
							glm::detail::uint32 lx, ly; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							GLM_EXTRACT_WORDS(hx, lx, x); | 
				
			||||||
 | 
							GLM_EXTRACT_WORDS(hy, ly, y); | 
				
			||||||
 | 
							ix = hx & 0x7fffffff;             // |x|  | 
				
			||||||
 | 
							iy = hy & 0x7fffffff;             // |y|  | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   // x is nan | 
				
			||||||
 | 
								((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     // y is nan | 
				
			||||||
 | 
								return x+y; | 
				
			||||||
 | 
							if(x==y) return y;              // x=y, return y | 
				
			||||||
 | 
							if((ix|lx)==0) {                        // x == 0  | 
				
			||||||
 | 
								GLM_INSERT_WORDS(x, hy & 0x80000000, 1);    // return +-minsubnormal | 
				
			||||||
 | 
								t = x*x; | 
				
			||||||
 | 
								if(t==x) return t; else return x;   // raise underflow flag  | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							if(hx>=0) {                             // x > 0  | 
				
			||||||
 | 
								if(hx>hy||((hx==hy)&&(lx>ly))) {    // x > y, x -= ulp  | 
				
			||||||
 | 
									if(lx==0) hx -= 1; | 
				
			||||||
 | 
									lx -= 1; | 
				
			||||||
 | 
								} else {                            // x < y, x += ulp | 
				
			||||||
 | 
									lx += 1; | 
				
			||||||
 | 
									if(lx==0) hx += 1; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} else {                                // x < 0  | 
				
			||||||
 | 
								if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){// x < y, x -= ulp | 
				
			||||||
 | 
									if(lx==0) hx -= 1; | 
				
			||||||
 | 
									lx -= 1; | 
				
			||||||
 | 
								} else {                            // x > y, x += ulp | 
				
			||||||
 | 
									lx += 1; | 
				
			||||||
 | 
									if(lx==0) hx += 1; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							hy = hx&0x7ff00000; | 
				
			||||||
 | 
							if(hy>=0x7ff00000) return x+x;  // overflow | 
				
			||||||
 | 
							if(hy<0x00100000) {             // underflow | 
				
			||||||
 | 
								t = x*x; | 
				
			||||||
 | 
								if(t!=x) {          // raise underflow flag | 
				
			||||||
 | 
									GLM_INSERT_WORDS(y,hx,lx); | 
				
			||||||
 | 
									return y; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							GLM_INSERT_WORDS(x,hx,lx); | 
				
			||||||
 | 
							return x; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					}//namespace detail | 
				
			||||||
 | 
					}//namespace glm | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if(GLM_COMPILER & GLM_COMPILER_VC) | 
				
			||||||
 | 
					#	if(GLM_MODEL == GLM_MODEL_32) | 
				
			||||||
 | 
					#		define GLM_NEXT_AFTER_FLT(x, toward) glm::detail::nextafterf((x), (toward)) | 
				
			||||||
 | 
					#	else | 
				
			||||||
 | 
					#		define GLM_NEXT_AFTER_FLT(x, toward) _nextafterf((x), (toward)) | 
				
			||||||
 | 
					#	endif | 
				
			||||||
 | 
					#   define GLM_NEXT_AFTER_DBL(x, toward) _nextafter((x), (toward)) | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					#   define GLM_NEXT_AFTER_FLT(x, toward) nextafterf((x), (toward)) | 
				
			||||||
 | 
					#   define GLM_NEXT_AFTER_DBL(x, toward) nextafter((x), (toward)) | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace glm{ | 
				
			||||||
 | 
					namespace gtx{ | 
				
			||||||
 | 
					namespace ulp | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    GLM_FUNC_QUALIFIER float next_float(float const & x) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return GLM_NEXT_AFTER_FLT(x, std::numeric_limits<float>::max()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GLM_FUNC_QUALIFIER double next_float(double const & x) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return GLM_NEXT_AFTER_DBL(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_FLT(x, std::numeric_limits<float>::min()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GLM_FUNC_QUALIFIER double prev_float(double const & x) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return GLM_NEXT_AFTER_DBL(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, uint const & ulps) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        T temp = x; | 
				
			||||||
 | 
					        for(std::size_t i = 0; i < ulps; ++i) | 
				
			||||||
 | 
					            temp = next_float(temp); | 
				
			||||||
 | 
					        return temp; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename T, template<typename> class vecType> | 
				
			||||||
 | 
					    GLM_FUNC_QUALIFIER vecType<T> next_float(vecType<T> const & x, vecType<uint> const & ulps) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        vecType<T> Result; | 
				
			||||||
 | 
					        for(std::size_t i = 0; i < Result.length(); ++i) | 
				
			||||||
 | 
					            Result[i] = next_float(x[i], ulps[i]); | 
				
			||||||
 | 
					        return Result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template <typename T> | 
				
			||||||
 | 
					    GLM_FUNC_QUALIFIER T prev_float(T const & x, uint const & ulps) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        T temp = x; | 
				
			||||||
 | 
					        for(std::size_t i = 0; i < ulps; ++i) | 
				
			||||||
 | 
					            temp = prev_float(temp); | 
				
			||||||
 | 
					        return temp; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename T, template<typename> class vecType> | 
				
			||||||
 | 
					    GLM_FUNC_QUALIFIER vecType<T> prev_float(vecType<T> const & x, vecType<uint> const & ulps) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        vecType<T> Result; | 
				
			||||||
 | 
					        for(std::size_t i = 0; i < Result.length(); ++i) | 
				
			||||||
 | 
					            Result[i] = prev_float(x[i], ulps[i]); | 
				
			||||||
 | 
					        return Result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template <typename T> | 
				
			||||||
 | 
					    GLM_FUNC_QUALIFIER uint 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; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename T, template<typename> class vecType> | 
				
			||||||
 | 
					    GLM_FUNC_QUALIFIER vecType<uint> float_distance(vecType<T> const & x, vecType<T> const & y) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        vecType<uint> Result; | 
				
			||||||
 | 
					        for(std::size_t i = 0; i < Result.length(); ++i) | 
				
			||||||
 | 
					            Result[i] = float_distance(x[i], y[i]); | 
				
			||||||
 | 
					        return Result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					/* | 
				
			||||||
 | 
						inline std::size_t ulp | 
				
			||||||
 | 
						( | 
				
			||||||
 | 
							detail::thalf const & a, | 
				
			||||||
 | 
							detail::thalf const & b | 
				
			||||||
 | 
						) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							std::size_t Count = 0; | 
				
			||||||
 | 
							float TempA(a); | 
				
			||||||
 | 
							float TempB(b); | 
				
			||||||
 | 
							//while((TempA = _nextafterf(TempA, TempB)) != TempB) | 
				
			||||||
 | 
								++Count; | 
				
			||||||
 | 
							return Count; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inline std::size_t ulp | 
				
			||||||
 | 
						( | 
				
			||||||
 | 
							float const & a, | 
				
			||||||
 | 
							float const & b | 
				
			||||||
 | 
						) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							std::size_t Count = 0; | 
				
			||||||
 | 
							float Temp = a; | 
				
			||||||
 | 
							//while((Temp = _nextafterf(Temp, b)) != b) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            std::cout << Temp << " " << b << std::endl; | 
				
			||||||
 | 
								++Count; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
							return Count; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inline std::size_t ulp | 
				
			||||||
 | 
						( | 
				
			||||||
 | 
							double const & a, | 
				
			||||||
 | 
							double const & b | 
				
			||||||
 | 
						) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							std::size_t Count = 0; | 
				
			||||||
 | 
							double Temp = a; | 
				
			||||||
 | 
							//while((Temp = _nextafter(Temp, b)) != b) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            std::cout << Temp << " " << b << std::endl; | 
				
			||||||
 | 
								++Count; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
							return Count; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template <typename T> | 
				
			||||||
 | 
						inline std::size_t ulp | 
				
			||||||
 | 
						( | 
				
			||||||
 | 
							detail::tvec2<T> const & a, | 
				
			||||||
 | 
							detail::tvec2<T> const & b | 
				
			||||||
 | 
						) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
					        std::size_t ulps[] =  | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            ulp(a[0], b[0]), | 
				
			||||||
 | 
					            ulp(a[1], b[1]) | 
				
			||||||
 | 
					        }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return glm::max(ulps[0], ulps[1]); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template <typename T> | 
				
			||||||
 | 
						inline std::size_t ulp | 
				
			||||||
 | 
						( | 
				
			||||||
 | 
							detail::tvec3<T> const & a, | 
				
			||||||
 | 
							detail::tvec3<T> const & b | 
				
			||||||
 | 
						) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
					        std::size_t ulps[] =  | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            ulp(a[0], b[0]), | 
				
			||||||
 | 
					            ulp(a[1], b[1]), | 
				
			||||||
 | 
					            ulp(a[2], b[2]) | 
				
			||||||
 | 
					        }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return glm::max(glm::max(ulps[0], ulps[1]), ulps[2]); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template <typename T> | 
				
			||||||
 | 
						inline std::size_t ulp | 
				
			||||||
 | 
						( | 
				
			||||||
 | 
							detail::tvec4<T> const & a, | 
				
			||||||
 | 
							detail::tvec4<T> const & b | 
				
			||||||
 | 
						) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
					        std::size_t ulps[] =  | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            ulp(a[0], b[0]), | 
				
			||||||
 | 
					            ulp(a[1], b[1]), | 
				
			||||||
 | 
					            ulp(a[2], b[2]), | 
				
			||||||
 | 
					            ulp(a[3], b[3]) | 
				
			||||||
 | 
					        }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return glm::max(glm::max(ulps[0], ulps[1]), glm::max(ulps[2], ulps[3])); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					}//namespace ulp | 
				
			||||||
 | 
					}//namespace gtx | 
				
			||||||
 | 
					}//namespace glm | 
				
			||||||
@ -0,0 +1,107 @@ | 
				
			|||||||
 | 
					///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Created : 2011-04-26
 | 
				
			||||||
 | 
					// Updated : 2011-04-26
 | 
				
			||||||
 | 
					// Licence : This source is under MIT licence
 | 
				
			||||||
 | 
					// File    : test/gtx/ulp.cpp
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <glm/glm.hpp> | 
				
			||||||
 | 
					#include <glm/gtx/ulp.hpp> | 
				
			||||||
 | 
					#include <iostream> | 
				
			||||||
 | 
					#include <limits> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int test_ulp_float_dist() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						int Error = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						float A = 1.0f; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    float B = glm::next_float(A); | 
				
			||||||
 | 
						Error += A != B ? 0 : 1; | 
				
			||||||
 | 
						float C = glm::prev_float(B); | 
				
			||||||
 | 
						Error += A == C ? 0 : 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int D = glm::float_distance(A, B); | 
				
			||||||
 | 
						Error += D == 1 ? 0 : 1; | 
				
			||||||
 | 
						int E = glm::float_distance(A, C); | 
				
			||||||
 | 
						Error += E == 0 ? 0 : 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Error; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int test_ulp_float_step() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						int Error = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						float A = 1.0f; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for(int i = 10; i < 1000; i *= 10) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							float B = glm::next_float(A, i); | 
				
			||||||
 | 
							Error += A != B ? 0 : 1; | 
				
			||||||
 | 
							float C = glm::prev_float(B, i); | 
				
			||||||
 | 
							Error += A == C ? 0 : 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int D = glm::float_distance(A, B); | 
				
			||||||
 | 
							Error += D == i ? 0 : 1; | 
				
			||||||
 | 
							int E = glm::float_distance(A, C); | 
				
			||||||
 | 
							Error += E == 0 ? 0 : 1; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Error; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int test_ulp_double_dist() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						int Error = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						double A = 1.0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double B = glm::next_float(A); | 
				
			||||||
 | 
						Error += A != B ? 0 : 1; | 
				
			||||||
 | 
						double C = glm::prev_float(B); | 
				
			||||||
 | 
						Error += A == C ? 0 : 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int D = glm::float_distance(A, B); | 
				
			||||||
 | 
						Error += D == 1 ? 0 : 1; | 
				
			||||||
 | 
						int E = glm::float_distance(A, C); | 
				
			||||||
 | 
						Error += E == 0 ? 0 : 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Error; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int test_ulp_double_step() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						int Error = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						double A = 1.0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for(int i = 10; i < 1000; i *= 10) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							double B = glm::next_float(A, i); | 
				
			||||||
 | 
							Error += A != B ? 0 : 1; | 
				
			||||||
 | 
							double C = glm::prev_float(B, i); | 
				
			||||||
 | 
							Error += A == C ? 0 : 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int D = glm::float_distance(A, B); | 
				
			||||||
 | 
							Error += D == i ? 0 : 1; | 
				
			||||||
 | 
							int E = glm::float_distance(A, C); | 
				
			||||||
 | 
							Error += E == 0 ? 0 : 1; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Error; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						int Error = 0; | 
				
			||||||
 | 
						Error += test_ulp_float_dist(); | 
				
			||||||
 | 
						Error += test_ulp_float_step(); | 
				
			||||||
 | 
						Error += test_ulp_double_dist(); | 
				
			||||||
 | 
						Error += test_ulp_double_step(); | 
				
			||||||
 | 
						return Error; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					Loading…
					
					
				
		Reference in New Issue