Fixed error: comparing floating point with == or != is unsafe

This commit is contained in:
Groove 2018-07-28 20:51:13 +02:00
parent a7e0e8387b
commit d6b0b9b1ef
4 changed files with 48 additions and 53 deletions

View File

@ -1,5 +1,7 @@
#include <glm/gtc/type_precision.hpp> #include <glm/gtc/type_precision.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/ext/vector_relational.hpp>
#include <vector> #include <vector>
#if GLM_HAS_OPENMP #if GLM_HAS_OPENMP
# include <omp.h> # include <omp.h>
@ -94,27 +96,16 @@ static int test_fvec_size()
static int test_fvec_precision() static int test_fvec_precision()
{ {
int Error = 0; int Error = 0;
/*
{
glm::f32vec2 v1;
glm::lowp_f32vec2 v2((glm::f32vec2(v1)));
glm::mediump_f32vec2 v3((glm::f32vec2(v1)));
glm::highp_f32vec2 v4((glm::f32vec2(v1)));
Error += glm::all(glm::equal(v1, v2)) ? 0 : 1;
Error += glm::all(glm::equal(v1, v3)) ? 0 : 1;
Error += glm::all(glm::equal(v1, v4)) ? 0 : 1;
}
*/
{ {
glm::f32vec2 v1(1.f); glm::f32vec2 v1(1.f);
glm::lowp_f32vec2 v2(v1); glm::lowp_f32vec2 v2(v1);
glm::mediump_f32vec2 v3(v1); glm::mediump_f32vec2 v3(v1);
glm::highp_f32vec2 v4(v1); glm::highp_f32vec2 v4(v1);
Error += glm::all(glm::equal(v1, glm::f32vec2(v2))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec2(v2), glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f32vec2(v3))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec2(v3), glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f32vec2(v4))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec2(v4), glm::epsilon<float>())) ? 0 : 1;
} }
{ {
@ -123,9 +114,9 @@ static int test_fvec_precision()
glm::mediump_f32vec3 v3(v1); glm::mediump_f32vec3 v3(v1);
glm::highp_f32vec3 v4(v1); glm::highp_f32vec3 v4(v1);
Error += glm::all(glm::equal(v1, glm::f32vec3(v2))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec3(v2), glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f32vec3(v3))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec3(v3), glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f32vec3(v4))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec3(v4), glm::epsilon<float>())) ? 0 : 1;
} }
{ {
@ -134,9 +125,9 @@ static int test_fvec_precision()
glm::mediump_f32vec4 v3(v1); glm::mediump_f32vec4 v3(v1);
glm::highp_f32vec4 v4(v1); glm::highp_f32vec4 v4(v1);
Error += glm::all(glm::equal(v1, glm::f32vec4(v2))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec4(v2), glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f32vec4(v3))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec4(v3), glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f32vec4(v4))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f32vec4(v4), glm::epsilon<float>())) ? 0 : 1;
} }
return Error; return Error;
@ -152,9 +143,9 @@ static int test_dvec_precision()
glm::mediump_f64vec2 v3(v1); glm::mediump_f64vec2 v3(v1);
glm::highp_f64vec2 v4(v1); glm::highp_f64vec2 v4(v1);
Error += glm::all(glm::equal(v1, glm::f64vec2(v2))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec2(v2), glm::epsilon<double>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f64vec2(v3))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec2(v3), glm::epsilon<double>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f64vec2(v4))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec2(v4), glm::epsilon<double>())) ? 0 : 1;
} }
{ {
@ -163,9 +154,9 @@ static int test_dvec_precision()
glm::mediump_f64vec3 v3(v1); glm::mediump_f64vec3 v3(v1);
glm::highp_f64vec3 v4(v1); glm::highp_f64vec3 v4(v1);
Error += glm::all(glm::equal(v1, glm::f64vec3(v2))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec3(v2), glm::epsilon<double>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f64vec3(v3))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec3(v3), glm::epsilon<double>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f64vec3(v4))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec3(v4), glm::epsilon<double>())) ? 0 : 1;
} }
{ {
@ -174,9 +165,9 @@ static int test_dvec_precision()
glm::mediump_f64vec4 v3(v1); glm::mediump_f64vec4 v3(v1);
glm::highp_f64vec4 v4(v1); glm::highp_f64vec4 v4(v1);
Error += glm::all(glm::equal(v1, glm::f64vec4(v2))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec4(v2), glm::epsilon<double>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f64vec4(v3))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec4(v3), glm::epsilon<double>())) ? 0 : 1;
Error += glm::all(glm::equal(v1, glm::f64vec4(v4))) ? 0 : 1; Error += glm::all(glm::equal(v1, glm::f64vec4(v4), glm::epsilon<double>())) ? 0 : 1;
} }
return Error; return Error;
@ -833,9 +824,9 @@ static int test_quat_precision()
glm::f32quat q3(qB); glm::f32quat q3(qB);
glm::f32quat q4(qC); glm::f32quat q4(qC);
Error += glm::all(glm::equal(q1, q2)) ? 0 : 1; Error += glm::all(glm::equal(q1, q2, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(q1, q3)) ? 0 : 1; Error += glm::all(glm::equal(q1, q3, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(q1, q4)) ? 0 : 1; Error += glm::all(glm::equal(q1, q4, glm::epsilon<float>())) ? 0 : 1;
} }
return Error; return Error;
@ -853,7 +844,7 @@ static int test_fvec_conversion()
glm::lowp_ivec4 e = glm::ivec4(d); glm::lowp_ivec4 e = glm::ivec4(d);
glm::lowp_ivec3 f = glm::ivec3(e); glm::lowp_ivec3 f = glm::ivec3(e);
Error += glm::all(glm::equal(b, d)) ? 0 : 1; Error += glm::all(glm::equal(b, d, glm::epsilon<float>())) ? 0 : 1;
} }
return Error; return Error;

