summaryrefslogtreecommitdiff
path: root/tests/checkasm
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2016-01-02 12:35:24 +0100
committerHendrik Leppkes <h.leppkes@gmail.com>2016-01-02 12:35:52 +0100
commit0c7ade547ad8aeaee0e1afd5b6730087b6c97da2 (patch)
tree5c25f9e41c0efec8c64fa9b20a5e9f091fff17f7 /tests/checkasm
parent753930bc7300dd595c4bab51c5a70d1da9083da4 (diff)
parent9d218d573f8088c606d873e80df572582e6773ef (diff)
Merge commit '9d218d573f8088c606d873e80df572582e6773ef'
* commit '9d218d573f8088c606d873e80df572582e6773ef': checkasm: add float comparison util functions Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
Diffstat (limited to 'tests/checkasm')
-rw-r--r--tests/checkasm/checkasm.c73
-rw-r--r--tests/checkasm/checkasm.h11
2 files changed, 84 insertions, 0 deletions
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index ba7a83cae2..2009d81313 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
@@ -166,6 +167,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 e41ef67547..ca6acee42d 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -46,6 +46,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)