summaryrefslogtreecommitdiff
path: root/n/avr/modules/math/fixed/test/test_fixed.c
diff options
context:
space:
mode:
Diffstat (limited to 'n/avr/modules/math/fixed/test/test_fixed.c')
-rw-r--r--n/avr/modules/math/fixed/test/test_fixed.c105
1 files changed, 97 insertions, 8 deletions
diff --git a/n/avr/modules/math/fixed/test/test_fixed.c b/n/avr/modules/math/fixed/test/test_fixed.c
index 35ea573..ff826d4 100644
--- a/n/avr/modules/math/fixed/test/test_fixed.c
+++ b/n/avr/modules/math/fixed/test/test_fixed.c
@@ -30,6 +30,72 @@
#include "modules/utils/utils.h"
#include "io.h"
+#ifdef HOST
+
+#include <math.h>
+#include <fenv.h>
+#include <stdio.h>
+
+static void
+check_mul (int32_t a, int32_t b, int32_t r)
+{
+ feclearexcept (FE_ALL_EXCEPT);
+ double af = (double) a / (1 << 24);
+ double bf = (double) b / (1 << 24);
+ int32_t ri = rint (af * bf * (1 << 24));
+ if (r != ri && !fetestexcept (FE_INVALID))
+ printf ("error: %08x * %08x != %08x (%08x)\n", a, b, r, ri);
+}
+
+static void
+check_div (int32_t a, int32_t b, int32_t r)
+{
+ feclearexcept (FE_ALL_EXCEPT);
+ double af = (double) a / (1 << 24);
+ double bf = (double) b / (1 << 24);
+ int32_t ri = af / bf * (1 << 24);
+ if (r != ri && !fetestexcept (FE_INVALID))
+ printf ("error: %08x / %08x != %08x (%08x)\n", a, b, r, ri);
+}
+
+static void
+check_cos (int32_t a, int32_t rc, int32_t rs)
+{
+ double af = (double) a / (1 << 24) * 2 * M_PI;
+ int32_t rci = cos (af) * (1 << 24);
+ if (rc != rci)
+ printf ("error: cos (%08x) != %08x (%08x%+d)\n",
+ a, rc, rci, rc - rci);
+ int32_t rsi = sin (af) * (1 << 24);
+ if (rs != rsi)
+ printf ("error: sin (%08x) != %08x (%08x%+d)\n",
+ a, rs, rsi, rs - rsi);
+}
+
+static void
+check_sqrt (uint32_t a, uint32_t rf, uint16_t ri)
+{
+ double aff = (double) a / (1 << 8);
+ uint32_t rfi = sqrt (aff) * (1 << 8);
+ if (rf != rfi)
+ printf ("error: sqrt_f (%08x) != %08x (%08x%+d)\n",
+ a, rf, rfi, rf - rfi);
+ double aif = (double) a;
+ uint16_t rii = sqrt (aif);
+ if (ri != rii)
+ printf ("error: sqrt_i (%08x) != %04x (%04x%+d)\n",
+ a, ri, rii, ri - rii);
+}
+
+#else
+
+# define check_mul(a, b, r)
+# define check_div(a, b, r)
+# define check_cos(a, rc, rs)
+# define check_sqrt(a, rf, ri)
+
+#endif
+
void
proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
{
@@ -54,9 +120,13 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
bl = patl[bp] >> bs;
proto_send2d ('a', al, bl);
rl[0] = fixed_mul_f824 (al, bl);
+ check_mul (al, bl, rl[0]);
rl[1] = fixed_mul_f824 (-al, bl);
+ check_mul (-al, bl, rl[1]);
rl[2] = fixed_mul_f824 (al, -bl);
+ check_mul (al, -bl, rl[2]);
rl[3] = fixed_mul_f824 (-al, -bl);
+ check_mul (-al, -bl, rl[3]);
proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
}
for (i = 0; i < 64000; i++)
@@ -65,9 +135,13 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
bl = random_u32 ();
proto_send2d ('a', al, bl);
rl[0] = fixed_mul_f824 (al, bl);
+ check_mul (al, bl, rl[0]);
rl[1] = fixed_mul_f824 (-al, bl);
+ check_mul (-al, bl, rl[1]);
rl[2] = fixed_mul_f824 (al, -bl);
+ check_mul (al, -bl, rl[2]);
rl[3] = fixed_mul_f824 (-al, -bl);
+ check_mul (-al, -bl, rl[3]);
proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
}
break;
@@ -75,35 +149,47 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
for (ap = 0; ap < patn; ap++)
for (bp = 0; bp < patn; bp++)
for (as = 0; as < 32; as++)
- for (bs = 0; bs < 32; bs++)
+ for (bs = 0; bs < 31; bs++)
{
al = patl[ap] >> as;
bl = patl[bp] >> bs;
proto_send2d ('a', al, bl);
rl[0] = fixed_div_f824 (al, bl);
+ check_div (al, bl, rl[0]);
rl[1] = fixed_div_f824 (-al, bl);
+ check_div (-al, bl, rl[1]);
rl[2] = fixed_div_f824 (al, -bl);
+ check_div (al, -bl, rl[2]);
rl[3] = fixed_div_f824 (-al, -bl);
+ check_div (-al, -bl, rl[3]);
proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
}
for (i = 0; i < 64000; i++)
{
al = random_u32 ();
bl = random_u32 ();
- proto_send2d ('a', al, bl);
- rl[0] = fixed_div_f824 (al, bl);
- rl[1] = fixed_div_f824 (-al, bl);
- rl[2] = fixed_div_f824 (al, -bl);
- rl[3] = fixed_div_f824 (-al, -bl);
- proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ if (bl != 0)
+ {
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_div_f824 (al, bl);
+ check_div (al, bl, rl[0]);
+ rl[1] = fixed_div_f824 (-al, bl);
+ check_div (-al, bl, rl[1]);
+ rl[2] = fixed_div_f824 (al, -bl);
+ check_div (al, -bl, rl[2]);
+ rl[3] = fixed_div_f824 (-al, -bl);
+ check_div (-al, -bl, rl[3]);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
}
break;
case c ('c', 0):
- for (al = 0; al < (1L << 24); al += 1 << 8)
+ for (al = 0; al < (1L << 24); al += 257)
{
proto_send1d ('a', al);
rl[0] = fixed_cos_f824 (al);
rl[1] = fixed_sin_f824 (al);
+ check_cos (al, rl[0], rl[1]);
proto_send2d ('r', rl[0], rl[1]);
}
for (i = 0; i < 64000; i++)
@@ -112,6 +198,7 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
proto_send1d ('a', al);
rl[0] = fixed_cos_f824 (al);
rl[1] = fixed_sin_f824 (al);
+ check_cos (al, rl[0], rl[1]);
proto_send2d ('r', rl[0], rl[1]);
}
break;
@@ -123,6 +210,7 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
proto_send1d ('a', al);
rl[0] = fixed_sqrt_uf248 (al);
rl[1] = fixed_sqrt_ui32 (al);
+ check_sqrt (al, rl[0], rl[1]);
proto_send2d ('r', rl[0], rl[1]);
}
for (i = 0; i < 64000; i++)
@@ -131,6 +219,7 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
proto_send1d ('a', al);
rl[0] = fixed_sqrt_uf248 (al);
rl[1] = fixed_sqrt_ui32 (al);
+ check_sqrt (al, rl[0], rl[1]);
proto_send2d ('r', rl[0], rl[1]);
}
break;