39 const uint64_t gcd1 = gcd<uint64_t>((uint64_t)
abs(r1.
num), r2.
denom);
40 const uint64_t gcd2 = gcd<uint64_t>((uint64_t)
abs(r2.
num), r1.
denom);
51 const uint64_t gcd_num = gcd<uint64_t>((uint64_t)
abs(p1.
num), (uint64_t)
abs(p2.
num));
52 const uint64_t gcd_den = gcd<uint64_t>(p1.
denom, p2.
denom);
58template<
typename int_type>
59static void test_gcd_fract(
const int_type n,
const std::make_unsigned_t<int_type> d,
60 const int_type exp_gcd,
const int_type exp_num,
const std::make_unsigned_t<int_type> exp_denom) {
62 const int_type n1 =
sign(n) *
abs(n);
63 const std::make_unsigned_t<int_type> d1 =
sign(d) *
abs(d);
68 const int_type _gcd =
gcd( n,
static_cast<int_type
>(d) );
69 REQUIRE( exp_gcd == _gcd );
72 REQUIRE( exp_num == f1.
num );
73 REQUIRE( exp_denom == f1.
denom);
76template<
typename int_type>
78 const int_type exp_gcd,
const int_type exp_num,
const std::make_unsigned_t<int_type> exp_denom) {
83template<
typename int_type>
89 const bool show_double =
true;
97 const double epsilon = std::numeric_limits<double>::epsilon();
100 if(
std::abs( ad - bd ) <= epsilon ) {
102 REQUIRE( !(a != b) );
105 }
else if(
std::abs( ad - bd ) > epsilon ) {
107 REQUIRE( !(a == b) );
108 if( ad - bd < -epsilon ) {
126 REQUIRE( has_max >= has_min );
127 REQUIRE( has_min <= has_max );
131 const double exp_double = a.
to_double() + b.to_double();
132 const double has_double = has_sum.
to_double();
138 const double exp_double = a.
to_double() - b.to_double();
139 const double has_double = has_diff.
to_double();
145 const double exp_double = a.
to_double() * b.to_double();
146 const double has_double = has_mul.
to_double();
153 const double has_double = has_div.
to_double();
162 for(count = 0; i < lim; i+=step, ++count) { }
165 REQUIRE( 10 == count );
169 REQUIRE( i == lim + step );
171 if( !std::is_unsigned_v<int_type> ) {
176 for(count = 0; i > lim; i-=step, ++count) { }
179 REQUIRE( 10 == count );
183 REQUIRE( i == lim - step );
187template<
typename Rep,
typename Period,
typename int_type>
194 std::chrono::duration<Rep, Period> d = a.
to_duration( dur_ref );
201 REQUIRE( exp_count == d_num );
202 REQUIRE( exp_count == d.count() );
207 typename std::chrono::duration<Rep, Period>::rep d_count = a.to_duration_count( dur_ref );
208 auto d = a.to_auto_duration();
216 REQUIRE( exp_count == d_count );
217 REQUIRE( exp_count == d.count() );
224TEST_CASE(
"Fraction Types Test 00",
"[fraction][type]" ) {
226 INFO_STR(
" is_trivially_copyable_v<fraction_i64>: " +
std::to_string(std::is_trivially_copyable_v<fraction_i64>));
227 INFO_STR(
" is_trivially_copyable<fraction_timespec>: " +
std::to_string(std::is_trivially_copyable_v<fraction_timespec>));
228 REQUIRE(
true == std::is_trivially_copyable_v<fraction_i64> );
229 REQUIRE(
true == std::is_trivially_copyable_v<fraction_timespec> );
234 INFO_STR(
" is_trivially_copyable_v<fraction_i64>: " +
std::to_string(std::is_trivially_copyable_v<fraction_i64>));
235 REQUIRE(
true == std::is_trivially_copyable_v<fraction_i64> );
300TEST_CASE(
"Fraction GCD and Modulo Test 00",
"[integer][fraction][gcd]" ) {
301 test_gcd_fract<int>(0, 0, 0, 0, 1);
302 test_gcd_fract<uint32_t>(0, 0, 0, 0, 1);
304 test_gcd_fract_pm<int>(15, 5, 5, 3, 1);
305 test_gcd_fract_pm<int>(17, 5, 1, 17, 5);
307 test_gcd_fract<uint32_t>(15, 5, 5, 3, 1);
308 test_gcd_fract<uint32_t>(17, 5, 1, 17, 5);
312 bool overflow =
false;
313 int64_t rr = v.
to_num_of(new_base, &overflow);
316 std::string rr_s = exp == rr ?
" - OK " :
" - ********* ERROR ";
318 if constexpr ( false ) {
320 const uint64_t _gcd = gcd<uint64_t>( v.
denom, new_base.
denom );
321 const uint64_t _lcm = ( v.
denom * new_base.
denom ) / _gcd;
322 int64_t r0 = ( v.
num * (int64_t)( _lcm / v.
denom ) ) / new_base.
num;
323 int64_t r2 = ( v.
num * (int64_t)new_base.
denom ) / ( (int64_t) v.
denom ) / new_base.
num;
328 std::string r0_s = exp == r0 ?
" - OK " :
" - ********* ERROR ";
330 std::string r2_s = exp == r2 ?
" - OK " :
" - ********* ERROR ";
333 REQUIRE( exp_overflow == overflow );
334 if( !exp_overflow ) {
335 REQUIRE( exp == rr );
339TEST_CASE(
"Fraction Cast Test 01.1",
"[integer][fraction][type][to_num_of]" ) {
363 REQUIRE( exp_nsum == n1 + n2 );
385TEST_CASE(
"Fraction String Test 01.2",
"[integer][fraction][type][string]" ) {
412 REQUIRE( 10_us == a );
416 REQUIRE( 10_us == b );
426TEST_CASE(
"Fraction Arithmetic Test 02",
"[integer][fraction]" ) {
511 const std::chrono::milliseconds::rep exp_count = 100;
516 const std::chrono::nanoseconds::rep exp_count = -50;
521 const std::chrono::hours::rep exp_count = 24;
528 REQUIRE( 1_i64 / fps == refresh_rate );
529 REQUIRE( fps == 1_i64 / refresh_rate );
530 REQUIRE( 2_i64 * fps == 1_i64 / ( refresh_rate / 2_i64 ) );
533 REQUIRE( 1_m / 2_one == 500_one * 1_u );
540 REQUIRE( 60_s == 1_min );
543 REQUIRE( 24_h == 1_d );
549 REQUIRE( m == h/4_i64 );
556 REQUIRE( 1000_s == a );
557 REQUIRE( 1000_ns == b );
559 fraction_i64 exp_c ( 1'000'000'000lu + 1lu, 1'000'000lu );
560 REQUIRE( exp_c == c );
570#if defined __x86_64__ && defined __ILP32__
573 return sizeof( __int64_t );
575 return sizeof(
long int );
579 return sizeof(
long int );
588#if __WORDSIZE == 64 \
589 || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
592 return sizeof( int64_t );
595 return sizeof(
long int );
599TEST_CASE(
"struct timespec type validation Test 03.00",
"[fraction][struct_timespec][time]" ) {
602 using time_t_type =
decltype(timespec::tv_sec);
605 CHECK(
true == std::is_signed_v<time_t_type> );
607 using ns_type =
decltype(timespec::tv_nsec);
610 CHECK(
true == std::is_signed_v<ns_type> );
615TEST_CASE(
"Fraction Time Arithmetic Add Test 03.1",
"[fraction][fraction_timespec][add]" ) {
616 const int64_t ns_per_sec = 1'000'000'000_i64;
626 REQUIRE( ( a + b ) == exp_sum );
636 REQUIRE( ( a - b ) == exp_sum );
646 REQUIRE( ( a - b ) == exp_sum );
653 REQUIRE( ( a + b ) == exp_sum );
663 REQUIRE( ( a + b ) == exp_sum );
673 REQUIRE( ( a + b ) == exp_sum );
683 REQUIRE( ( a + b ) == exp_sum );
693 REQUIRE( ( a + b ) == exp_sum );
700 REQUIRE( ( a + b ) == exp_sum );
707 REQUIRE( ( a + b ) == exp_sum );
717 REQUIRE( ( a + b ) == exp_sum );
727 REQUIRE( ( a + b ) == exp_sum );
737 REQUIRE( ( a + b ) == exp_sum );
741TEST_CASE(
"Fraction Time Arithmetic Sub Test 03.2",
"[fraction][fraction_timespec][sub]" ) {
754 REQUIRE( a.
tv_sec == -5 );
769 REQUIRE( a.
tv_nsec == 600000000_i64 );
776 REQUIRE( a.
tv_nsec == -600000000_i64 );
787 REQUIRE( ( a - b ) == exp_sum );
796 INFO_STR(
" exp " + exp_sum.to_string() );
798 REQUIRE( ( a - b ) == exp_sum );
805 REQUIRE( ( a - b ) == exp_sum );
812 REQUIRE( ( a - b ) == exp_sum );
822 REQUIRE( ( a - b ) == exp_sum );
832 REQUIRE( ( a - b ) == exp_sum );
840 REQUIRE( ( a - b ) == exp_sum );
850 REQUIRE( ( a - b ) == exp_sum );
860 REQUIRE( ( a - b ) == exp_sum );
870 REQUIRE( ( a - b ) == exp_sum );
874TEST_CASE(
"Fraction Time Measurement Test 04.01",
"[fraction][fraction_timespec][time]" ) {
875 const int64_t sleep_ms = 50;
890 INFO_STR(
" Test-1: sleep_for() getMonotonicTime:");
895 REQUIRE( t0.
tv_sec >= 0 );
897 REQUIRE( t1.
tv_sec >= 0 );
899 REQUIRE( td_1.
tv_sec >= 0 );
903 REQUIRE( terr <= accuracy );
912 INFO_STR(
" Test-2: sleep_until() getMonotonicTime:");
917 REQUIRE( t0.
tv_sec >= 0 );
919 REQUIRE( t1.
tv_sec >= 0 );
921 REQUIRE( td_1.
tv_sec >= 0 );
925 REQUIRE( terr <= accuracy );
#define REQUIRE_MSG(MSG,...)
std::string to_string(const bool show_double=false) const noexcept
Returns a string representation of this fraction.
uint_type denom
Denominator, always positive.
int_type num
Numerator, carries the sign.
constexpr double to_double() const noexcept
Returns the converted fraction to lossy double.
constexpr int_type to_num_of(const fraction< int_type > &new_base, bool *overflow_ptr=nullptr) const noexcept
Converts this this fraction to a numerator for the given new base fraction.
std::chrono::duration< Rep, Period > to_duration(const std::chrono::duration< Rep, Period > &dur_ref, bool *overflow_ptr=nullptr) const noexcept
Convert this fraction into std::chrono::duration with given Rep and Period.
std::string to_string(const alphabet &v) noexcept
bool to_fraction_i64(fraction_i64 &result, const std::string &value, const fraction_i64 &min_allowed, const fraction_i64 &max_allowed) noexcept
Stores the fraction_i64 value of the given string value in format <num>/<denom>, which may contain wh...
fraction_timespec getMonotonicTime() noexcept
Returns current monotonic time since Unix Epoch 00:00:00 UTC on 1970-01-01.
fraction< int64_t > fraction_i64
fraction using int64_t as integral type
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
constexpr T gcd(T a, T b) noexcept
Returns the greatest common divisor (GCD) of the two given integer values following Euclid's algorith...
constexpr int sign(const T x) noexcept
Returns the value of the sign function (w/o branching ?) in O(1).
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
constexpr const jau::fraction_i64 tera(1 '000 '000 '000 '000l, 1lu)
tera is 10^12
constexpr const jau::fraction_i64 zero(0l, 1lu)
zero is 0/1
constexpr const jau::fraction_i64 minutes(60l, 1lu)
minutes is 60/1
constexpr const jau::fraction_i64 nano(1l, 1 '000 '000 '000lu)
nano is 10^-9
constexpr const jau::fraction_i64 milli(1l, 1 '000lu)
milli is 10^-3
constexpr const jau::fraction_i64 seconds(1l, 1lu)
seconds is 1/1
constexpr const jau::fraction_i64 kilo(1 '000l, 1lu)
kilo is 10^3
constexpr const jau::fraction_i64 pico(1l, 1 '000 '000 '000 '000lu)
pico is 10^-12
constexpr const jau::fraction_i64 one(1l, 1lu)
one is 10^0 or 1/1
constexpr const jau::fraction_i64 days(86 '400l, 1lu)
days is 86400/1
constexpr const jau::fraction_i64 giga(1 '000 '000 '000l, 1lu)
giga is 10^9
constexpr const jau::fraction_i64 micro(1l, 1 '000 '000lu)
micro is 10^-6
constexpr const jau::fraction_i64 mega(1 '000 '000l, 1lu)
mega is 10^6
constexpr const jau::fraction_i64 hours(3 '600l, 1lu)
hours is 3660/1
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
bool sleep_until(const fraction_timespec &absolute_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_until causes the current thread to block until the specific time is reached.
bool sleep_for(const fraction_timespec &relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_for causes the current thread to block until a specific amount of time has passed.
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
int64_t tv_nsec
Nanoseconds component with its absolute value in range [0..1'000'000'000[ or [0..1'000'000'000),...
int64_t tv_sec
Seconds component, with its absolute value in range [0..inf[ or [0..inf), sharing same sign with tv_n...
std::string to_string() const noexcept
Return simple string representation in seconds and nanoseconds.
constexpr fraction_i64 to_fraction_i64() const noexcept
Returns the sum of both components.
static void test_comp_fract(const fraction< int_type > &a, const fraction< int_type > &b, const fraction< int_type > &exp_max, const fraction< int_type > &exp_min, const fraction< int_type > &exp_sum, const fraction< int_type > &exp_diff, const fraction< int_type > &exp_mul, const fraction< int_type > &exp_div)
static void test_to_num_of(const int64_t exp, const fraction< int64_t > &v, const fraction< int64_t > &new_base, bool exp_overflow=false) noexcept
static int sizeof_time_t()
Resembling the GNU/Linux bits/types.h, documenting whether time_t is 32-bit (arm-32) or 64-bit (arm-6...
static void test_gcd_fract_pm(const int_type n, const std::make_unsigned_t< int_type > d, const int_type exp_gcd, const int_type exp_num, const std::make_unsigned_t< int_type > exp_denom)
static void test_gcd_fract(const int_type n, const std::make_unsigned_t< int_type > d, const int_type exp_gcd, const int_type exp_num, const std::make_unsigned_t< int_type > exp_denom)
TEST_CASE("Fraction Types Test 00", "[fraction][type]")
static int sizeof_tv_nsec()
Resembling the GNU/Linux bits/types.h, documenting whether tv_nsec of struct timespec is 32-bit (arm-...
static void test_duration(const fraction< int_type > &a, const std::chrono::duration< Rep, Period > &dur_ref, const Rep exp_count)