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