aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Baƙinka <marun1@email.cz>2021-04-29 08:40:06 +0200
committerGitHub <noreply@github.com>2021-04-29 09:40:06 +0300
commit35eb7753d29a9ad14b145a09c057a88131d6ede0 (patch)
treeebe2b69d32e12126c8a1e49c5e1d0012044c2bfa
parent951f522b13b1ea0068345369a98d18d862b29582 (diff)
New unittests (#28)
Refactor unittests
-rw-r--r--.gitignore4
-rw-r--r--CMakeLists.txt22
-rw-r--r--benchmarks/Makefile5
-rw-r--r--libfixmath/fix16.h1
-rw-r--r--libfixmath/fix16_fft.c (renamed from contrib/fix16_fft.c)2
-rw-r--r--libfixmath/libfixmath.cmake3
-rwxr-xr-xtests/run_tests2
-rw-r--r--tests/tests.c51
-rw-r--r--tests/tests.cmake44
-rw-r--r--tests/tests.h80
-rw-r--r--tests/tests_basic.c246
-rw-r--r--tests/tests_basic.h10
-rw-r--r--tests/tests_lerp.c33
-rw-r--r--tests/tests_lerp.h6
-rw-r--r--tests/tests_sqrt.c37
-rw-r--r--tests/tests_sqrt.h6
-rw-r--r--unittests/Makefile2
-rw-r--r--unittests/fix16_exp_unittests.c2
-rw-r--r--unittests/fix16_unittests.c4
19 files changed, 545 insertions, 15 deletions
diff --git a/.gitignore b/.gitignore
index a6cb559..59904ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -158,3 +158,7 @@ compile_commands.json
*creator.user*
*_qmlcache.qrc
+
+benchmarks/testcases.c
+
+*.elf
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 75b7322..204ef3b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,25 +4,29 @@ project(libfixmath LANGUAGES CXX C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
-set(CMAKE_C_FLAGS "-Wall -pedantic -Wextra")
+set(CMAKE_C_FLAGS "-Wall -pedantic -Wextra -Werror=return-type")
-set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_FLAGS "-Wall -pedantic -Wextra")
+set(CMAKE_CXX_FLAGS "-Wall -pedantic -Wextra -Werror=return-type")
+
+include(libfixmath/libfixmath.cmake)
+include(tests/tests.cmake)
-file(GLOB libfixmath-srcs libfixmath/*.h libfixmath/*.hpp libfixmath/*.c)
-file(GLOB contrib-srcs contrib/*.c)
file(GLOB fixsingen-srcs fixsingen/*.c)
file(GLOB fixtest-srcs fixtest/*.c fixtest/*.h)
-
-add_library(libfixmath STATIC ${libfixmath-srcs} ${contrib-srcs})
-target_include_directories(libfixmath PRIVATE ${CMAKE_SOURCE_DIR})
+file(GLOB unittests-srcs unittests/*.c unittests/*.h)
add_executable(fixtest ${fixtest-srcs})
target_link_libraries(fixtest PRIVATE libfixmath m)
target_include_directories(fixtest PRIVATE ${CMAKE_SOURCE_DIR})
-
add_executable(fixsingen ${fixsingen-srcs})
target_link_libraries(fixsingen PRIVATE libfixmath m)
target_include_directories(fixsingen PRIVATE ${CMAKE_SOURCE_DIR})
+
+add_executable(unittests ${unittests-srcs})
+target_link_libraries(unittests PRIVATE libfixmath m)
+target_include_directories(unittests PRIVATE ${CMAKE_SOURCE_DIR})
+
+
diff --git a/benchmarks/Makefile b/benchmarks/Makefile
index efd450e..6331596 100644
--- a/benchmarks/Makefile
+++ b/benchmarks/Makefile
@@ -6,6 +6,9 @@ FILES = benchmark.c ../libfixmath/fix16.c ../libfixmath/fix16_sqrt.c ../libfixma
CFLAGS = -DFIXMATH_NO_OVERFLOW -DFIXMATH_NO_ROUNDING -ffast-math -I../libfixmath
+.PHONY clean:
+ rm -f *.elf
+
testcases.c: generate_testcases.py
python $<
@@ -23,7 +26,7 @@ run-benchmark-arm: benchmark-arm.elf
benchmark-avr.elf: $(FILES) interface-avr.c testcases.c
avr-gcc -Wall -mmcu=atmega128 $(CFLAGS) \
- -Wall -O2 -DFIXMATH_OPTIMIZE_8BIT \
+ -O2 -DFIXMATH_OPTIMIZE_8BIT \
-o $@ -I .. $(FILES) interface-avr.c
run-benchmark-avr: benchmark-avr.elf
diff --git a/libfixmath/fix16.h b/libfixmath/fix16.h
index eeb0b99..79c0090 100644
--- a/libfixmath/fix16.h
+++ b/libfixmath/fix16.h
@@ -38,6 +38,7 @@ static const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicat
static const fix16_t fix16_pi = 205887; /*!< fix16_t value of pi */
static const fix16_t fix16_e = 178145; /*!< fix16_t value of e */
static const fix16_t fix16_one = 0x00010000; /*!< fix16_t value of 1 */
+static const fix16_t fix16_eps = 1; /*!< fix16_t epsilon */
/* Conversion functions between fix16_t and float/integer.
* These are inlined to allow compiler to optimize away constant numbers
diff --git a/contrib/fix16_fft.c b/libfixmath/fix16_fft.c
index 8259083..1a5aeb3 100644
--- a/contrib/fix16_fft.c
+++ b/libfixmath/fix16_fft.c
@@ -9,7 +9,7 @@
*/
#include <stdint.h>
-#include <libfixmath/fix16.h>
+#include "fix16.h"
// You can change the input datatype and intermediate scaling here.
// By default, the output is divided by the transform length to get a normalized FFT.
diff --git a/libfixmath/libfixmath.cmake b/libfixmath/libfixmath.cmake
new file mode 100644
index 0000000..e4e7018
--- /dev/null
+++ b/libfixmath/libfixmath.cmake
@@ -0,0 +1,3 @@
+file(GLOB libfixmath-srcs libfixmath/*.h libfixmath/*.hpp libfixmath/*.c)
+
+add_library(libfixmath STATIC ${libfixmath-srcs})
diff --git a/tests/run_tests b/tests/run_tests
new file mode 100755
index 0000000..bca1d68
--- /dev/null
+++ b/tests/run_tests
@@ -0,0 +1,2 @@
+#!/bin/env bash
+for i in $(ls -1 tests_*); do ./$i; done
diff --git a/tests/tests.c b/tests/tests.c
new file mode 100644
index 0000000..cef9710
--- /dev/null
+++ b/tests/tests.c
@@ -0,0 +1,51 @@
+#include "tests.h"
+#include "tests_basic.h"
+#include "tests_lerp.h"
+#include "tests_sqrt.h"
+#include <stdio.h>
+
+const fix16_t testcases[] = {
+ // Small numbers
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10,
+
+ // Integer numbers
+ 0x10000, -0x10000, 0x20000, -0x20000, 0x30000, -0x30000, 0x40000, -0x40000,
+ 0x50000, -0x50000, 0x60000, -0x60000,
+
+ // Fractions (1/2, 1/4, 1/8)
+ 0x8000, -0x8000, 0x4000, -0x4000, 0x2000, -0x2000,
+
+ // Problematic carry
+ 0xFFFF, -0xFFFF, 0x1FFFF, -0x1FFFF, 0x3FFFF, -0x3FFFF,
+
+ // Smallest and largest values
+ 0x7FFFFFFF, 0x80000000,
+
+ // Large random numbers
+ 831858892, 574794913, 2147272293, -469161054, -961611615, 1841960234,
+ 1992698389, 520485404, 560523116, -2094993050, -876897543, -67813629,
+ 2146227091, 509861939, -1073573657,
+
+ // Small random numbers
+ -14985, 30520, -83587, 41129, 42137, 58537, -2259, 84142, -28283, 90914,
+ 19865, 33191, 81844, -66273, -63215, -44459, -11326, 84295, 47515, -39324,
+
+ // Tiny random numbers
+ -171, -359, 491, 844, 158, -413, -422, -737, -575, -330, -376, 435, -311,
+ 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");
+ TEST(test_abs());
+ TEST(test_add());
+ TEST(test_mul());
+ TEST(test_div());
+ TEST(test_sub());
+ TEST(test_sqrt());
+ TEST(test_lerp());
+ return 0;
+}
diff --git a/tests/tests.cmake b/tests/tests.cmake
new file mode 100644
index 0000000..56aefe3
--- /dev/null
+++ b/tests/tests.cmake
@@ -0,0 +1,44 @@
+file(GLOB tests-srcs tests/*.c tests/*.h)
+
+set(ro64 PREFIX=ro64)
+set(no64 PREFIX=no64 FIXMATH_NO_ROUNDING)
+set(rn64 PREFIX=rn64 FIXMATH_NO_OVERFLOW)
+set(nn64 PREFIX=nn64 FIXMATH_NO_ROUNDING FIXMATH_NO_OVERFLOW)
+set(ro32 PREFIX=ro32 FIXMATH_NO_64BIT)
+set(no32 PREFIX=no32 FIXMATH_NO_ROUNDING FIXMATH_NO_64BIT)
+set(rn32 PREFIX=rn32 FIXMATH_NO_OVERFLOW FIXMATH_NO_64BIT)
+set(nn32 PREFIX=nn32 FIXMATH_NO_OVERFLOW FIXMATH_NO_ROUNDING FIXMATH_NO_64BIT)
+set(ro08 PREFIX=ro08 FIXMATH_OPTIMIZE_8BIT)
+set(no08 PREFIX=no08 FIXMATH_NO_ROUNDING FIXMATH_OPTIMIZE_8BIT)
+set(rn08 PREFIX=rn08 FIXMATH_NO_OVERFLOW FIXMATH_OPTIMIZE_8BIT)
+set(nn08 PREFIX=nn08 FIXMATH_NO_OVERFLOW FIXMATH_NO_ROUNDING FIXMATH_OPTIMIZE_8BIT)
+
+configure_file(tests/run_tests ${CMAKE_BINARY_DIR}/run_tests COPYONLY)
+
+add_custom_target(tests)
+
+function(create_variant name defs)
+ add_library(libfixmath_${name} STATIC ${libfixmath-srcs})
+ target_compile_definitions(libfixmath_${name} PRIVATE ${defs})
+ 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})
+ add_dependencies(tests tests_${name})
+endfunction()
+
+
+create_variant("ro64" "${ro64}")
+create_variant("no64" "${no64}")
+create_variant("rn64" "${rn64}")
+create_variant("nn64" "${nn64}")
+create_variant("ro32" "${ro32}")
+create_variant("no32" "${no32}")
+create_variant("rn32" "${rn32}")
+create_variant("nn32" "${nn32}")
+create_variant("ro08" "${ro08}")
+create_variant("no08" "${no08}")
+create_variant("rn08" "${rn08}")
+create_variant("nn08" "${nn08}")
+
+
diff --git a/tests/tests.h b/tests/tests.h
new file mode 100644
index 0000000..6be58db
--- /dev/null
+++ b/tests/tests.h
@@ -0,0 +1,80 @@
+#ifndef TESTS_H
+#define TESTS_H
+
+#include <libfixmath/fix16.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.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 TEST(x) \
+ do \
+ { \
+ ++stack_depth; \
+ if ((x)) \
+ { \
+ fflush(stdout); \
+ fflush(stderr); \
+ fprintf(stdout, \
+ "\033[31;1m FAILED:\033[22;39m%*s" #x \
+ " \033[0mat: " __FILE__ ":" STR2(__LINE__) " \n", \
+ stack_depth, ""); \
+ --stack_depth; \
+ return 1; \
+ } \
+ else \
+ { \
+ fflush(stdout); \
+ fflush(stderr); \
+ printf("\033[32;1m OK:\033[22;39m%*s" #x "\n\033[0m", \
+ stack_depth, ""); \
+ } \
+ --stack_depth; \
+ } while (0)
+
+#define ASSERT_NEAR_DOUBLE(a, b, eps, ...) \
+ do \
+ { \
+ if ((delta((a), (b)) >= (eps))) \
+ { \
+ fflush(stdout); \
+ fflush(stderr); \
+ fprintf(stdout, \
+ "\033[31;1m FAILED:\033[22;39m%*sASSERT_NEAR a: %f, b: " \
+ "%f, eps: %f\033[0m at: %s(), " __FILE__ \
+ ":" STR2(__LINE__) "\n", \
+ stack_depth, "", (a), (b), (eps), __func__); \
+ fprintf(stdout, " %*s", stack_depth, ""); \
+ fprintf(stdout, __VA_ARGS__); \
+ return 1; \
+ } \
+ } while (0)
+
+#define ASSERT_EQ_INT(a, b) \
+ do \
+ { \
+ if ((a) != (b)) \
+ { \
+ fflush(stdout); \
+ fflush(stderr); \
+ fprintf(stdout, \
+ "\033[31;1m FAILED:\033[22;39m%*sASSERT_EQ a: %i, b: " \
+ "%i\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]))
+
+#define delta(a, b) (((a) >= (b)) ? (a) - (b) : (b) - (a))
+
+#endif // TESTS_H
diff --git a/tests/tests_basic.c b/tests/tests_basic.c
new file mode 100644
index 0000000..6037ae2
--- /dev/null
+++ b/tests/tests_basic.c
@@ -0,0 +1,246 @@
+#include "tests_basic.h"
+#include "tests.h"
+
+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);
+ if (fa <= 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), "in: %f", fa);
+ }
+ }
+ return 0;
+}
+
+int test_abs(void)
+{
+ TEST(test_abs_short());
+ return 0;
+}
+
+int test_add_short(void)
+{
+ for (unsigned i = 0; i < TESTCASES_COUNT; ++i)
+ {
+ for (unsigned j = 0; j < TESTCASES_COUNT; ++j)
+ {
+ fix16_t a = testcases[i];
+ fix16_t b = testcases[j];
+ fix16_t result = fix16_add(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);
+ 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), "%f + %f", fa, fb);
+ }
+ }
+ }
+ return 0;
+}
+
+int test_add(void)
+{
+ TEST(test_add_short());
+ return 0;
+}
+
+int test_mul_specific(void)
+{
+ ASSERT_EQ_INT(fix16_mul(fix16_from_int(5), fix16_from_int(5)),
+ fix16_from_int(25));
+ ASSERT_EQ_INT(fix16_mul(fix16_from_int(-5), fix16_from_int(5)),
+ fix16_from_int(-25));
+ ASSERT_EQ_INT(fix16_mul(fix16_from_int(-5), fix16_from_int(-5)),
+ fix16_from_int(25));
+ ASSERT_EQ_INT(fix16_mul(fix16_from_int(5), fix16_from_int(-5)),
+ fix16_from_int(-25));
+
+ ASSERT_EQ_INT(fix16_mul(0, 10), 0);
+ ASSERT_EQ_INT(fix16_mul(2, 0x8000), 1);
+ ASSERT_EQ_INT(fix16_mul(-2, 0x8000), -1);
+#ifndef FIXMATH_NO_ROUNDING
+ ASSERT_EQ_INT(fix16_mul(3, 0x8000), 2);
+ ASSERT_EQ_INT(fix16_mul(2, 0x7FFF), 1);
+ ASSERT_EQ_INT(fix16_mul(-2, 0x8001), -1);
+ ASSERT_EQ_INT(fix16_mul(-3, 0x8000), -2);
+ ASSERT_EQ_INT(fix16_mul(-2, 0x7FFF), -1);
+ ASSERT_EQ_INT(fix16_mul(2, 0x8001), 1);
+#endif
+ return 0;
+}
+
+int test_mul_short()
+{
+ for (unsigned i = 0; i < TESTCASES_COUNT; ++i)
+ {
+ for (unsigned j = 0; j < TESTCASES_COUNT; ++j)
+ {
+ fix16_t a = testcases[i];
+ fix16_t b = testcases[j];
+ fix16_t result = fix16_mul(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);
+
+ 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), "%f * %f", fa, fb);
+ }
+ }
+ }
+ return 0;
+}
+
+int test_mul(void)
+{
+ TEST(test_mul_specific());
+ TEST(test_mul_short());
+ return 0;
+}
+
+int test_div_specific()
+{
+ ASSERT_EQ_INT(fix16_div(fix16_from_int(15), fix16_from_int(5)),
+ fix16_from_int(3));
+ ASSERT_EQ_INT(fix16_div(fix16_from_int(-15), fix16_from_int(5)),
+ fix16_from_int(-3));
+ ASSERT_EQ_INT(fix16_div(fix16_from_int(-15), fix16_from_int(-5)),
+ fix16_from_int(3));
+ ASSERT_EQ_INT(fix16_div(fix16_from_int(15), fix16_from_int(-5)),
+ fix16_from_int(-3));
+
+#ifndef FIXMATH_NO_ROUNDING
+ ASSERT_EQ_INT(fix16_div(0, 10), 0);
+ ASSERT_EQ_INT(fix16_div(1, fix16_from_int(2)), 1);
+ ASSERT_EQ_INT(fix16_div(-1, fix16_from_int(2)), -1);
+ ASSERT_EQ_INT(fix16_div(1, fix16_from_int(-2)), -1);
+ ASSERT_EQ_INT(fix16_div(-1, fix16_from_int(-2)), 1);
+ ASSERT_EQ_INT(fix16_div(3, fix16_from_int(2)), 2);
+ ASSERT_EQ_INT(fix16_div(-3, fix16_from_int(2)), -2);
+ ASSERT_EQ_INT(fix16_div(3, fix16_from_int(-2)), -2);
+ ASSERT_EQ_INT(fix16_div(-3, fix16_from_int(-2)), 2);
+ ASSERT_EQ_INT(fix16_div(2, 0x7FFF), 4);
+ ASSERT_EQ_INT(fix16_div(-2, 0x7FFF), -4);
+ ASSERT_EQ_INT(fix16_div(2, 0x8001), 4);
+ ASSERT_EQ_INT(fix16_div(-2, 0x8001), -4);
+#endif
+
+ return 0;
+}
+
+int test_div_short()
+{
+ for (unsigned i = 0; i < TESTCASES_COUNT; ++i)
+ {
+ for (unsigned j = 0; j < TESTCASES_COUNT; ++j)
+ {
+ fix16_t a = testcases[i];
+ fix16_t b = testcases[j];
+ // We don't require a solution for /0 :)
+ if (b == 0)
+ continue;
+ 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);
+
+ 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);
+ }
+ }
+ }
+ return 0;
+}
+
+int test_div(void)
+{
+ TEST(test_div_specific());
+ TEST(test_div_short());
+ return 0;
+}
+
+int test_sub_short()
+{
+ for (unsigned i = 0; i < TESTCASES_COUNT; ++i)
+ {
+ for (unsigned j = 0; j < TESTCASES_COUNT; ++j)
+ {
+ fix16_t a = testcases[i];
+ fix16_t b = testcases[j];
+ fix16_t result = fix16_sub(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);
+ 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), "%f - %f", fa, fb);
+ }
+ }
+ }
+ return 0;
+}
+
+int test_sub()
+{
+ TEST(test_sub_short());
+ return 0;
+}
diff --git a/tests/tests_basic.h b/tests/tests_basic.h
new file mode 100644
index 0000000..a51f283
--- /dev/null
+++ b/tests/tests_basic.h
@@ -0,0 +1,10 @@
+#ifndef TESTS_BASIC_H
+#define TESTS_BASIC_H
+
+int test_abs(void);
+int test_add(void);
+int test_mul(void);
+int test_div(void);
+int test_sub();
+
+#endif // TESTS_BASIC_H
diff --git a/tests/tests_lerp.c b/tests/tests_lerp.c
new file mode 100644
index 0000000..b3a04f6
--- /dev/null
+++ b/tests/tests_lerp.c
@@ -0,0 +1,33 @@
+#include "tests_lerp.h"
+#include "tests.h"
+
+int test_lerp()
+{
+ ASSERT_EQ_INT(fix16_lerp8(0, 2, 0), 0);
+ ASSERT_EQ_INT(fix16_lerp8(0, 2, 127), 0);
+ ASSERT_EQ_INT(fix16_lerp8(0, 2, 128), 1);
+ ASSERT_EQ_INT(fix16_lerp8(0, 2, 255), 1);
+ ASSERT_EQ_INT(fix16_lerp8(fix16_minimum, fix16_maximum, 0), fix16_minimum);
+ ASSERT_EQ_INT(fix16_lerp8(fix16_minimum, fix16_maximum, 255),
+ (fix16_maximum - (1 << 24)));
+ ASSERT_EQ_INT(fix16_lerp8(-fix16_maximum, fix16_maximum, 128), 0);
+
+ ASSERT_EQ_INT(fix16_lerp16(0, 2, 0), 0);
+ ASSERT_EQ_INT(fix16_lerp16(0, 2, 0x7fff), 0);
+ ASSERT_EQ_INT(fix16_lerp16(0, 2, 0x8000), 1);
+ ASSERT_EQ_INT(fix16_lerp16(0, 2, 0xffff), 1);
+ ASSERT_EQ_INT(fix16_lerp16(fix16_minimum, fix16_maximum, 0), fix16_minimum);
+ ASSERT_EQ_INT(fix16_lerp16(fix16_minimum, fix16_maximum, 0xffff),
+ (fix16_maximum - (1 << 16)));
+ ASSERT_EQ_INT(fix16_lerp16(-fix16_maximum, fix16_maximum, 0x8000), 0);
+
+ ASSERT_EQ_INT(fix16_lerp32(0, 2, 0), 0);
+ ASSERT_EQ_INT(fix16_lerp32(0, 2, 0x7fffffff), 0);
+ ASSERT_EQ_INT(fix16_lerp32(0, 2, 0x80000000), 1);
+ ASSERT_EQ_INT(fix16_lerp32(0, 2, 0xffffffff), 1);
+ ASSERT_EQ_INT(fix16_lerp32(fix16_minimum, fix16_maximum, 0), fix16_minimum);
+ ASSERT_EQ_INT(fix16_lerp32(fix16_minimum, fix16_maximum, 0xffffffff),
+ (fix16_maximum - 1));
+ ASSERT_EQ_INT(fix16_lerp32(-fix16_maximum, fix16_maximum, 0x80000000), 0);
+ return 0;
+}
diff --git a/tests/tests_lerp.h b/tests/tests_lerp.h
new file mode 100644
index 0000000..ab261dd
--- /dev/null
+++ b/tests/tests_lerp.h
@@ -0,0 +1,6 @@
+#ifndef TESTS_LERP_H
+#define TESTS_LERP_H
+
+int test_lerp();
+
+#endif // TESTS_LERP_H
diff --git a/tests/tests_sqrt.c b/tests/tests_sqrt.c
new file mode 100644
index 0000000..8faf016
--- /dev/null
+++ b/tests/tests_sqrt.c
@@ -0,0 +1,37 @@
+#include "tests_sqrt.h"
+#include "tests.h"
+
+int test_sqrt_specific()
+{
+ ASSERT_EQ_INT(fix16_sqrt(fix16_from_int(16)), fix16_from_int(4));
+ ASSERT_EQ_INT(fix16_sqrt(fix16_from_int(100)), fix16_from_int(10));
+ ASSERT_EQ_INT(fix16_sqrt(fix16_from_int(1)), fix16_from_int(1));
+#ifndef FIXMATH_NO_ROUNDING
+ ASSERT_EQ_INT(fix16_sqrt(214748302), 3751499);
+ ASSERT_EQ_INT(fix16_sqrt(214748303), 3751499);
+ ASSERT_EQ_INT(fix16_sqrt(214748359), 3751499);
+ ASSERT_EQ_INT(fix16_sqrt(214748360), 3751500);
+#endif
+ return 0;
+}
+
+int test_sqrt_short()
+{
+ for (unsigned i = 0; i < TESTCASES_COUNT; ++i)
+ {
+ fix16_t a = testcases[i];
+ double fa = fix16_to_dbl(a);
+ fix16_t result = fix16_sqrt(a);
+ double fresult = sqrt(fa);
+ ASSERT_NEAR_DOUBLE(fresult, fix16_to_dbl(result), fix16_to_dbl(1),
+ "in: %f", fa);
+ }
+ return 0;
+}
+
+int test_sqrt()
+{
+ TEST(test_sqrt_specific());
+ TEST(test_sqrt_short());
+ return 0;
+}
diff --git a/tests/tests_sqrt.h b/tests/tests_sqrt.h
new file mode 100644
index 0000000..d0e108d
--- /dev/null
+++ b/tests/tests_sqrt.h
@@ -0,0 +1,6 @@
+#ifndef TESTS_SQRT_H
+#define TESTS_SQRT_H
+
+int test_sqrt();
+
+#endif // TESTS_SQRT_H
diff --git a/unittests/Makefile b/unittests/Makefile
index 78433fe..612be42 100644
--- a/unittests/Makefile
+++ b/unittests/Makefile
@@ -2,7 +2,7 @@
CC = gcc
# Basic CFLAGS for debugging
-CFLAGS = -g -O0 -I../libfixmath -Wall -Wextra -Werror
+CFLAGS = -g -O0 -I../libfixmath -I.. -Wall -Wextra -Werror
# The files required for tests
FIX16_SRC = ../libfixmath/fix16.c ../libfixmath/fix16_sqrt.c ../libfixmath/fix16_str.c \
diff --git a/unittests/fix16_exp_unittests.c b/unittests/fix16_exp_unittests.c
index afb6706..9fc0617 100644
--- a/unittests/fix16_exp_unittests.c
+++ b/unittests/fix16_exp_unittests.c
@@ -1,4 +1,4 @@
-#include <fix16.h>
+#include <libfixmath/fix16.h>
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
diff --git a/unittests/fix16_unittests.c b/unittests/fix16_unittests.c
index 51d8f61..436c979 100644
--- a/unittests/fix16_unittests.c
+++ b/unittests/fix16_unittests.c
@@ -1,8 +1,8 @@
-#include <fix16.h>
+#include <libfixmath/fix16.h>
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
-#include "int64.h"
+#include "libfixmath/int64.h"
#include "unittests.h"
const fix16_t testcases[] = {