more fractions functionality.

This commit is contained in:
Enno Rehling 2017-02-24 20:47:31 +01:00
parent e0229be500
commit e557140ad1
3 changed files with 31 additions and 1 deletions

View File

@ -4,6 +4,9 @@
#include <assert.h>
#include <limits.h>
const variant frac_zero = { .sa = { 0, 1 } };
const variant frac_one = { .sa = { 1, 1 } };
static int gcd(int a, int b) {
const int primes[] = { 3, 5, 7, 11, 13, 17, 19, 23, 0 };
int i = 0, g = 1, p = 2;
@ -28,6 +31,10 @@ static int lcm(int a, int b) {
return x;
}
bool frac_equal(variant a, variant b) {
return frac_sign(frac_sub(a, b)) == 0;
}
variant frac_make(int num, int den)
{
variant v;
@ -64,3 +71,10 @@ variant frac_div(variant a, variant b)
{
return frac_make(a.sa[0] * b.sa[1], a.sa[1] * b.sa[0]);
}
int frac_sign(variant a) {
if (a.sa[0] == 0) return 0;
if (a.sa[0] > 0 && a.sa[1] > 0) return 1;
if (a.sa[0] < 0 && a.sa[1] < 0) return 1;
return -1;
}

View File

@ -2,6 +2,9 @@
#ifndef STRUCT_VARIANT_H
#define STRUCT_VARIANT_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -21,11 +24,16 @@ extern "C" {
VAR_FLOAT
} variant_type;
extern const variant frac_zero;
extern const variant frac_one;
variant frac_make(int num, int den);
variant frac_add(variant a, variant b);
variant frac_sub(variant a, variant b);
variant frac_mul(variant a, variant b);
variant frac_div(variant a, variant b);
int frac_sign(variant a);
bool frac_equal(variant a, variant b);
#ifdef __cplusplus
}

View File

@ -20,8 +20,16 @@ static void test_fractions(CuTest *tc) {
CuAssertIntEquals(tc, 1, a.sa[1]);
a = frac_sub(a, a);
CuAssertIntEquals(tc, 0, a.sa[0]);
a = frac_mul(a, b);
a = frac_sub(frac_one, a);
CuAssertIntEquals(tc, 1, a.sa[0]);
CuAssertIntEquals(tc, 1, a.sa[1]);
a = frac_mul(a, frac_zero);
CuAssertIntEquals(tc, 0, a.sa[0]);
CuAssertIntEquals(tc, 1, frac_sign(frac_make(-1, -1)));
CuAssertIntEquals(tc, 1, frac_sign(frac_make(1, 1)));
CuAssertIntEquals(tc, -1, frac_sign(frac_make(-1, 1)));
CuAssertIntEquals(tc, -1, frac_sign(frac_make(1, -1)));
CuAssertIntEquals(tc, 0, frac_sign(frac_make(0, 1)));
}
CuSuite *get_variant_suite(void)