mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-16 00:46:03 +08:00
etl::ratio work-in-progress
This commit is contained in:
parent
0d0b9be310
commit
4741c71e34
@ -32,6 +32,7 @@ SOFTWARE.
|
||||
#define ETL_RATIO_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "static_assert.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@ -71,6 +72,7 @@ namespace etl
|
||||
struct ratio
|
||||
{
|
||||
ETL_STATIC_ASSERT(Num != 0, "Numerator cannot be zero");
|
||||
ETL_STATIC_ASSERT(Den != 0, "Denominator cannot be zero");
|
||||
|
||||
static ETL_CONSTANT intmax_t num = Num / private_ratio::gcd<Num, Den>::value;
|
||||
static ETL_CONSTANT intmax_t den = Den / private_ratio::gcd<Num, Den>::value;
|
||||
@ -103,13 +105,67 @@ namespace etl
|
||||
typedef etl::ratio<N, D> type;
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
/// ratio_multiply
|
||||
//***********************************************************************
|
||||
template <typename TRatio1, typename TRatio2>
|
||||
struct ratio_multiply
|
||||
{
|
||||
private:
|
||||
|
||||
static ETL_CONSTANT intmax_t N = TRatio1::num * TRatio2::num;
|
||||
static ETL_CONSTANT intmax_t D = TRatio1::den * TRatio2::den;
|
||||
|
||||
static ETL_CONSTANT intmax_t Num = N / private_ratio::gcd<N, D>::value;
|
||||
static ETL_CONSTANT intmax_t Den = D / private_ratio::gcd<N, D>::value;
|
||||
|
||||
public:
|
||||
|
||||
typedef etl::ratio<N, D> type;
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
/// ratio_add
|
||||
//***********************************************************************
|
||||
template <typename TRatio1, typename TRatio2>
|
||||
struct ratio_add
|
||||
{
|
||||
private:
|
||||
|
||||
static ETL_CONSTANT intmax_t N = (TRatio1::num * TRatio2::den) + (TRatio2::num * TRatio1::den);
|
||||
static ETL_CONSTANT intmax_t D = TRatio1::den * TRatio2::den;;
|
||||
|
||||
static ETL_CONSTANT intmax_t Num = N / private_ratio::gcd<N, D>::value;
|
||||
static ETL_CONSTANT intmax_t Den = D / private_ratio::gcd<N, D>::value;
|
||||
|
||||
public:
|
||||
|
||||
typedef etl::ratio<N, D> type;
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
/// ratio_subtract
|
||||
//***********************************************************************
|
||||
template <typename TRatio1, typename TRatio2>
|
||||
struct ratio_subtract
|
||||
{
|
||||
private:
|
||||
|
||||
static ETL_CONSTANT intmax_t N = (TRatio1::num * TRatio2::den) - (TRatio2::num * TRatio1::den);
|
||||
static ETL_CONSTANT intmax_t D = TRatio1::den * TRatio2::den;;
|
||||
|
||||
static ETL_CONSTANT intmax_t Num = N / private_ratio::gcd<N, D>::value;
|
||||
static ETL_CONSTANT intmax_t Den = D / private_ratio::gcd<N, D>::value;
|
||||
|
||||
public:
|
||||
|
||||
typedef etl::ratio<N, D> type;
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
/// Predefined ration types.
|
||||
//***********************************************************************
|
||||
#if INT_MAX > INT32_MAX
|
||||
typedef ratio<1, 1000000000000000000000000> yocto;
|
||||
typedef ratio<1, 1000000000000000000000> zepto;
|
||||
typedef ratio<1, 1000000000000000000> atto;
|
||||
typedef ratio<1, 1000000000000000> femto;
|
||||
typedef ratio<1, 1000000000000> pico;
|
||||
@ -138,8 +194,6 @@ namespace etl
|
||||
typedef ratio<1000000000000, 1> tera;
|
||||
typedef ratio<1000000000000000, 1> peta;
|
||||
typedef ratio<1000000000000000000, 1> exa;
|
||||
typedef ratio<1000000000000000000000, 1> zetta;
|
||||
typedef ratio<1000000000000000000000000, 1> yotta;
|
||||
#endif
|
||||
|
||||
/// An approximation of PI to 6 digits.
|
||||
|
||||
133
test/test_ratio.cpp
Normal file
133
test/test_ratio.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Documentation:
|
||||
|
||||
Copyright(c) 2024 John Wellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "etl/ratio.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Helper to find the greatest common divisor
|
||||
template <intmax_t A, intmax_t B>
|
||||
struct gcd
|
||||
{
|
||||
static ETL_CONSTANT intmax_t value = gcd<B, A % B>::value;
|
||||
};
|
||||
|
||||
template <intmax_t A>
|
||||
struct gcd<A, 0>
|
||||
{
|
||||
static ETL_CONSTANT intmax_t value = A;
|
||||
};
|
||||
|
||||
// Helper to find the least common multiple
|
||||
template <intmax_t A, intmax_t B>
|
||||
struct lcm
|
||||
{
|
||||
static ETL_CONSTANT intmax_t value = (A / gcd<A, B>::value) * B;
|
||||
};
|
||||
|
||||
SUITE(test_ratio)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_constructor)
|
||||
{
|
||||
constexpr intmax_t Num = 20;
|
||||
constexpr intmax_t Den = 600;
|
||||
|
||||
intmax_t N = Num / gcd<Num, Den>::value;
|
||||
intmax_t D = Den / gcd<Num, Den>::value;
|
||||
|
||||
using ratio = etl::ratio<Num, Den>;
|
||||
using ratio_type = ratio::type;
|
||||
|
||||
CHECK_FALSE((std::is_same<ratio, ratio_type>::value));
|
||||
|
||||
CHECK_EQUAL(N, ratio::num);
|
||||
CHECK_EQUAL(D, ratio::den);
|
||||
|
||||
CHECK_EQUAL(N, ratio_type::num);
|
||||
CHECK_EQUAL(D, ratio_type::den);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_predefined_ratios)
|
||||
{
|
||||
#if INT_MAX > INT32_MAX
|
||||
CHECK_EQUAL(etl::atto::num, 1);
|
||||
CHECK_EQUAL(etl::atto::den, 1000000000000000000);
|
||||
CHECK_EQUAL(etl::femto::num, 1);
|
||||
CHECK_EQUAL(etl::femto::den, 1000000000000000);
|
||||
CHECK_EQUAL(etl::pico::num, 1);
|
||||
CHECK_EQUAL(etl::pico::den, 1000000000000);
|
||||
#endif
|
||||
#if (INT_MAX >= INT32_MAX)
|
||||
CHECK_EQUAL(etl::nano::num, 1);
|
||||
CHECK_EQUAL(etl::nano::den, 1000000000);
|
||||
CHECK_EQUAL(etl::micro::num, 1);
|
||||
CHECK_EQUAL(etl::micro::den, 1000000);
|
||||
#endif
|
||||
#if (INT_MAX >= INT16_MAX)
|
||||
CHECK_EQUAL(etl::milli::num, 1);
|
||||
CHECK_EQUAL(etl::milli::den, 1000);
|
||||
CHECK_EQUAL(etl::centi::num, 1);
|
||||
CHECK_EQUAL(etl::centi::den, 100);
|
||||
CHECK_EQUAL(etl::deci::num, 1);
|
||||
CHECK_EQUAL(etl::deci::den, 10);
|
||||
CHECK_EQUAL(etl::deca::num, 10);
|
||||
CHECK_EQUAL(etl::deca::den, 1);
|
||||
CHECK_EQUAL(etl::hecto::num, 100);
|
||||
CHECK_EQUAL(etl::hecto::den, 1);
|
||||
CHECK_EQUAL(etl::kilo::num, 1000);
|
||||
CHECK_EQUAL(etl::kilo::den, 1);
|
||||
#endif
|
||||
#if (INT_MAX >= INT32_MAX)
|
||||
CHECK_EQUAL(etl::mega::num, 1000000);
|
||||
CHECK_EQUAL(etl::mega::den, 1);
|
||||
CHECK_EQUAL(etl::giga::num, 1000000000);
|
||||
CHECK_EQUAL(etl::giga::den, 1);
|
||||
#endif
|
||||
|
||||
#if INT_MAX > INT32_MAX
|
||||
CHECK_EQUAL(etl::tera::num, 1000000000000);
|
||||
CHECK_EQUAL(etl::tera::den, 1);
|
||||
CHECK_EQUAL(etl::peta::num, 1000000000000000);
|
||||
CHECK_EQUAL(etl::peta::den, 1);
|
||||
CHECK_EQUAL(etl::exa::num, 1000000000000000000);
|
||||
CHECK_EQUAL(etl::exa::den, 1);
|
||||
#endif
|
||||
|
||||
double expected_pi = 3.1415926535897931;
|
||||
double actual_pi = double(etl::ratio_pi::num) / double(etl::ratio_pi::den);
|
||||
|
||||
CHECK_CLOSE(expected_pi, actual_pi, 0.0000003);
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user