parent
951f522b13
commit
35eb7753d2
|
@ -158,3 +158,7 @@ compile_commands.json
|
|||
*creator.user*
|
||||
|
||||
*_qmlcache.qrc
|
||||
|
||||
benchmarks/testcases.c
|
||||
|
||||
*.elf
|
||||
|
|
|
@ -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})
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
|
@ -0,0 +1,3 @@
|
|||
file(GLOB libfixmath-srcs libfixmath/*.h libfixmath/*.hpp libfixmath/*.c)
|
||||
|
||||
add_library(libfixmath STATIC ${libfixmath-srcs})
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/env bash
|
||||
for i in $(ls -1 tests_*); do ./$i; done
|
|
@ -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;
|
||||
}
|
|
@ -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}")
|
||||
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef TESTS_LERP_H
|
||||
#define TESTS_LERP_H
|
||||
|
||||
int test_lerp();
|
||||
|
||||
#endif // TESTS_LERP_H
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef TESTS_SQRT_H
|
||||
#define TESTS_SQRT_H
|
||||
|
||||
int test_sqrt();
|
||||
|
||||
#endif // TESTS_SQRT_H
|
|
@ -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 \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <fix16.h>
|
||||
#include <libfixmath/fix16.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
Loading…
Reference in New Issue