Added Math::Mod method
This commit is contained in:
parent
e699a20f11
commit
6926ebab1c
@ -75,5 +75,24 @@ bool Math::RandomChance(const double chance)
|
|||||||
return Random() <= chance;
|
return Random() <= chance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Math::Mod(const int numerator, const int denominator)
|
||||||
|
{
|
||||||
|
if (denominator == 0)
|
||||||
|
throw std::logic_error("Divide by zero");
|
||||||
|
|
||||||
|
// Quick optimizations:
|
||||||
|
|
||||||
|
// -> 0/n is always 0
|
||||||
|
if (numerator == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// -> operator% works for a > 0 && b > 0
|
||||||
|
if (denominator > 0 && numerator > 0)
|
||||||
|
return numerator % denominator;
|
||||||
|
|
||||||
|
// Else: generalized formula
|
||||||
|
return (denominator + (numerator % denominator)) % denominator;
|
||||||
|
}
|
||||||
|
|
||||||
std::mt19937 Math::rng;
|
std::mt19937 Math::rng;
|
||||||
bool Math::isRngInitialized = true;
|
bool Math::isRngInitialized = true;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace Eule
|
namespace Eule
|
||||||
{
|
{
|
||||||
@ -26,6 +27,10 @@ namespace Eule
|
|||||||
//! Compares two double values with a given accuracy
|
//! Compares two double values with a given accuracy
|
||||||
[[nodiscard]] static constexpr bool Similar(const double a, const double b, const double epsilon = 0.00001);
|
[[nodiscard]] static constexpr bool Similar(const double a, const double b, const double epsilon = 0.00001);
|
||||||
|
|
||||||
|
//! Will compute the actual modulo of a fraction. The % operator returns bs for n<0.
|
||||||
|
//! May throw divide-by-zero std::logic_error
|
||||||
|
[[nodiscard]] static int Mod(const int numerator, const int denominator);
|
||||||
|
|
||||||
//! Will return a random double between `0` and `1`
|
//! Will return a random double between `0` and `1`
|
||||||
static double Random();
|
static double Random();
|
||||||
|
|
||||||
|
83
Test/Math__Mod.cpp
Normal file
83
Test/Math__Mod.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "CppUnitTest.h"
|
||||||
|
#include "../Eule/Math.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
using namespace Eule;
|
||||||
|
|
||||||
|
/** Equivalence classes:
|
||||||
|
* a -> numerator
|
||||||
|
* b -> denominator
|
||||||
|
* -- a > 0 && b > 0
|
||||||
|
* -- a < 0 && b > 0
|
||||||
|
* -- a > 0 && b < 0
|
||||||
|
* -- a < 0 && b < 0
|
||||||
|
*
|
||||||
|
* -- a > 0 && b = 0
|
||||||
|
* -- a = 0 && b > 0
|
||||||
|
* * -- a < 0 && b = 0
|
||||||
|
* -- a = 0 && b < 0
|
||||||
|
* -- a = 0 && b = 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace _Math
|
||||||
|
{
|
||||||
|
TEST_CLASS(_Mod)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// a > 0 && b > 0
|
||||||
|
TEST_METHOD(a_gt_0_and_b_gt_0)
|
||||||
|
{
|
||||||
|
Assert::AreEqual(7, Math::Mod(199, 32));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a < 0 && b > 0
|
||||||
|
TEST_METHOD(a_lt_0_and_b_gt_0)
|
||||||
|
{
|
||||||
|
Assert::AreEqual(25, Math::Mod(-199, 32));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a > 0 && b < 0
|
||||||
|
TEST_METHOD(a_gt_0_and_b_lt_0)
|
||||||
|
{
|
||||||
|
Assert::AreEqual(-25, Math::Mod(199, -32));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a > 0 && b = 0
|
||||||
|
TEST_METHOD(a_gt_0_and_b_eq_0)
|
||||||
|
{
|
||||||
|
// Exppect divide-by-zero
|
||||||
|
Assert::ExpectException<std::logic_error&>([]() {
|
||||||
|
Assert::AreEqual(0, Math::Mod(199, 0));
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a = 0 && b > 0
|
||||||
|
TEST_METHOD(a_eq_0_and_b_gt_0)
|
||||||
|
{
|
||||||
|
Assert::AreEqual(0, Math::Mod(0, 32));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a < 0 && b = 0
|
||||||
|
TEST_METHOD(a_lt_0_and_b_eq_0)
|
||||||
|
{
|
||||||
|
// Exppect divide-by-zero
|
||||||
|
Assert::ExpectException<std::logic_error&>([]() {
|
||||||
|
Assert::AreEqual(0, Math::Mod(-199, 0));
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a = 0 && b < 0
|
||||||
|
TEST_METHOD(a_eq_0_and_b_lt_0)
|
||||||
|
{
|
||||||
|
Assert::AreEqual(0, Math::Mod(0, -32));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -33,6 +33,7 @@
|
|||||||
<ClCompile Include="Math_RandomInteger.cpp" />
|
<ClCompile Include="Math_RandomInteger.cpp" />
|
||||||
<ClCompile Include="Math_RandomIntRange.cpp" />
|
<ClCompile Include="Math_RandomIntRange.cpp" />
|
||||||
<ClCompile Include="Math_Similar.cpp" />
|
<ClCompile Include="Math_Similar.cpp" />
|
||||||
|
<ClCompile Include="Math__Mod.cpp" />
|
||||||
<ClCompile Include="Math__Oscillate.cpp" />
|
<ClCompile Include="Math__Oscillate.cpp" />
|
||||||
<ClCompile Include="Math__RandomRange.cpp" />
|
<ClCompile Include="Math__RandomRange.cpp" />
|
||||||
<ClCompile Include="Matrix4x4.cpp" />
|
<ClCompile Include="Matrix4x4.cpp" />
|
||||||
|
@ -75,5 +75,8 @@
|
|||||||
<ClCompile Include="TrapazoidalPrismCollider.cpp">
|
<ClCompile Include="TrapazoidalPrismCollider.cpp">
|
||||||
<Filter>Tests</Filter>
|
<Filter>Tests</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Math__Mod.cpp">
|
||||||
|
<Filter>Tests\Math</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
x
Reference in New Issue
Block a user