mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-04 12:54:25 +02:00
feat: fmod
floating-point division remainder
This commit is contained in:
@@ -337,7 +337,7 @@ Among others, we can find there the following:
|
|||||||
- `exp()`,
|
- `exp()`,
|
||||||
- `abs()`,
|
- `abs()`,
|
||||||
- `epsilon()`,
|
- `epsilon()`,
|
||||||
- `fma()`,
|
- `fma()`, `fmod()`,
|
||||||
- `isfinite()`, `isinf()`, `isnan()`,
|
- `isfinite()`, `isinf()`, `isnan()`,
|
||||||
- `floor()`, `ceil()`, `round()`,
|
- `floor()`, `ceil()`, `round()`,
|
||||||
- `inverse()`,
|
- `inverse()`,
|
||||||
|
@@ -198,6 +198,24 @@ template<auto R, auto S, auto T, typename Rep1, typename Rep2, typename Rep3>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Computes the floating-point remainder of the division operation x / y.
|
||||||
|
*/
|
||||||
|
template<auto R1, typename Rep1, auto R2, typename Rep2>
|
||||||
|
requires requires(Rep1 v1, Rep2 v2) {
|
||||||
|
common_reference(R1, R2);
|
||||||
|
requires requires { fmod(v1, v2); } || requires { std::fmod(v1, v2); };
|
||||||
|
}
|
||||||
|
[[nodiscard]] constexpr QuantityOf<get_quantity_spec(R1)> auto fmod(const quantity<R1, Rep1>& x,
|
||||||
|
const quantity<R2, Rep2>& y) noexcept
|
||||||
|
{
|
||||||
|
constexpr auto ref = common_reference(R1, R2);
|
||||||
|
constexpr auto unit = get_unit(ref);
|
||||||
|
using std::fmod;
|
||||||
|
return quantity{fmod(x.numerical_value_in(unit), y.numerical_value_in(unit)), ref};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the epsilon of the quantity
|
* @brief Returns the epsilon of the quantity
|
||||||
*
|
*
|
||||||
|
@@ -71,6 +71,24 @@ TEST_CASE("'fma()' on quantity changes the value and the dimension accordingly",
|
|||||||
REQUIRE(fma(isq::speed(10.0 * m / s), isq::time(2.0 * s), isq::height(42.0 * m)) == isq::length(62.0 * m));
|
REQUIRE(fma(isq::speed(10.0 * m / s), isq::time(2.0 * s), isq::height(42.0 * m)) == isq::length(62.0 * m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("fmod functions", "[math][fmod]")
|
||||||
|
{
|
||||||
|
SECTION("fmod should work on the same quantities")
|
||||||
|
{
|
||||||
|
REQUIRE(fmod(4. * isq::length[km], 3. * isq::length[km]) == 1. * isq::length[km]);
|
||||||
|
REQUIRE(fmod(-9. * isq::length[km], 3. * isq::length[km]) == -0. * isq::length[km]);
|
||||||
|
REQUIRE(fmod(3 * isq::length[km], 2 * isq::length[km]) == 1 * isq::length[km]);
|
||||||
|
REQUIRE(fmod(4 * isq::length[km], 2.5f * isq::length[km]) == 1.5 * isq::length[km]);
|
||||||
|
}
|
||||||
|
SECTION("fmod should work with different units of the same dimension")
|
||||||
|
{
|
||||||
|
REQUIRE(fmod(4. * isq::length[km], 3000. * isq::length[m]) == 1000. * isq::length[m]);
|
||||||
|
REQUIRE(fmod(-9. * isq::length[km], 3000. * isq::length[m]) == -0. * isq::length[m]);
|
||||||
|
REQUIRE(fmod(3. * isq::length[km], 2000. * isq::length[m]) == 1000 * isq::length[m]);
|
||||||
|
REQUIRE(fmod(4 * isq::length[km], 2500 * isq::length[m]) == 1500 * isq::length[m]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("'isfinite()' accepts dimensioned arguments", "[math][isfinite]") { REQUIRE(isfinite(4.0 * isq::length[m])); }
|
TEST_CASE("'isfinite()' accepts dimensioned arguments", "[math][isfinite]") { REQUIRE(isfinite(4.0 * isq::length[m])); }
|
||||||
|
|
||||||
TEST_CASE("'isinf()' accepts dimensioned arguments", "[math][isinf]") { REQUIRE(!isinf(4.0 * isq::length[m])); }
|
TEST_CASE("'isinf()' accepts dimensioned arguments", "[math][isinf]") { REQUIRE(!isinf(4.0 * isq::length[m])); }
|
||||||
|
@@ -57,6 +57,12 @@ static_assert(compare(fma(2.0 * one, 3.0 * m, 1.0 * m), 7.0 * m));
|
|||||||
static_assert(compare(fma(2.0 * m, 3.0 * one, 1.0 * m), 7.0 * m));
|
static_assert(compare(fma(2.0 * m, 3.0 * one, 1.0 * m), 7.0 * m));
|
||||||
static_assert(compare(fma(2 * m, 3.0f * m, 1.0 * m2), 7.0 * m2));
|
static_assert(compare(fma(2 * m, 3.0f * m, 1.0 * m2), 7.0 * m2));
|
||||||
static_assert(compare(fma(isq::width(2.0 * m), 2.0 * one, isq::height(3.0 * m)), isq::length(7.0 * m)));
|
static_assert(compare(fma(isq::width(2.0 * m), 2.0 * one, isq::height(3.0 * m)), isq::length(7.0 * m)));
|
||||||
|
static_assert(compare(fmod(4.0 * km, 3.0 * km), 1.0 * km));
|
||||||
|
static_assert(compare(fmod(-4.0 * km, 3.0 * km), -1.0 * km));
|
||||||
|
static_assert(compare(fmod(9.0 * km, -3.0 * km), 0.0 * km));
|
||||||
|
static_assert(compare(fmod(9.5 * km, -2000 * m), 1500.0 * m));
|
||||||
|
static_assert(compare(fmod(3 * km, 2 * km), 1.0 * km));
|
||||||
|
static_assert(compare(fmod(4 * km, 2.5f * km), 1.5 * km));
|
||||||
static_assert(compare(pow<0>(2 * m), 1 * one));
|
static_assert(compare(pow<0>(2 * m), 1 * one));
|
||||||
static_assert(compare(pow<1>(2 * m), 2 * m));
|
static_assert(compare(pow<1>(2 * m), 2 * m));
|
||||||
static_assert(compare(pow<2>(2 * m), 4 * pow<2>(m), 4 * m2));
|
static_assert(compare(pow<2>(2 * m), 4 * pow<2>(m), 4 * m2));
|
||||||
|
Reference in New Issue
Block a user