Posted By: txesmi
[SUB] Fractions - 05/15/18 10:44
Hi!
I wrote a little module to work with fractions.
ifractions.h
ifractions.c
Maybe a bit overheaded of simplification.
Enjoy!
I wrote a little module to work with fractions.
ifractions.h
Code:
#ifndef _IFRACTIONS_H_ #define _IFRACTIONS_H_ #define TEMPFRAC_COUNT 16 typedef struct IFRAC { int num; int den; } IFRAC; IFRAC *ifraction(int _num, int _den); // temporal ifrac IFRAC *ifracSet(IFRAC *_ifracA, IFRAC *_ifracB); IFRAC *ifracAdd(IFRAC *_ifracA, IFRAC *_ifracB); IFRAC *ifracSub(IFRAC *_ifracA, IFRAC *_ifracB); IFRAC *ifracDiff(IFRAC *_ifracR, IFRAC *_ifracA, IFRAC *_ifracB); IFRAC *ifracMul(IFRAC *_ifracA, IFRAC *_ifracB); IFRAC *ifracDiv(IFRAC *_ifracA, IFRAC *_ifracB); IFRAC *ifracSimplify(IFRAC *_ifrac); IFRAC *ifracCommonDen(IFRAC *_ifracA, IFRAC *_ifracB); var ifracToNum(IFRAC *_ifrac); IFRAC *ifracForNum(IFRAC *_ifrac, var _n); void ifracPrintf(IFRAC *_ifrac); #include "ifractions.c" #endif
ifractions.c
Code:
int _mathGCD(int _a, int _b) { for (;;) { if (_a == 0) return _b; _b %= _a; if (_b == 0) return _a; _a %= _b; } } int _mathLCM(int _a, int _b) { int _t = _mathGCD(_a, _b); if (!_t) return 0; return _a / _t * _b; } IFRAC _ifracTemp[TEMPFRAC_COUNT]; IFRAC *_ifracZero = {num = 0; den = 1;} IFRAC *ifraction(int _num, int _den) { static int _i = 0; IFRAC *_ifrac = _ifracTemp + _i; _i = (_i + 1) % TEMPFRAC_COUNT; memcpy(_ifrac, &_num, sizeof(IFRAC)); return ifracSimplify(_ifrac); } IFRAC *ifracSet(IFRAC *_ifracA, IFRAC *_ifracB) { memcpy(_ifracA, _ifracB, sizeof(IFRAC)); return ifracSimplify(_ifracA); } IFRAC *ifracSimplify(IFRAC *_ifrac) { int _gcd = _mathGCD(abs(_ifrac->num), abs(_ifrac->den)); if (_gcd) { _ifrac->num /= _gcd; _ifrac->den /= _gcd; } if ((_ifrac->num == 0) || (_ifrac->den == 0)) { memcpy(_ifrac, _ifracZero, sizeof(IFRAC)); } else if (_ifrac->den < 0) { _ifrac->num *= -1; _ifrac->den *= -1; } return _ifrac; } IFRAC *ifracCommonDen(IFRAC *_ifracA, IFRAC *_ifracB) { int _lcm = _mathLCM(_ifracA->den, _ifracB->den); _ifracA->num *= _lcm / _ifracA->den; _ifracA->den = _lcm; _ifracB->num *= _lcm / _ifracB->den; _ifracB->den = _lcm; return _ifracA; } IFRAC *ifracAdd(IFRAC *_ifracA, IFRAC *_ifracB) { IFRAC *_ifracT = ifraction(_ifracB->num, _ifracB->den); ifracCommonDen(_ifracA, _ifracT); _ifracA->num += _ifracT->num; return ifracSimplify(_ifracA); } IFRAC *ifracSub(IFRAC *_ifracA, IFRAC *_ifracB) { IFRAC *_ifracT = ifraction(_ifracB->num, _ifracB->den); ifracCommonDen(_ifracA, _ifracT); _ifracA->num -= _ifracT->num; return ifracSimplify(_ifracA); } IFRAC *ifracDiff(IFRAC *_ifracR, IFRAC *_ifracA, IFRAC *_ifracB) { ifracSet(_ifracR, _ifracA); return ifracSub(_ifracR, _ifracB); } IFRAC *ifracMul(IFRAC *_ifracA, IFRAC *_ifracB) { _ifracA->num *= _ifracB->num; _ifracA->den *= _ifracB->den; return ifracSimplify(_ifracA); } IFRAC *ifracDiv(IFRAC *_ifracA, IFRAC *_ifracB) { _ifracA->num *= _ifracB->den; _ifracA->den *= _ifracB->num; return ifracSimplify(_ifracA); } var ifracToNum(IFRAC *_ifrac) { return (var)_ifrac->num / _ifrac->den; } IFRAC *ifracForNum(IFRAC *_ifrac, var _n) { _ifrac->num = _n << 10; _ifrac->den = 1024; return ifracSimplify(_ifrac); } void ifracPrintf(IFRAC *_ifrac) { printf("%d / %d", _ifrac->num, _ifrac->den); }
Maybe a bit overheaded of simplification.
Enjoy!