When compiling with -Wfloat-equal you will notice a few warnings about
unsafe comparison of floating points with == or != operators.

To get around this two functions a_compare_float & a_compare_double
were created. They safely compare the two floating point numbers
within a  given precision.

Thanks,
- Brian Gianforcaro
From b88d4f3c79fe55d60327605212626dc8c9401038 Mon Sep 17 00:00:00 2001
From: Brian Gianforcaro <[email protected]>
Date: Fri, 4 Sep 2009 00:47:20 -0400
Subject: [PATCH 2/3] common: Fix unsafe comparison of floating point numbers

When compiling with -Wfloat-equal you will notice a few
warnings about unsafe comparison of floating points with == or != operators.

To get around this two functions a_compare_float & a_compare_double were
created. They safely compare the two floating point numbers within a
given precision.

Signed-off-by: Brian Gianforcaro <[email protected]>
---
 awesomeConfig.cmake |    2 +-
 client.c            |    2 +-
 common/util.h       |   28 ++++++++++++++++++++++++++++
 wibox.c             |    6 +++---
 widgets/graph.c     |    2 +-
 5 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/awesomeConfig.cmake b/awesomeConfig.cmake
index 019cd5a..2bb60c2 100644
--- a/awesomeConfig.cmake
+++ b/awesomeConfig.cmake
@@ -19,7 +19,7 @@ link_directories(/usr/local/lib)
 # {{{ CFLAGS
 add_definitions(-std=gnu99 -ggdb3 -fno-strict-aliasing -Wall -Wextra
     -Wchar-subscripts -Wundef -Wshadow -Wcast-align -Wwrite-strings
-    -Wsign-compare -Wunused -Wno-unused-parameter -Wuninitialized -Winit-self
+    -Wsign-compare -Wunused -Wfloat-equal -Wno-unused-parameter -Wuninitialized -Winit-self
     -Wpointer-arith -Wredundant-decls -Wformat-nonliteral
     -Wno-format-zero-length -Wmissing-format-attribute -Wmissing-prototypes
     -Wstrict-prototypes)
diff --git a/client.c b/client.c
index 140c90b..af4b835 100644
--- a/client.c
+++ b/client.c
@@ -72,7 +72,7 @@ client_set_opacity(lua_State *L, int cidx, double opacity)
 {
     client_t *c = luaA_client_checkudata(L, cidx);
 
-    if(c->opacity != opacity)
+    if(!a_compare_double(c->opacity, opacity))
     {
         c->opacity = opacity;
         window_opacity_set(c->window, opacity);
diff --git a/common/util.h b/common/util.h
index 779eb46..198ac48 100644
--- a/common/util.h
+++ b/common/util.h
@@ -273,6 +273,34 @@ static inline int a_strncmp(const char *a, const char *b, ssize_t n)
     return strncmp(NONULL(a), NONULL(b), n);
 }
 
+/** High precision float comparison
+ * \param[in] a The first float to compare
+ * \param[in] b The second float to compare
+ * \return true if equal within precision, false if not equal within defined precision.
+ */
+static inline int a_compare_float(const float a, const float b)
+{
+    const float precision = 0.00001;
+    if((a - precision) < b && (a + precision) > b)
+         return true;
+    else
+	 return false;
+}
+
+/** High precision double comparison
+ * \param[in] a The first double to compare
+ * \param[in] b The second double to compare
+ * \return true on equal within precison, false if not equal within defined precision.
+ */
+static inline int a_compare_double(const double a, const double b)
+{
+    const double precision = 0.00001;
+    if((a - precision) < b && (a + precision) > b)
+         return true;
+    else
+	 return false;
+}
+
 ssize_t a_strncpy(char *dst, ssize_t n, const char *src, ssize_t l) __attribute__((nonnull(1)));
 ssize_t a_strcpy(char *dst, ssize_t n, const char *src) __attribute__((nonnull(1)));
 
diff --git a/wibox.c b/wibox.c
index c7214b2..278c6ec 100644
--- a/wibox.c
+++ b/wibox.c
@@ -317,7 +317,7 @@ void
 wibox_set_opacity(lua_State *L, int udx, double opacity)
 {
     wibox_t *w = luaA_checkudata(L, udx, &wibox_class);
-    if(w->opacity != opacity)
+    if(!a_compare_double(w->opacity,opacity))
     {
         w->opacity = opacity;
         if(w->window)
@@ -763,7 +763,7 @@ wibox_attach(lua_State *L, int udx, screen_t *s)
     window_set_cursor(wibox->window,
                       xcursor_new(globalconf.connection, xcursor_font_fromstr(wibox->cursor)));
 
-    if(wibox->opacity != -1)
+    if(!a_compare_double(wibox->opacity,-1))
         window_opacity_set(wibox->window, wibox->opacity);
 
     ewmh_update_strut(wibox->window, &wibox->strut);
@@ -806,7 +806,7 @@ luaA_wibox_new(lua_State *L)
 
     w->visible = true;
 
-    if(!w->opacity)
+    if(a_compare_double(w->opacity, 0))
         w->opacity = -1;
 
     if(!w->cursor)
diff --git a/widgets/graph.c b/widgets/graph.c
index 861fce3..82cd3ab 100644
--- a/widgets/graph.c
+++ b/widgets/graph.c
@@ -333,7 +333,7 @@ luaA_graph_plot_properties_set(lua_State *L)
     plot->scale = luaA_getopt_boolean(L, 3, "scale", plot->scale);
 
     max_value = luaA_getopt_number(L, 3, "max_value", plot->max_value);
-    if(max_value != plot->max_value)
+    if(!a_compare_float(max_value, plot->max_value))
         plot->max_value = plot->current_max = max_value;
 
     if((buf = luaA_getopt_lstring(L, 3, "style", NULL, &len)))
-- 
1.6.3.3

Reply via email to