summaryrefslogtreecommitdiff
path: root/cesar/lib/src/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/lib/src/utils.c')
-rw-r--r--cesar/lib/src/utils.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/cesar/lib/src/utils.c b/cesar/lib/src/utils.c
new file mode 100644
index 0000000000..4ca7b39654
--- /dev/null
+++ b/cesar/lib/src/utils.c
@@ -0,0 +1,42 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file lib/src/utils.c
+ * \brief Common utilities.
+ * \ingroup lib
+ */
+#include "common/std.h"
+
+/* See
+ * http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
+ */
+bool
+almost_eqf (float a, float b, int max_ulps)
+{
+ union
+ {
+ float f;
+ s32 i;
+ } aInt, bInt;
+ /* Make sure max_ulps is non-negative and small enough that the default
+ * NAN won't compare as equal to anything. */
+ dbg_assert (max_ulps > 0 && max_ulps < 4 * 1024 * 1024);
+ aInt.f = a;
+ /* Make aInt lexicographically ordered as a twos-complement int. */
+ if (aInt.i < 0)
+ aInt.i = 0x80000000 - aInt.i;
+ /* Make bInt lexicographically ordered as a twos-complement int. */
+ bInt.f = b;
+ if (bInt.i < 0)
+ bInt.i = 0x80000000 - bInt.i;
+ s32 intDiff = ABS (aInt.i - bInt.i);
+ if (intDiff <= max_ulps)
+ return true;
+ return false;
+}
+