[FFmpeg-cvslog] checkasm: add float comparison util functions

Janne Grunau git at videolan.org
Sat Jan 2 12:36:14 CET 2016


ffmpeg | branch: master | Janne Grunau <janne-libav at jannau.net> | Mon Dec  7 16:14:46 2015 +0100| [9d218d573f8088c606d873e80df572582e6773ef] | committer: Janne Grunau

checkasm: add float comparison util functions

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9d218d573f8088c606d873e80df572582e6773ef
---

 tests/checkasm/checkasm.c |   73 +++++++++++++++++++++++++++++++++++++++++++++
 tests/checkasm/checkasm.h |   11 +++++++
 2 files changed, 84 insertions(+)

diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index 37bc139..becfe35 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -27,6 +27,7 @@
 #include "checkasm.h"
 #include "libavutil/common.h"
 #include "libavutil/cpu.h"
+#include "libavutil/intfloat.h"
 #include "libavutil/random_seed.h"
 
 #if HAVE_IO_H
@@ -151,6 +152,78 @@ static struct {
 /* PRNG state */
 AVLFG checkasm_lfg;
 
+/* float compare support code */
+static int is_negative(union av_intfloat32 u)
+{
+    return u.i >> 31;
+}
+
+int float_near_ulp(float a, float b, unsigned max_ulp)
+{
+    union av_intfloat32 x, y;
+
+    x.f = a;
+    y.f = b;
+
+    if (is_negative(x) != is_negative(y)) {
+        // handle -0.0 == +0.0
+        return a == b;
+    }
+
+    if (abs(x.i - y.i) <= max_ulp)
+        return 1;
+
+    return 0;
+}
+
+int float_near_ulp_array(const float *a, const float *b, unsigned max_ulp,
+                         unsigned len)
+{
+    unsigned i;
+
+    for (i = 0; i < len; i++) {
+        if (!float_near_ulp(a[i], b[i], max_ulp))
+            return 0;
+    }
+    return 1;
+}
+
+int float_near_abs_eps(float a, float b, float eps)
+{
+    float abs_diff = fabsf(a - b);
+
+    return abs_diff < eps;
+}
+
+int float_near_abs_eps_array(const float *a, const float *b, float eps,
+                         unsigned len)
+{
+    unsigned i;
+
+    for (i = 0; i < len; i++) {
+        if (!float_near_abs_eps(a[i], b[i], eps))
+            return 0;
+    }
+    return 1;
+}
+
+int float_near_abs_eps_ulp(float a, float b, float eps, unsigned max_ulp)
+{
+    return float_near_ulp(a, b, max_ulp) || float_near_abs_eps(a, b, eps);
+}
+
+int float_near_abs_eps_array_ulp(const float *a, const float *b, float eps,
+                         unsigned max_ulp, unsigned len)
+{
+    unsigned i;
+
+    for (i = 0; i < len; i++) {
+        if (!float_near_abs_eps_ulp(a[i], b[i], eps, max_ulp))
+            return 0;
+    }
+    return 1;
+}
+
 /* Print colored text to stderr if the terminal supports it */
 static void color_printf(int color, const char *fmt, ...)
 {
diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h
index 6fc30ca..4a4cce4 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -42,6 +42,17 @@ void checkasm_fail_func(const char *msg, ...) av_printf_format(1, 2);
 void checkasm_update_bench(int iterations, uint64_t cycles);
 void checkasm_report(const char *name, ...) av_printf_format(1, 2);
 
+/* float compare utilities */
+int float_near_ulp(float a, float b, unsigned max_ulp);
+int float_near_abs_eps(float a, float b, float eps);
+int float_near_abs_eps_ulp(float a, float b, float eps, unsigned max_ulp);
+int float_near_ulp_array(const float *a, const float *b, unsigned max_ulp,
+                         unsigned len);
+int float_near_abs_eps_array(const float *a, const float *b, float eps,
+                             unsigned len);
+int float_near_abs_eps_array_ulp(const float *a, const float *b, float eps,
+                                 unsigned max_ulp, unsigned len);
+
 extern AVLFG checkasm_lfg;
 #define rnd() av_lfg_get(&checkasm_lfg)
 



More information about the ffmpeg-cvslog mailing list