Skip to content

Commit

Permalink
Add multiply operator with reversed operand order and additional stat…
Browse files Browse the repository at this point in the history
…ic checks verifying the return type of various mathematical expressions on Fixed type
  • Loading branch information
saxbophone committed Sep 14, 2021
1 parent c20baca commit 240b03f
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
6 changes: 6 additions & 0 deletions sxpsxfp/include/sxpsxfp/Fixed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ namespace com::saxbophone::sxpsxfp {
lhs *= rhs;
return lhs;
}
/**
* @brief Integer multiplication operator
*/
constexpr friend Fixed operator*(UnderlyingType lhs, const Fixed& rhs) {
return rhs * lhs;
}
/**
* @brief Division operator
*/
Expand Down
12 changes: 12 additions & 0 deletions tests/multiplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,15 @@ TEST_CASE("Fixed * UnderlyingType") {
// allowed to deviate up to the smallest step in the fixed-point representation
REQUIRE((double)baz == Approx((double)foo * bar).margin(Fixed::FRACTIONAL_STEP));
}

TEST_CASE("UnderlyingType * Fixed") {
// max value is sqrt(max fixed point value) to prevent overflow
const double max_operand = std::sqrt(524287.9997558594);
Underlying i = GENERATE_COPY(take(10, random((Underlying)-max_operand, (Underlying)max_operand)));
double j = GENERATE_COPY(take(10, random(-max_operand, max_operand)));
Underlying foo = i;
Fixed bar(j);
Fixed baz = foo * bar;
// allowed to deviate up to the smallest step in the fixed-point representation
REQUIRE((double)baz == Approx(foo * (double)bar).margin(Fixed::FRACTIONAL_STEP));
}
70 changes: 70 additions & 0 deletions tests/static_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,73 @@ TEST_CASE("Fixed::FRACTIONAL_MAX == Fixed::DECIMAL_MAX + (1 - Fixed::FRACTIONAL_
TEST_CASE("Fixed::FRACTIONAL_MIN == Fixed::DECIMAL_MIN - (1 - Fixed::FRACTIONAL_STEP)") {
STATIC_REQUIRE(Fixed::FRACTIONAL_MIN == Fixed::DECIMAL_MIN - (1.0 - Fixed::FRACTIONAL_STEP));
}

TEST_CASE("typeof(Fixed + Fixed) == Fixed") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x + y), Fixed>);
}

TEST_CASE("typeof(Fixed += Fixed) == Fixed&") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x += y), Fixed&>);
}

TEST_CASE("typeof(Fixed - Fixed) == Fixed") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x - y), Fixed>);
}

TEST_CASE("typeof(Fixed -= Fixed) == Fixed&") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x -= y), Fixed&>);
}

TEST_CASE("typeof(Fixed * Fixed) == Fixed") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x * y), Fixed>);
}

TEST_CASE("typeof(Fixed *= Fixed) == Fixed&") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x *= y), Fixed&>);
}

TEST_CASE("typeof(Fixed * UnderlyingType) == Fixed") {
Fixed x = {};
Fixed::UnderlyingType y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x * y), Fixed>);
}

TEST_CASE("typeof(Fixed *= UnderlyingType) == Fixed&") {
Fixed x = {};
Fixed::UnderlyingType y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x *= y), Fixed&>);
}

TEST_CASE("typeof(UnderlyingType * Fixed) == Fixed") {
Fixed::UnderlyingType x = {};
Fixed y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x * y), Fixed>);
}

TEST_CASE("typeof(Fixed / Fixed) == Fixed") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x / y), Fixed>);
}

TEST_CASE("typeof(Fixed /= Fixed) == Fixed&") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x /= y), Fixed&>);
}

TEST_CASE("typeof(Fixed / UnderlyingType) == Fixed") {
Fixed x = {};
Fixed::UnderlyingType y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x / y), Fixed>);
}

TEST_CASE("typeof(Fixed /= UnderlyingType) == Fixed&") {
Fixed x = {};
Fixed::UnderlyingType y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x /= y), Fixed&>);
}

0 comments on commit 240b03f

Please sign in to comment.