Browse Source

fix "warning: comparing floating point with == or != is unsafe" (epsilon comparison)

Instead of comparing floats "x == y", perform comparison
"fabs(x - y) <= epsilon", where epsilon is acceptable error that
accumulates in computation of x and/or y.

Because in this case all integers are small and all floats are exactly
representable under IEEE754, epsilon may be zero in our tests.

This warning occurred when compiling using

gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)

on CentOS 6.5 x86_64

using the following CFLAGS (locally inserted into Makefile)

CFLAGS = -g -Wall -Wextra -Wformat=2 -funsigned-char -fstrict-aliasing
 -Wstrict-aliasing -Wfloat-equal -Wundef -Wuninitialized -Wpointer-arith
 -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Waddress
 -Waggregate-return -Wstrict-prototypes -Wold-style-declaration
 -Wold-style-definition -Wmissing-parameter-type -Wmissing-prototypes
 -Wmissing-declarations -Wmissing-field-initializers -Wmissing-noreturn
 -Wmissing-format-attribute -Wpacked -Wredundant-decls -Wnested-externs
 -Wshadow -Wsign-compare -Wlogical-op -std=c99

and this make command:

make clean ; make example tests
Evgueni Souleimanov 11 years ago
parent
commit
f68eb7c9fd
1 changed files with 6 additions and 6 deletions
  1. 6 6
      tests.c

+ 6 - 6
tests.c

@@ -688,18 +688,18 @@ END_TEST
 START_TEST(test_minmea_float)
 START_TEST(test_minmea_float)
 {
 {
     ck_assert(isnan(minmea_tofloat(&(struct minmea_float) { 42, 0 })));
     ck_assert(isnan(minmea_tofloat(&(struct minmea_float) { 42, 0 })));
-    ck_assert(minmea_tofloat(&(struct minmea_float) { 7, 1}) == 7.0);
-    ck_assert(minmea_tofloat(&(struct minmea_float) { -200, 100}) == -2.0);
-    ck_assert(minmea_tofloat(&(struct minmea_float) { 15, 10}) == 1.5);
+    ck_assert(fabs(minmea_tofloat(&(struct minmea_float) { 7, 1}) - 7.0) <= 0.0f);
+    ck_assert(fabs(minmea_tofloat(&(struct minmea_float) { -200, 100}) - (-2.0)) <= 0.0f);
+    ck_assert(fabs(minmea_tofloat(&(struct minmea_float) { 15, 10}) - 1.5) <= 0.0f);
 }
 }
 END_TEST
 END_TEST
 
 
 START_TEST(test_minmea_coord)
 START_TEST(test_minmea_coord)
 {
 {
     ck_assert(isnan(minmea_tocoord(&(struct minmea_float) { 42, 0 })));
     ck_assert(isnan(minmea_tocoord(&(struct minmea_float) { 42, 0 })));
-    ck_assert(minmea_tocoord(&(struct minmea_float) { 4200, 1 }) == 42.0);
-    ck_assert(minmea_tocoord(&(struct minmea_float) { 420000, 100 }) == 42.0);
-    ck_assert(minmea_tocoord(&(struct minmea_float) { 423000, 100 }) == 42.5);
+    ck_assert(fabs(minmea_tocoord(&(struct minmea_float) { 4200, 1 }) - 42.0) <= 0.0f);
+    ck_assert(fabs(minmea_tocoord(&(struct minmea_float) { 420000, 100 }) - 42.0) <= 0.0f);
+    ck_assert(fabs(minmea_tocoord(&(struct minmea_float) { 423000, 100 }) - 42.5) <= 0.0f);
 }
 }
 END_TEST
 END_TEST