aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMartin Baƙinka <marun1@email.cz>2021-05-03 12:43:54 +0200
committerGitHub <noreply@github.com>2021-05-03 13:43:54 +0300
commit0c88e55fa8f132e8ac15426911d155f136078302 (patch)
tree03fc1b22c0582bd57ae3a14095d3d9c9f949f0c9 /tests
parent4ea8f3ff12da61a5ceba690bf1e39d9385b42880 (diff)
downloadlibfixmath-0c88e55fa8f132e8ac15426911d155f136078302.tar.gz
fixed division, undefined behaviors and some improvements (#33)
* testing using ctest * emove old testing script * added github workflow CI * updated CI * added unit test for macros * F16() and F16C() are both rounding allways, so fix16_from_dbl should as well * added tests for strign operations, but these functions are in my opinion unreliable and tests are failing * removed old unittests * removed old unittests from cmake * problem with division using gcc * improved benchmark * clarification of problem with division * attempt to fix * fixed some undefined behaviors, fixed division
Diffstat (limited to 'tests')
-rw-r--r--tests/tests.c38
-rw-r--r--tests/tests.cmake7
-rw-r--r--tests/tests.h33
-rw-r--r--tests/tests_basic.c10
-rw-r--r--tests/tests_macros.c100
-rw-r--r--tests/tests_macros.h6
-rw-r--r--tests/tests_str.c108
-rw-r--r--tests/tests_str.h6
8 files changed, 298 insertions, 10 deletions
diff --git a/tests/tests.c b/tests/tests.c
index cef9710..d06ee26 100644
--- a/tests/tests.c
+++ b/tests/tests.c
@@ -1,7 +1,9 @@
#include "tests.h"
#include "tests_basic.h"
#include "tests_lerp.h"
+#include "tests_macros.h"
#include "tests_sqrt.h"
+#include "tests_str.h"
#include <stdio.h>
const fix16_t testcases[] = {
@@ -32,14 +34,41 @@ const fix16_t testcases[] = {
// Tiny random numbers
-171, -359, 491, 844, 158, -413, -422, -737, -575, -330, -376, 435, -311,
- 116, 715, -1024, -487, 59, 724, 993
-};
+ 116, 715, -1024, -487, 59, 724, 993};
unsigned stack_depth = 0;
int main()
{
- printf("\033[1;34m\nVARIANT: \033[39m"STR2(PREFIX)"\033[0m\n");
+ printf("\033[1;34m\nVARIANT: \033[39m" STR2(PREFIX) "\033[0m\n");
+#if 0
+ fix16_t a = 65536;
+ fix16_t b = -2147483648;
+ fix16_t result = fix16_div(a, b);
+
+ double fa = fix16_to_dbl(a);
+ double fb = fix16_to_dbl(b);
+ double fresult = fa / fb;
+
+ double max = fix16_to_dbl(fix16_maximum);
+ double min = fix16_to_dbl(fix16_minimum);
+
+ printf("result %i, %.20f\n", result, fix16_to_dbl(result));
+ printf("fresult %i, %.20f\n", fix16_from_dbl(fresult), fresult);
+
+ if ((fa / fb) > max || (fa / fb) < min)
+ {
+#ifndef FIXMATH_NO_OVERFLOW
+ ASSERT_EQ_INT(result, fix16_overflow);
+#endif
+ }
+ else
+ {
+ ASSERT_NEAR_DOUBLE(fresult, fix16_to_dbl(result),
+ fix16_to_dbl(fix16_eps), "%i / %i \n", a, b);
+ }
+
+#else
TEST(test_abs());
TEST(test_add());
TEST(test_mul());
@@ -47,5 +76,8 @@ int main()
TEST(test_sub());
TEST(test_sqrt());
TEST(test_lerp());
+ TEST(test_macros());
+ //TEST(test_str());
+#endif
return 0;
}
diff --git a/tests/tests.cmake b/tests/tests.cmake
index 5f6c90b..c07b69d 100644
--- a/tests/tests.cmake
+++ b/tests/tests.cmake
@@ -15,15 +15,22 @@ set(nn08 PREFIX=nn08 FIXMATH_NO_OVERFLOW FIXMATH_NO_ROUNDING FIXMATH_OPTIMIZE_8B
enable_testing()
+#-fno-sanitize-recover
+set(sanitizer_opts -fsanitize=undefined)
+
add_custom_target(make_tests)
function(create_variant name defs)
add_library(libfixmath_${name} STATIC ${libfixmath-srcs})
target_compile_definitions(libfixmath_${name} PRIVATE ${defs})
+ target_compile_options(libfixmath_${name} PRIVATE ${sanitizer_opts})
+ target_link_options(libfixmath_${name} PRIVATE ${sanitizer_opts})
add_executable(tests_${name} ${tests-srcs})
target_link_libraries(tests_${name} PRIVATE libfixmath_${name} m)
target_include_directories(tests_${name} PRIVATE ${CMAKE_SOURCE_DIR})
target_compile_definitions(tests_${name} PRIVATE ${defs})
+ target_compile_options(tests_${name} PRIVATE ${sanitizer_opts})
+ target_link_options(tests_${name} PRIVATE ${sanitizer_opts})
add_dependencies(make_tests tests_${name})
add_test(NAME tests_${name} COMMAND tests_${name})
endfunction()
diff --git a/tests/tests.h b/tests/tests.h
index 6bd8e4d..72e7801 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -5,14 +5,15 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
extern unsigned stack_depth;
#define delta(a, b) (((a) >= (b)) ? (a) - (b) : (b) - (a))
#define COMMENT(x) printf("\n----" x "----\n");
-#define STR(x) #x
-#define STR2(x) STR(x)
+#define STR(x) #x
+#define STR2(x) STR(x)
#define TEST(x) \
do \
{ \
@@ -71,6 +72,34 @@ extern unsigned stack_depth;
} \
} while (0)
+#define ASSERT_EQ_STR(a, b) \
+ do \
+ { \
+ size_t la = strlen(a); \
+ size_t lb = strlen(b); \
+ if (la != lb) \
+ { \
+ fflush(stdout); \
+ fflush(stderr); \
+ fprintf(stderr, \
+ "\033[31;1m FAILED:\033[22;39m%*sASSERT_EQ a: %s, b: " \
+ "%s\033[0m at: %s(), " __FILE__ ":" STR2(__LINE__) "\n", \
+ stack_depth, "", (a), (b), __func__); \
+ return 1; \
+ } \
+ int res = strncmp((a), (b), la); \
+ if (res != 0) \
+ { \
+ fflush(stdout); \
+ fflush(stderr); \
+ fprintf(stderr, \
+ "\033[31;1m FAILED:\033[22;39m%*sASSERT_EQ a: %s, b: " \
+ "%s\033[0m at: %s(), " __FILE__ ":" STR2(__LINE__) "\n", \
+ stack_depth, "", (a), (b), __func__); \
+ return 1; \
+ } \
+ } while (0)
+
extern const fix16_t testcases[102];
#define TESTCASES_COUNT (sizeof(testcases) / sizeof(testcases[0]))
diff --git a/tests/tests_basic.c b/tests/tests_basic.c
index 6037ae2..8fd3580 100644
--- a/tests/tests_basic.c
+++ b/tests/tests_basic.c
@@ -5,11 +5,11 @@ int test_abs_short(void)
{
for (unsigned i = 0; i < TESTCASES_COUNT; ++i)
{
- fix16_t a = testcases[i];
- double fa = fix16_to_dbl(a);
- fix16_t result = fix16_abs(a);
- double fresult = fabs(fa);
- double min = fix16_to_dbl(fix16_minimum);
+ fix16_t a = testcases[i];
+ double fa = fix16_to_dbl(a);
+ fix16_t result = fix16_abs(a);
+ double fresult = fabs(fa);
+ double min = fix16_to_dbl(fix16_minimum);
if (fa <= min)
{
#ifndef FIXMATH_NO_OVERFLOW
diff --git a/tests/tests_macros.c b/tests/tests_macros.c
new file mode 100644
index 0000000..bb80c79
--- /dev/null
+++ b/tests/tests_macros.c
@@ -0,0 +1,100 @@
+#include "tests_macros.h"
+#include "tests.h"
+
+#define DO_TEST(i, m) \
+ do \
+ { \
+ ASSERT_EQ_INT(F16(i##.##m), F16C(i, m)); \
+ ASSERT_EQ_INT(F16(i##.##m), fix16_from_dbl(i##.##m)); \
+ } while (0)
+
+int test_macros()
+{
+ DO_TEST(1, 234);
+ DO_TEST(0, 0);
+ DO_TEST(1, 0);
+ DO_TEST(-1, 0);
+ DO_TEST(1, 5);
+ DO_TEST(-1, 5);
+ DO_TEST(000000, 00000);
+ DO_TEST(0, 00001);
+ DO_TEST(0, 00010);
+ DO_TEST(0, 1);
+ DO_TEST(0, 10001);
+ DO_TEST(0, 11000);
+ DO_TEST(25, 133);
+ DO_TEST(32767, 00000);
+ DO_TEST(32767, 00001);
+ DO_TEST(32767, 99999);
+ DO_TEST(0, 25);
+ DO_TEST(0, 99555);
+ DO_TEST(0, 99998);
+ DO_TEST(0, 99999);
+ DO_TEST(-1, 1);
+ DO_TEST(-25, 133);
+ DO_TEST(-32767, 00001);
+ DO_TEST(-32768, 00000);
+
+ /* Random values */
+ DO_TEST(0, 02267);
+ DO_TEST(1, 49887);
+ DO_TEST(0, 27589);
+ DO_TEST(0, 38393);
+ DO_TEST(0, 08934);
+ DO_TEST(0, 95820);
+ DO_TEST(0, 95596);
+ DO_TEST(72, 10642);
+ DO_TEST(0, 48939);
+ DO_TEST(3, 37797);
+ DO_TEST(1, 09194);
+ DO_TEST(0, 08605);
+ DO_TEST(3, 04349);
+ DO_TEST(3, 95401);
+ DO_TEST(15, 36292);
+ DO_TEST(56, 09242);
+ DO_TEST(0, 54071);
+ DO_TEST(27, 08953);
+ DO_TEST(0, 03913);
+ DO_TEST(1, 32707);
+ DO_TEST(4, 50117);
+ DO_TEST(0, 24990);
+ DO_TEST(44, 77319);
+ DO_TEST(2, 59139);
+ DO_TEST(0, 16279);
+ DO_TEST(17, 14712);
+ DO_TEST(11, 54281);
+ DO_TEST(0, 02768);
+ DO_TEST(0, 39278);
+ DO_TEST(0, 19369);
+ DO_TEST(-0, 04534);
+ DO_TEST(-0, 00349);
+ DO_TEST(-2, 30380);
+ DO_TEST(-0, 03061);
+ DO_TEST(-7, 50065);
+ DO_TEST(-3, 97050);
+ DO_TEST(-0, 43898);
+ DO_TEST(-3, 49876);
+ DO_TEST(-1, 35942);
+ DO_TEST(-10, 81154);
+ DO_TEST(-0, 26676);
+ DO_TEST(-9, 52134);
+ DO_TEST(-0, 42592);
+ DO_TEST(-0, 05424);
+ DO_TEST(-0, 62461);
+ DO_TEST(-0, 21562);
+ DO_TEST(-0, 22366);
+ DO_TEST(-0, 09074);
+ DO_TEST(-1, 29527);
+ DO_TEST(-4, 98427);
+ DO_TEST(-0, 10721);
+ DO_TEST(-11, 39446);
+ DO_TEST(-451, 53916);
+ DO_TEST(-0, 04279);
+ DO_TEST(-3, 36543);
+ DO_TEST(-0, 01003);
+ DO_TEST(-12, 08326);
+ DO_TEST(-1, 07143);
+ DO_TEST(-1, 07737);
+ DO_TEST(-0, 22957);
+ return 0;
+}
diff --git a/tests/tests_macros.h b/tests/tests_macros.h
new file mode 100644
index 0000000..75ab0f3
--- /dev/null
+++ b/tests/tests_macros.h
@@ -0,0 +1,6 @@
+#ifndef TESTS_MACROS_H
+#define TESTS_MACROS_H
+
+int test_macros();
+
+#endif // TESTS_MACROS_H
diff --git a/tests/tests_str.c b/tests/tests_str.c
new file mode 100644
index 0000000..d893ffb
--- /dev/null
+++ b/tests/tests_str.c
@@ -0,0 +1,108 @@
+#include "tests_str.h"
+#include "tests.h"
+
+int test_str_to()
+{
+ char buf[13];
+ fix16_to_str(fix16_from_dbl(1234.5678), buf, 4);
+ ASSERT_EQ_STR(buf, "1234.5678");
+
+ fix16_to_str(fix16_from_dbl(-1234.5678), buf, 4);
+ ASSERT_EQ_STR(buf, "-1234.5678");
+
+ fix16_to_str(0, buf, 0);
+ ASSERT_EQ_STR(buf, "0");
+
+ fix16_to_str(fix16_from_dbl(0.9), buf, 0);
+ ASSERT_EQ_STR(buf, "1");
+
+ fix16_to_str(1, buf, 5);
+ ASSERT_EQ_STR(buf, "0.00002");
+
+ fix16_to_str(-1, buf, 5);
+ ASSERT_EQ_STR(buf, "-0.00002");
+
+ fix16_to_str(65535, buf, 5);
+ ASSERT_EQ_STR(buf, "0.99998");
+
+ fix16_to_str(65535, buf, 4);
+ ASSERT_EQ_STR(buf, "1.0000");
+
+ fix16_to_str(fix16_maximum, buf, 5);
+ ASSERT_EQ_STR(buf, "32767.99998");
+
+ fix16_to_str(fix16_minimum, buf, 5);
+ ASSERT_EQ_STR(buf, "-32768.00000");
+
+ return 0;
+}
+
+int test_str_from()
+{
+ ASSERT_EQ_INT(fix16_from_str("1234.5678"), fix16_from_dbl(1234.5678));
+ ASSERT_EQ_INT(fix16_from_str("-1234.5678"), fix16_from_dbl(-1234.5678));
+ ASSERT_EQ_INT(fix16_from_str(" +1234,56780 "),
+ fix16_from_dbl(1234.5678));
+
+ ASSERT_EQ_INT(fix16_from_str("0"), 0);
+ ASSERT_EQ_INT(fix16_from_str("1"), fix16_one);
+ ASSERT_EQ_INT(fix16_from_str("1.0"), fix16_one);
+ ASSERT_EQ_INT(fix16_from_str("1.0000000000"), fix16_one);
+
+ ASSERT_EQ_INT(fix16_from_str("0.00002"), 1);
+ ASSERT_EQ_INT(fix16_from_str("0.99998"), 65535);
+
+ ASSERT_EQ_INT(fix16_from_str("32767.99998"), fix16_maximum);
+ ASSERT_EQ_INT(fix16_from_str("-32768.00000"), fix16_minimum);
+
+ return 0;
+}
+
+int test_str_extended()
+{
+
+ fix16_t value = fix16_minimum;
+ char testbuf[13];
+ char goodbuf[13];
+
+ while (value < fix16_maximum)
+ {
+ double fvalue = fix16_to_dbl(value);
+
+ /* Turns out we have to jump through some hoops to round
+ doubles perfectly for printing:
+ http://stackoverflow.com/questions/994764/rounding-doubles-5-sprintf
+ */
+ fvalue = round(fvalue * 100000.) / 100000.;
+
+ snprintf(goodbuf, 13, "%0.5f", fvalue);
+ fix16_to_str(value, testbuf, 5);
+
+ if (strcmp(goodbuf, testbuf) != 0)
+ {
+ printf("Value (fix16_t)%d gave %s, should be %s\n", value, testbuf,
+ goodbuf);
+ return 1;
+ }
+
+ fix16_t roundtrip = fix16_from_str(testbuf);
+ if (roundtrip != value)
+ {
+ printf("Roundtrip failed: (fix16_t)%d -> %s -> (fix16_t)%d\n",
+ value, testbuf, roundtrip);
+ return 1;
+ }
+
+ value += 0x10001;
+ }
+
+ return 0;
+}
+
+int test_str()
+{
+ TEST(test_str_to());
+ TEST(test_str_from());
+ TEST(test_str_extended());
+ return 0;
+}
diff --git a/tests/tests_str.h b/tests/tests_str.h
new file mode 100644
index 0000000..bb072ea
--- /dev/null
+++ b/tests/tests_str.h
@@ -0,0 +1,6 @@
+#ifndef TESTS_STR_H
+#define TESTS_STR_H
+
+int test_str();
+
+#endif // TESTS_STR_H