1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-10 16:58:47 +03:00

gcc: fix comparing floating point warning

Since we enabled some more gcc warnings - let's adapt for
it and check for double equals with DBL_EPSILON.

Current close_enough() is far from perfect
for more details see i.e. here:
http://randomascii.wordpress.com/2012/01/11/tricks-with-the-floating-point-format/
but fairly enough for lvm2 use-case.
This commit is contained in:
Zdenek Kabelac 2013-10-25 10:38:09 +02:00
parent d4e5140b52
commit 8e1f2e733e
3 changed files with 23 additions and 5 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.104 - Version 2.02.104 -
=================================== ===================================
Compare equality of double values with DBL_EPSILON predefined constant.
Use additional gcc warning flags by default. Use additional gcc warning flags by default.
Add ignore_lvm_mirrors to config file to read/ignore labels on mirrors. Add ignore_lvm_mirrors to config file to read/ignore labels on mirrors.
Add internal flag for temporary LVs to properly direct udev to not interfere. Add internal flag for temporary LVs to properly direct udev to not interfere.

View File

@ -26,6 +26,9 @@
#include <stdint.h> #include <stdint.h>
#include <unistd.h> #include <unistd.h>
#include <math.h> /* fabs() */
#include <float.h> /* DBL_EPSILON */
typedef struct { typedef struct {
log_state *log; /* convenience */ log_state *log; /* convenience */
const char *log_config; const char *log_config;
@ -503,6 +506,12 @@ bad:
return reply_fail("out of memory"); return reply_fail("out of memory");
} }
/* Test if the doubles are close enough to be considered equal */
static int close_enough(double d1, double d2)
{
return fabs(d1 - d2) < DBL_EPSILON;
}
static int compare_value(struct dm_config_value *a, struct dm_config_value *b) static int compare_value(struct dm_config_value *a, struct dm_config_value *b)
{ {
int r = 0; int r = 0;
@ -514,7 +523,7 @@ static int compare_value(struct dm_config_value *a, struct dm_config_value *b)
switch (a->type) { switch (a->type) {
case DM_CFG_STRING: r = strcmp(a->v.str, b->v.str); break; case DM_CFG_STRING: r = strcmp(a->v.str, b->v.str); break;
case DM_CFG_FLOAT: r = (a->v.f == b->v.f) ? 0 : (a->v.f > b->v.f) ? 1 : -1; break; case DM_CFG_FLOAT: r = close_enough(a->v.f, b->v.f) ? 0 : (a->v.f > b->v.f) ? 1 : -1; break;
case DM_CFG_INT: r = (a->v.i == b->v.i) ? 0 : (a->v.i > b->v.i) ? 1 : -1; break; case DM_CFG_INT: r = (a->v.i == b->v.i) ? 0 : (a->v.i > b->v.i) ? 1 : -1; break;
case DM_CFG_EMPTY_ARRAY: return 0; case DM_CFG_EMPTY_ARRAY: return 0;
} }

View File

@ -20,6 +20,8 @@
#include "toolcontext.h" #include "toolcontext.h"
#include "segtype.h" #include "segtype.h"
#include "defaults.h" #include "defaults.h"
#include <math.h> /* fabs() */
#include <float.h> /* DBL_EPSILON */
#define SIZE_BUF 128 #define SIZE_BUF 128
@ -41,6 +43,12 @@ static const struct {
static const int _num_policies = sizeof(_policies) / sizeof(*_policies); static const int _num_policies = sizeof(_policies) / sizeof(*_policies);
/* Test if the doubles are close enough to be considered equal */
static int _close_enough(double d1, double d2)
{
return fabs(d1 - d2) < DBL_EPSILON;
}
uint64_t units_to_bytes(const char *units, char *unit_type) uint64_t units_to_bytes(const char *units, char *unit_type)
{ {
char *ptr = NULL; char *ptr = NULL;
@ -53,7 +61,7 @@ uint64_t units_to_bytes(const char *units, char *unit_type)
if (ptr == units) if (ptr == units)
return 0; return 0;
v = (uint64_t) strtoull(units, NULL, 10); v = (uint64_t) strtoull(units, NULL, 10);
if ((double) v == custom_value) if (_close_enough((double) v, custom_value))
custom_value = 0; /* Use integer arithmetic */ custom_value = 0; /* Use integer arithmetic */
units = ptr; units = ptr;
} else } else
@ -126,10 +134,10 @@ uint64_t units_to_bytes(const char *units, char *unit_type)
return 0; return 0;
} }
if (custom_value) if (_close_enough(custom_value, 0.))
return (uint64_t) (custom_value * multiplier); return v * multiplier; /* Use integer arithmetic */
else else
return v * multiplier; return (uint64_t) (custom_value * multiplier);
} }
char alloc_policy_char(alloc_policy_t alloc) char alloc_policy_char(alloc_policy_t alloc)