Skip to content

Commit 240b03f

Browse files
committed
Add multiply operator with reversed operand order and additional static checks verifying the return type of various mathematical expressions on Fixed type
1 parent c20baca commit 240b03f

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

sxpsxfp/include/sxpsxfp/Fixed.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ namespace com::saxbophone::sxpsxfp {
267267
lhs *= rhs;
268268
return lhs;
269269
}
270+
/**
271+
* @brief Integer multiplication operator
272+
*/
273+
constexpr friend Fixed operator*(UnderlyingType lhs, const Fixed& rhs) {
274+
return rhs * lhs;
275+
}
270276
/**
271277
* @brief Division operator
272278
*/

tests/multiplication.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,15 @@ TEST_CASE("Fixed * UnderlyingType") {
5656
// allowed to deviate up to the smallest step in the fixed-point representation
5757
REQUIRE((double)baz == Approx((double)foo * bar).margin(Fixed::FRACTIONAL_STEP));
5858
}
59+
60+
TEST_CASE("UnderlyingType * Fixed") {
61+
// max value is sqrt(max fixed point value) to prevent overflow
62+
const double max_operand = std::sqrt(524287.9997558594);
63+
Underlying i = GENERATE_COPY(take(10, random((Underlying)-max_operand, (Underlying)max_operand)));
64+
double j = GENERATE_COPY(take(10, random(-max_operand, max_operand)));
65+
Underlying foo = i;
66+
Fixed bar(j);
67+
Fixed baz = foo * bar;
68+
// allowed to deviate up to the smallest step in the fixed-point representation
69+
REQUIRE((double)baz == Approx(foo * (double)bar).margin(Fixed::FRACTIONAL_STEP));
70+
}

tests/static_checks.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,73 @@ TEST_CASE("Fixed::FRACTIONAL_MAX == Fixed::DECIMAL_MAX + (1 - Fixed::FRACTIONAL_
5252
TEST_CASE("Fixed::FRACTIONAL_MIN == Fixed::DECIMAL_MIN - (1 - Fixed::FRACTIONAL_STEP)") {
5353
STATIC_REQUIRE(Fixed::FRACTIONAL_MIN == Fixed::DECIMAL_MIN - (1.0 - Fixed::FRACTIONAL_STEP));
5454
}
55+
56+
TEST_CASE("typeof(Fixed + Fixed) == Fixed") {
57+
Fixed x = {}, y = {};
58+
STATIC_REQUIRE(std::is_same_v<decltype(x + y), Fixed>);
59+
}
60+
61+
TEST_CASE("typeof(Fixed += Fixed) == Fixed&") {
62+
Fixed x = {}, y = {};
63+
STATIC_REQUIRE(std::is_same_v<decltype(x += y), Fixed&>);
64+
}
65+
66+
TEST_CASE("typeof(Fixed - Fixed) == Fixed") {
67+
Fixed x = {}, y = {};
68+
STATIC_REQUIRE(std::is_same_v<decltype(x - y), Fixed>);
69+
}
70+
71+
TEST_CASE("typeof(Fixed -= Fixed) == Fixed&") {
72+
Fixed x = {}, y = {};
73+
STATIC_REQUIRE(std::is_same_v<decltype(x -= y), Fixed&>);
74+
}
75+
76+
TEST_CASE("typeof(Fixed * Fixed) == Fixed") {
77+
Fixed x = {}, y = {};
78+
STATIC_REQUIRE(std::is_same_v<decltype(x * y), Fixed>);
79+
}
80+
81+
TEST_CASE("typeof(Fixed *= Fixed) == Fixed&") {
82+
Fixed x = {}, y = {};
83+
STATIC_REQUIRE(std::is_same_v<decltype(x *= y), Fixed&>);
84+
}
85+
86+
TEST_CASE("typeof(Fixed * UnderlyingType) == Fixed") {
87+
Fixed x = {};
88+
Fixed::UnderlyingType y = {};
89+
STATIC_REQUIRE(std::is_same_v<decltype(x * y), Fixed>);
90+
}
91+
92+
TEST_CASE("typeof(Fixed *= UnderlyingType) == Fixed&") {
93+
Fixed x = {};
94+
Fixed::UnderlyingType y = {};
95+
STATIC_REQUIRE(std::is_same_v<decltype(x *= y), Fixed&>);
96+
}
97+
98+
TEST_CASE("typeof(UnderlyingType * Fixed) == Fixed") {
99+
Fixed::UnderlyingType x = {};
100+
Fixed y = {};
101+
STATIC_REQUIRE(std::is_same_v<decltype(x * y), Fixed>);
102+
}
103+
104+
TEST_CASE("typeof(Fixed / Fixed) == Fixed") {
105+
Fixed x = {}, y = {};
106+
STATIC_REQUIRE(std::is_same_v<decltype(x / y), Fixed>);
107+
}
108+
109+
TEST_CASE("typeof(Fixed /= Fixed) == Fixed&") {
110+
Fixed x = {}, y = {};
111+
STATIC_REQUIRE(std::is_same_v<decltype(x /= y), Fixed&>);
112+
}
113+
114+
TEST_CASE("typeof(Fixed / UnderlyingType) == Fixed") {
115+
Fixed x = {};
116+
Fixed::UnderlyingType y = {};
117+
STATIC_REQUIRE(std::is_same_v<decltype(x / y), Fixed>);
118+
}
119+
120+
TEST_CASE("typeof(Fixed /= UnderlyingType) == Fixed&") {
121+
Fixed x = {};
122+
Fixed::UnderlyingType y = {};
123+
STATIC_REQUIRE(std::is_same_v<decltype(x /= y), Fixed&>);
124+
}

0 commit comments

Comments
 (0)