skullc-peripherals/Tests/fixedpoint.cpp
Erki 983eb74bd7
All checks were successful
continuous-integration/drone/push Build is passing
Add Utility/Fixedpoint module
2021-05-01 01:41:34 +03:00

233 lines
4.6 KiB
C++

//
// Created by erki on 30.04.21.
//
#include <catch2/catch.hpp>
#include "utility_fixedpoint.hpp"
using FP15 = Peripherals::FixedPoint<std::uint32_t, 15>;
TEST_CASE("FP constructors work appropriately.", "[utility],[fixed point]")
{
SECTION("Empty FP constructs with data 0.")
{
FP15 fp;
REQUIRE(fp.data == 0);
}
SECTION("FP with integral data constructors appropriately.")
{
FP15 fp(1);
REQUIRE(fp.data == (1 << 15));
}
SECTION("FP assignment operators work appropriately.")
{
FP15 fp;
fp = 15;
REQUIRE(fp.data == (15 << 15));
}
SECTION("FP with floating point data constructors works appropriately.")
{
FP15 fp(1.5f);
REQUIRE(fp.data == ((1 << 15) | (1 << 14)));
FP15 fp2(1.5);
REQUIRE(fp2.data == ((1 << 15) | (1 << 14)));
}
SECTION("FP assignment operators work with floating point data appropriately.")
{
FP15 fp;
fp = 1.5f;
REQUIRE(fp.data == ((1 << 15) | (1 << 14)));
fp = 1.5;
REQUIRE(fp.data == ((1 << 15) | (1 << 14)));
}
}
TEST_CASE("FP comparison operators work appropriately.", "[utility],[fixed point]")
{
SECTION("FPs compare equal with other FPs appropriately.")
{
const FP15 fp1(15);
const FP15 fp2(15);
REQUIRE(fp1 == fp2);
const FP15 fp3(32);
REQUIRE(fp1 != fp3);
}
SECTION("FPs compare equal with integers appropriately.")
{
const FP15 fp1(15);
REQUIRE(fp1 == 15);
REQUIRE(fp1 != 32);
}
SECTION("FPs compare equal with floats appropriately.")
{
const FP15 fp1(1.45f);
REQUIRE(fp1 == 1.45f);
REQUIRE(fp1 == 1.45);
}
SECTION("FPs compare lt and gt with other FPs appropriately.")
{
const FP15 fp(1.45f);
const FP15 fp2(1.4525f);
const FP15 fp3(1.4475f);
REQUIRE(fp < fp2);
REQUIRE(fp > fp3);
REQUIRE(fp <= fp2);
REQUIRE(fp >= fp3);
REQUIRE(fp <= fp);
REQUIRE(fp >= fp);
REQUIRE(!(fp < fp));
REQUIRE(!(fp > fp));
}
SECTION("FPs compare lt and gt with integers appropriately.")
{
const FP15 fp(15);
REQUIRE(fp < 16);
REQUIRE(fp > 14);
REQUIRE(!(fp < 15));
REQUIRE(!(fp > 15));
REQUIRE(fp <= 15);
REQUIRE(fp <= 16);
REQUIRE(fp >= 15);
REQUIRE(fp >= 14);
}
SECTION("FPs compare lt and gt with floating point numbers appropriately.")
{
const FP15 fp(45.75f);
REQUIRE(fp < 45.80f);
REQUIRE(fp > 45.70f);
REQUIRE(!(fp < 45.75f));
REQUIRE(!(fp > 45.75f));
REQUIRE(fp <= 45.75f);
REQUIRE(fp <= 45.80f);
REQUIRE(fp >= 45.75f);
REQUIRE(fp >= 45.70f);
}
}
TEST_CASE("FP arithmetic operators work appropriately.", "[utility],[fixed point]")
{
SECTION("FPs add with other FPs appropriately.")
{
const FP15 fp1(45.75f);
const FP15 fp2(0.25f);
REQUIRE((fp1 + fp2) == FP15(46));
}
SECTION("FPs subtract from other FPs appropriately.")
{
const FP15 fp1(45.75f);
const FP15 fp2(0.75f);
REQUIRE((fp1 - fp2) == FP15(45));
}
SECTION("FPs add with arithmetic types appropriately.")
{
const FP15 fp(45.75f);
REQUIRE((fp + 10) == FP15(55.75f));
REQUIRE((fp + 0.25f) == FP15(46));
}
SECTION("FPs subtract from arithmetic types appropriately.")
{
const FP15 fp(45.75f);
REQUIRE((fp - 10) == FP15(35.75f));
REQUIRE((fp - 0.75f) == FP15(45));
}
}
TEMPLATE_TEST_CASE("FP converting back to integral values works appropriately.", "[utility],[fixed point]",
std::int8_t, std::int16_t, std::int32_t)
{
using FP = Peripherals::FixedPoint<TestType, 4>;
FP fp(4);
REQUIRE(fp.template toValue<TestType>() == 4);
}
TEMPLATE_TEST_CASE("FP converting back to floating point values works appropriately.", "[utility],[fixed point]",
float, double)
{
FP15 fp(TestType(4.45));
REQUIRE(TestType(fp) == Approx(TestType(4.45)));
}
TEST_CASE("FP multiplication works appropriately.", "[utility],[fixed point]")
{
SECTION("FP multiplies with other FPs appropriately.")
{
FP15 fp1(0.25);
FP15 fp2(0.1);
FP15 fp3 = fp1 * fp2;
REQUIRE(fp3 == FP15(0.025));
}
SECTION("FP multiplies with real values appropriately.")
{
FP15 fp1(0.25);
FP15 fp2 = fp1 * 0.1;
REQUIRE(fp2 == FP15(0.025));
}
}
TEST_CASE("FP division works appropriately.", "[utility],[fixed point]")
{
SECTION("FP divides with other FPs appropriately.")
{
FP15 fp1(0.25);
FP15 fp2(0.1);
FP15 fp3 = fp1 / fp2;
REQUIRE(fp3.data == FP15(2.5).data - 5);// Rounding errors, yay!
}
SECTION("FP divides with real values appropriately.")
{
FP15 fp1(0.25);
FP15 fp3 = fp1 / 0.1;
REQUIRE(fp3.data == FP15(2.5).data - 5);// Rounding errors, yay!
}
}