From 2859cbf31dd209cba93986c68c2ead37610eae66 Mon Sep 17 00:00:00 2001 From: Chris Hammond Date: Thu, 22 Oct 2020 16:24:49 -0400 Subject: [PATCH] Added unit tests for "lerp" functions, and found several type conversion bugs --- libfixmath/fix16.c | 4 ++-- libfixmath/int64.h | 2 +- unittests/fix16_unittests.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/libfixmath/fix16.c b/libfixmath/fix16.c index 2994905..ed7773a 100644 --- a/libfixmath/fix16.c +++ b/libfixmath/fix16.c @@ -485,7 +485,7 @@ fix16_t fix16_mod(fix16_t x, fix16_t y) fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract) { - int64_t tempOut = int64_mul_i32_i32(inArg0, ((1 << 8) - inFract)); + int64_t tempOut = int64_mul_i32_i32(inArg0, (((int32_t)1 << 8) - inFract)); tempOut = int64_add(tempOut, int64_mul_i32_i32(inArg1, inFract)); tempOut = int64_shift(tempOut, -8); return (fix16_t)int64_lo(tempOut); @@ -502,7 +502,7 @@ fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract) fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract) { int64_t tempOut; - tempOut = ((int64_t)inArg0 * (0 - inFract)); + tempOut = ((int64_t)inArg0 * (((int64_t)1<<32) - inFract)); tempOut += ((int64_t)inArg1 * inFract); tempOut >>= 32; return (fix16_t)tempOut; diff --git a/libfixmath/int64.h b/libfixmath/int64.h index 0479336..82ec9f7 100644 --- a/libfixmath/int64.h +++ b/libfixmath/int64.h @@ -19,7 +19,7 @@ static inline int64_t int64_neg(int64_t x) { return (-x); } static inline int64_t int64_sub(int64_t x, int64_t y) { return (x - y); } static inline int64_t int64_shift(int64_t x, int8_t y) { return (y < 0 ? (x >> -y) : (x << y)); } -static inline int64_t int64_mul_i32_i32(int32_t x, int32_t y) { return (x * y); } +static inline int64_t int64_mul_i32_i32(int32_t x, int32_t y) { return ((int64_t)x * y); } static inline int64_t int64_mul_i64_i32(int64_t x, int32_t y) { return (x * y); } static inline int64_t int64_div_i64_i32(int64_t x, int32_t y) { return (x / y); } diff --git a/unittests/fix16_unittests.c b/unittests/fix16_unittests.c index 9a301a1..b63c25d 100644 --- a/unittests/fix16_unittests.c +++ b/unittests/fix16_unittests.c @@ -330,6 +330,36 @@ int main() TEST(failures == 0); } +#ifndef FIXMATH_NO_64BIT + { + COMMENT("Running linear interpolation test cases"); + + TEST(fix16_lerp8(0, 2, 0) == 0); + TEST(fix16_lerp8(0, 2, 127) == 0); + TEST(fix16_lerp8(0, 2, 128) == 1); + TEST(fix16_lerp8(0, 2, 255) == 1); + TEST(fix16_lerp8(fix16_minimum, fix16_maximum, 0) == fix16_minimum); + TEST(fix16_lerp8(fix16_minimum, fix16_maximum, 255) == (fix16_maximum - (1<<24))); + TEST(fix16_lerp8(-fix16_maximum, fix16_maximum, 128) == 0); + + TEST(fix16_lerp16(0, 2, 0) == 0); + TEST(fix16_lerp16(0, 2, 0x7fff) == 0); + TEST(fix16_lerp16(0, 2, 0x8000) == 1); + TEST(fix16_lerp16(0, 2, 0xffff) == 1); + TEST(fix16_lerp16(fix16_minimum, fix16_maximum, 0) == fix16_minimum); + TEST(fix16_lerp16(fix16_minimum, fix16_maximum, 0xffff) == (fix16_maximum - (1<<16))); + TEST(fix16_lerp16(-fix16_maximum, fix16_maximum, 0x8000) == 0); + + TEST(fix16_lerp32(0, 2, 0) == 0); + TEST(fix16_lerp32(0, 2, 0x7fffffff) == 0); + TEST(fix16_lerp32(0, 2, 0x80000000) == 1); + TEST(fix16_lerp32(0, 2, 0xffffffff) == 1); + TEST(fix16_lerp32(fix16_minimum, fix16_maximum, 0) == fix16_minimum); + TEST(fix16_lerp32(fix16_minimum, fix16_maximum, 0xffffffff) == (fix16_maximum - 1)); + TEST(fix16_lerp32(-fix16_maximum, fix16_maximum, 0x80000000) == 0); + } +#endif + if (status != 0) fprintf(stdout, "\n\nSome tests FAILED!\n");