233 lines
4.6 KiB
C++
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!
|
|
}
|
|
}
|