View File

@ -2,7 +2,8 @@
#include <glm/gtx/extended_min_max.hpp> #include <glm/gtx/extended_min_max.hpp>
#include <glm/gtc/vec1.hpp> #include <glm/gtc/vec1.hpp>
#include <glm/gtc/epsilon.hpp> #include <glm/gtc/constants.hpp>
#include <glm/ext/vector_relational.hpp>
// This file has divisions by zero to test isnan // This file has divisions by zero to test isnan
#if GLM_COMPILER & GLM_COMPILER_VC #if GLM_COMPILER & GLM_COMPILER_VC
@ -17,24 +18,24 @@ namespace fmin_
float Zero_f = 0.0f; float Zero_f = 0.0f;
glm::vec1 A0 = glm::fmin(glm::vec1(1), glm::vec1(Zero_f / 0.0f)); glm::vec1 A0 = glm::fmin(glm::vec1(1), glm::vec1(Zero_f / 0.0f));
Error += glm::epsilonEqual(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1; Error += glm::equal(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
glm::vec1 A1 = glm::fmin(glm::vec1(Zero_f / 0.0f), glm::vec1(1)); glm::vec1 A1 = glm::fmin(glm::vec1(Zero_f / 0.0f), glm::vec1(1));
Error += glm::epsilonEqual(A1.x, 1.0f, glm::epsilon<float>()) ? 0 : 1; Error += glm::equal(A1.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
glm::vec2 B0 = glm::fmin(glm::vec2(1), glm::vec2(1)); glm::vec2 B0 = glm::fmin(glm::vec2(1), glm::vec2(1));
glm::vec2 B1 = glm::fmin(glm::vec2(1), 1.0f); glm::vec2 B1 = glm::fmin(glm::vec2(1), 1.0f);
bool B2 = glm::all(glm::equal(B0, B1)); bool B2 = glm::all(glm::equal(B0, B1, glm::epsilon<float>()));
Error += B2 ? 0 : 1; Error += B2 ? 0 : 1;
glm::vec3 C0 = glm::fmin(glm::vec3(1), glm::vec3(1)); glm::vec3 C0 = glm::fmin(glm::vec3(1), glm::vec3(1));
glm::vec3 C1 = glm::fmin(glm::vec3(1), 1.0f); glm::vec3 C1 = glm::fmin(glm::vec3(1), 1.0f);
bool C2 = glm::all(glm::equal(C0, C1)); bool C2 = glm::all(glm::equal(C0, C1, glm::epsilon<float>()));
Error += C2 ? 0 : 1; Error += C2 ? 0 : 1;
glm::vec4 D0 = glm::fmin(glm::vec4(1), glm::vec4(1)); glm::vec4 D0 = glm::fmin(glm::vec4(1), glm::vec4(1));
glm::vec4 D1 = glm::fmin(glm::vec4(1), 1.0f); glm::vec4 D1 = glm::fmin(glm::vec4(1), 1.0f);
bool D2 = glm::all(glm::equal(D0, D1)); bool D2 = glm::all(glm::equal(D0, D1, glm::epsilon<float>()));
Error += D2 ? 0 : 1; Error += D2 ? 0 : 1;
return Error; return Error;
@ -49,10 +50,10 @@ namespace fmax_
float Zero_f = 0.0f; float Zero_f = 0.0f;
glm::vec1 A0 = glm::fmax(glm::vec1(1), glm::vec1(Zero_f / 0.0f)); glm::vec1 A0 = glm::fmax(glm::vec1(1), glm::vec1(Zero_f / 0.0f));
Error += glm::epsilonEqual(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1; Error += glm::equal(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
glm::vec1 A1 = glm::fmax(glm::vec1(Zero_f / 0.0f), glm::vec1(1)); glm::vec1 A1 = glm::fmax(glm::vec1(Zero_f / 0.0f), glm::vec1(1));
Error += glm::epsilonEqual(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1; Error += glm::equal(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
glm::vec2 B0 = glm::fmax(glm::vec2(1), glm::vec2(1)); glm::vec2 B0 = glm::fmax(glm::vec2(1), glm::vec2(1));
glm::vec2 B1 = glm::fmax(glm::vec2(1), 1.0f); glm::vec2 B1 = glm::fmax(glm::vec2(1), 1.0f);
@ -81,7 +82,7 @@ namespace fclamp_
float Zero_f = 0.0f; float Zero_f = 0.0f;
glm::vec1 A0 = glm::fclamp(glm::vec1(1), glm::vec1(Zero_f / 0.0f), glm::vec1(2.0f)); glm::vec1 A0 = glm::fclamp(glm::vec1(1), glm::vec1(Zero_f / 0.0f), glm::vec1(2.0f));
Error += glm::epsilonEqual(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1; Error += glm::equal(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
return Error; return Error;
} }

View File

@ -1,6 +1,7 @@
#define GLM_ENABLE_EXPERIMENTAL #define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtc/constants.hpp>
#include <glm/ext/vector_relational.hpp>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/epsilon.hpp>
#if GLM_HAS_RANGE_FOR #if GLM_HAS_RANGE_FOR
@ -49,7 +50,7 @@ int test_mat()
Sum += x; Sum += x;
} }
Error += count == 12 ? 0 : 1; Error += count == 12 ? 0 : 1;
Error += glm::epsilonEqual(Sum, 3.0f, 0.001f) ? 0 : 1; Error += glm::equal(Sum, 3.0f, 0.001f) ? 0 : 1;
} }
{ {
@ -57,7 +58,7 @@ int test_mat()
for (float& x : m) { x = 0; } for (float& x : m) { x = 0; }
glm::vec4 v(1, 1, 1, 1); glm::vec4 v(1, 1, 1, 1);
Error += glm::all(glm::equal(m*v, glm::vec3(0, 0, 0))) ? 0 : 1; Error += glm::all(glm::equal(m*v, glm::vec3(0, 0, 0), glm::epsilon<float>())) ? 0 : 1;
} }
return Error; return Error;

View File

@ -1,4 +1,6 @@
#define GLM_ENABLE_EXPERIMENTAL #define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtc/constants.hpp>
#include <glm/ext/vector_relational.hpp>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#if GLM_HAS_TEMPLATE_ALIASES && !(GLM_COMPILER & GLM_COMPILER_GCC) #if GLM_HAS_TEMPLATE_ALIASES && !(GLM_COMPILER & GLM_COMPILER_GCC)
@ -9,18 +11,18 @@ int main()
int Error(0); int Error(0);
glm::vec3 v(0.5, 3.1, -9.1); glm::vec3 v(0.5, 3.1, -9.1);
Error += glm::all(glm::equal(v, 1.0 * v)) ? 0 : 1; Error += glm::all(glm::equal(v, 1.0 * v, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v, 1 * v)) ? 0 : 1; Error += glm::all(glm::equal(v, 1 * v, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v, 1u * v)) ? 0 : 1; Error += glm::all(glm::equal(v, 1u * v, glm::epsilon<float>())) ? 0 : 1;
glm::mat3 m(1, 2, 3, 4, 5, 6, 7, 8, 9); glm::mat3 m(1, 2, 3, 4, 5, 6, 7, 8, 9);
glm::vec3 w = 0.5f * m * v; glm::vec3 w = 0.5f * m * v;
Error += glm::all(glm::equal((m*v)/2, w)) ? 0 : 1; Error += glm::all(glm::equal((m*v)/2, w, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(m*(v/2), w)) ? 0 : 1; Error += glm::all(glm::equal(m*(v/2), w, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal((m/2)*v, w)) ? 0 : 1; Error += glm::all(glm::equal((m/2)*v, w, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal((0.5*m)*v, w)) ? 0 : 1; Error += glm::all(glm::equal((0.5*m)*v, w, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(0.5*(m*v), w)) ? 0 : 1; Error += glm::all(glm::equal(0.5*(m*v), w, glm::epsilon<float>())) ? 0 : 1;
return Error; return Error;
} }