543 lines
12 KiB
C++
Executable File
543 lines
12 KiB
C++
Executable File
#include <stdio.h>
|
|
|
|
#include <fraction.h>
|
|
#include <strings.h>
|
|
|
|
|
|
static __int64 mcd(__int64 a, __int64 b)
|
|
{
|
|
if (a < 0) a = -a;
|
|
if (b < 0) b = -b;
|
|
while (b > 0)
|
|
{
|
|
__int64 r = a % b;
|
|
a = b;
|
|
b = r;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
static __int64 mcm(__int64 a, __int64 b)
|
|
{
|
|
if (a < 0) a = -a;
|
|
if (b < 0) b = -b;
|
|
return ((a * b) / mcd(a, b));
|
|
}
|
|
|
|
void fraction::simplify()
|
|
{
|
|
if (_den > 1 && _num > 1)
|
|
{
|
|
__int64 div = mcd(_num, _den);
|
|
if (div > 1)
|
|
{
|
|
_num /= div;
|
|
_den /= div;
|
|
}
|
|
}
|
|
if (_den < 0)
|
|
{
|
|
_num = -_num;
|
|
_den = -_den;
|
|
}
|
|
}
|
|
|
|
// Crea una frazione a partire da una stringa avente la VIRGOLA come separatore dei decimali!
|
|
void fraction::build_fraction (const char *s)
|
|
{
|
|
TString80 n = s;
|
|
|
|
_num = 0;
|
|
_den = 1;
|
|
if (n.full())
|
|
{
|
|
int pdec = n.find(',');
|
|
const int psqr = n.find('['), psls = n.find('/');
|
|
int ndec = 0, len_periodo = 0, sign = 1, anti_periodo = 0;
|
|
if (pdec < 0)
|
|
pdec = n.find('.');
|
|
|
|
if (n.find('-') >= 0)
|
|
sign = -1;
|
|
if (pdec >= 0)
|
|
ndec = n.len() - pdec - 1;
|
|
|
|
if (psls > 0)
|
|
{
|
|
TString80 num = n.left(psls);
|
|
fraction a(num);
|
|
num = n.mid(psls + 1);
|
|
fraction b(num);
|
|
*this = a / b;
|
|
return;
|
|
}
|
|
if (psqr > 0)
|
|
{
|
|
int end = n.find(']');
|
|
|
|
if (end < psqr)
|
|
end = n.len();
|
|
len_periodo = end - psqr - 1;
|
|
anti_periodo = psqr -pdec - 1;
|
|
}
|
|
else
|
|
if (ndec > 2)
|
|
{
|
|
bool found = FALSE;
|
|
int j = 0;
|
|
const char * pc;
|
|
|
|
for (pc = (const char *)n + pdec + 1; !found && *pc != '\0'; pc++)
|
|
{
|
|
int max_period = strlen(pc) / 3;
|
|
for (j = max_period; !found && j > 0 ; j--)
|
|
{
|
|
int len = 0, pos = 0, c;
|
|
|
|
for (c = 0; c < j; c++)
|
|
{
|
|
const char * pp = pc + c;
|
|
len = strlen(pp);
|
|
char cmp = *pp;
|
|
pos = 0;
|
|
while (pos < len)
|
|
{
|
|
if (pp[pos] != cmp)
|
|
if (pos < len - 1 || (pp[pos] - cmp) != 1 || *(pp + 1) < '5')
|
|
break;
|
|
pos += j;
|
|
}
|
|
if (pos < len)
|
|
break;
|
|
}
|
|
found = (pos == len) && (c == (len + 1) % j + 1);
|
|
}
|
|
if (!found)
|
|
anti_periodo++;
|
|
}
|
|
if (found)
|
|
{
|
|
len_periodo = j + 1;
|
|
n.cut(pdec + anti_periodo + len_periodo + 1);
|
|
}
|
|
}
|
|
n.strip(",.-+/[]");
|
|
sscanf_s(n, "%I64d", &_num);
|
|
if (len_periodo > 0)
|
|
{
|
|
_den = 9;
|
|
__int64 sub = _num / 10;
|
|
for (int l = len_periodo - 1; l > 0 ; l--)
|
|
{
|
|
_den = (_den * 10) + 9;
|
|
sub /= 10;
|
|
}
|
|
if (anti_periodo > 0)
|
|
for (int p = anti_periodo; p > 0; p--)
|
|
_den *= 10;
|
|
_num -= sub;
|
|
}
|
|
else
|
|
for (int p = ndec; p > 0; p--)
|
|
_den *= 10;
|
|
|
|
_num *= sign;
|
|
}
|
|
simplify();
|
|
}
|
|
|
|
fraction::fraction()
|
|
{
|
|
_num = 0;
|
|
_den = 1;
|
|
}
|
|
|
|
fraction::fraction(const fraction& b)
|
|
{
|
|
_num = b._num;
|
|
_den = b._den;
|
|
}
|
|
|
|
fraction::fraction(const real& num, const real& den)
|
|
{
|
|
if (den.is_zero())
|
|
build_fraction("");
|
|
else
|
|
{
|
|
if (den == UNO)
|
|
build_fraction(num.stringa());
|
|
else
|
|
{
|
|
real n = num; n /= den;
|
|
build_fraction(n.stringa());
|
|
}
|
|
}
|
|
}
|
|
|
|
int fraction::sign() const
|
|
{
|
|
if (_num == 0 || _den == 0)
|
|
return 0;
|
|
return _num < 0 ? (_den < 0 ? +1 : -1) : (_den < 0 ? -1 : +1);
|
|
}
|
|
|
|
fraction& fraction::operator =(const fraction & b)
|
|
{
|
|
_num = b._num;
|
|
_den = b._den;
|
|
return *this;
|
|
}
|
|
|
|
fraction& fraction::operator += (const fraction & b)
|
|
{
|
|
const __int64 m = mcm(_den, b._den);
|
|
_num = _num * ( m / _den) + b._num * ( m / b._den);
|
|
_den = m;
|
|
simplify();
|
|
return *this;
|
|
}
|
|
|
|
fraction& fraction::operator -= (const fraction & b)
|
|
{
|
|
const __int64 m = mcm(_den, b._den);
|
|
_num = _num * ( m / _den) - b._num * ( m / b._den);
|
|
_den = m;
|
|
simplify();
|
|
return *this;
|
|
}
|
|
|
|
fraction& fraction::operator *= (const fraction & b)
|
|
{
|
|
_num = _num * b._num;
|
|
_den = _den * b._den;
|
|
simplify();
|
|
return *this;
|
|
}
|
|
|
|
fraction& fraction::operator /= (const fraction & b)
|
|
{
|
|
_num = _num * b._den;
|
|
_den = _den * b._num;
|
|
simplify();
|
|
return *this;
|
|
}
|
|
|
|
fraction fraction::operator - () const
|
|
{
|
|
fraction b(*this);
|
|
b._num = -b._num;
|
|
return b;
|
|
}
|
|
|
|
// Funzioni comuni dei due real
|
|
|
|
TObject* fraction::dup () const
|
|
{
|
|
return new fraction(*this);
|
|
}
|
|
|
|
fraction::operator real() const
|
|
{
|
|
real n, d;
|
|
n.set_int64(_num);
|
|
d.set_int64(_den);
|
|
|
|
real q = n; q /= d;
|
|
return q;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func real | operator + | Somma due numeri reali
|
|
//
|
|
// @rdesc Ritorna il valore della somma
|
|
fraction operator + (
|
|
const fraction & a, // @parm Primo addendo da sommare
|
|
const fraction & b) // @parm Secondo addendo da sommare
|
|
|
|
// @syntax operator +(const fraction & a, const fraction & b);
|
|
// @syntax operator +(const real & a, const fraction & b);
|
|
// @syntax operator +(const fraction & a, const real & b);
|
|
|
|
{
|
|
fraction f = a;
|
|
f += b;
|
|
return f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func real | operator - | Sottrae due numeri reali
|
|
//
|
|
// @rdesc Ritorna il valore della sottrazione
|
|
fraction operator - (
|
|
const fraction & a, // @parm Primo addendo da sottrarre
|
|
const fraction & b) // @parm Secondo addendo da sottrarre
|
|
|
|
// @syntax operator -(const fraction & a, const fraction & b);
|
|
// @syntax operator -(const real & a, const fraction & b);
|
|
// @syntax operator -(const fraction & a, const real & b);
|
|
{
|
|
fraction f = a;
|
|
f -= b;
|
|
return f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func real | operator * | Moltiplica due frazioni
|
|
//
|
|
// @rdesc Ritorna il valore della moltiplicazione
|
|
fraction operator *(
|
|
const fraction & a, // @parm Prima frazione da moltiplicare
|
|
const fraction & b) // @parm Seconda frazione da moltiplicare
|
|
|
|
// @syntax operator *(const fraction & a, const fraction & b);
|
|
// @syntax operator *(const real & a, const fraction & b);
|
|
// @syntax operator *(const fraction & a, const real & b);
|
|
|
|
{
|
|
fraction f = a;
|
|
f *= b;
|
|
return f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func real | operator * | Moltiplica una frazione e un intero
|
|
//
|
|
// @rdesc Ritorna il valore della moltiplicazione
|
|
fraction operator *(
|
|
const fraction & a, // @parm frazione da moltiplicare
|
|
__int64 b) // @parm intero da moltiplicare
|
|
|
|
// @syntax operator -(__int64 a, const fraction & b);
|
|
// @syntax operator -(const fraction & a, __int64 b);
|
|
|
|
{
|
|
fraction f;
|
|
f._num = a._num * b;
|
|
f._den = a._den;
|
|
f.simplify();
|
|
return f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func real | operator / | Divide due frazioni
|
|
//
|
|
// @rdesc Ritorna il valore della divisione
|
|
fraction operator / (
|
|
const fraction & a, // @parm Prima frazione da dividere
|
|
const fraction & b) // @parm Seconda frazione da dividere
|
|
|
|
// @syntax operator /(const fraction & a, const fraction & b);
|
|
// @syntax operator /(const real & a, const fraction & b);
|
|
// @syntax operator /(const fraction & a, const real & b);
|
|
{
|
|
fraction f = a;
|
|
f /= b;
|
|
return f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func real | operator * | Divide una frazione per un intero
|
|
//
|
|
// @rdesc Ritorna il valore della divisione
|
|
fraction operator /(
|
|
const fraction & a, // @parm frazione da dividere
|
|
__int64 b) // @parm intero divisore
|
|
// @syntax operator /(const fraction & a, __int64 b);
|
|
|
|
{
|
|
fraction f;
|
|
f._num = a._num;
|
|
f._den = a._den * b;
|
|
f.simplify();
|
|
return f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func real | operator * | Divide una frazione per un intero
|
|
//
|
|
// @rdesc Ritorna il valore della divisione
|
|
fraction operator /(
|
|
__int64 a, // @parm intero da dividere
|
|
const fraction & b) // @parm frazione divisore
|
|
// @syntax operator /(__int64 a, const fraction & b);
|
|
|
|
{
|
|
fraction f;
|
|
f._num = b._den * a;
|
|
f._den = b._num ;
|
|
f.simplify();
|
|
return f;
|
|
}
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func bool | operator <gt> | Controlla se un reale e' maggiore di un altro
|
|
//
|
|
// @rdesc Ritorna i seguenti valori
|
|
//
|
|
// @flag TRUE | Se <p a> e' maggiore di <p b>
|
|
// @flag FALSE | Se <p a> e' non maggiore di <p b>
|
|
bool operator > (
|
|
const fraction & a, // @parm Prima frazione da confrontare
|
|
const fraction & b) // @parm Seconda frazione da confrontare
|
|
|
|
// @syntax operator <gt> (const fraction & a, const fraction & b);
|
|
// @syntax operator <gt> (const real & a, const fraction &b);
|
|
// @syntax operator <gt> (const fraction &a, const real & b);
|
|
|
|
{
|
|
fraction f = a - b;
|
|
return f.sign() > 0;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func bool | operator <lt> | Controlla se un reale e' minore di un altro
|
|
//
|
|
// @rdesc Ritorna i seguenti valori
|
|
//
|
|
// @flag TRUE | Se <p a> e' minore di <p b>
|
|
// @flag FALSE | Se <p a> e' non minore di <p b>
|
|
bool operator < (
|
|
const fraction & a, // @parm Prima frazione da confrontare
|
|
const fraction & b) // @parm Seconda frazione da confrontare
|
|
|
|
// @syntax operator <lt> (const fraction &a, const fractio &b);
|
|
// @syntax operator <lt> (const real & a, const fraction &b);
|
|
// @syntax operator <lt> (const fraction &a, const real & b);
|
|
|
|
{
|
|
fraction f = a - b;
|
|
return f.sign() < 0;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func bool | operator <gt>= | Controlla se un reale e' maggiore o uguale ad
|
|
// un altro
|
|
//
|
|
// @rdesc Ritorna i seguenti valori
|
|
//
|
|
// @flag TRUE | Se <p a> e' maggiore o uguale a <p b>
|
|
// @flag FALSE | Se <p a> e' minore di <p b>
|
|
bool operator >= (
|
|
const fraction & a, // @parm Prima frazione da confrontare
|
|
const fraction & b) // @parm Seconda frazione da confrontare
|
|
|
|
// @syntax operator <gt>= (const fraction &a, const fractio &b);
|
|
// @syntax operator <gt>= (const real & a, const fraction &b);
|
|
// @syntax operator <gt>= (const fraction &a, const real & b);
|
|
|
|
{
|
|
fraction f = a - b;
|
|
return f.sign() >= 0;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func bool | operator <lt>= | Controlla se un reale e' minore o uguale ad
|
|
// un altro
|
|
//
|
|
// @rdesc Ritorna i seguenti valori
|
|
//
|
|
// @flag TRUE | Se <p a> e' minore o uguale a <p b>
|
|
// @flag FALSE | Se <p a> e' maggiore di <p b>
|
|
bool operator <= (
|
|
const fraction & a, // @parm Prima frazione da confrontare
|
|
const fraction & b) // @parm Seconda frazione da confrontare
|
|
|
|
// @syntax operator <lt>= (const fraction &a, const fractio &b);
|
|
// @syntax operator <lt>= (const real & a, const fraction &b);
|
|
// @syntax operator <lt>= (const fraction &a, const real & b);
|
|
{
|
|
fraction f = a - b;
|
|
return f.sign() <= 0;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func bool | operator == | Controlla se un reale e' uguale ad un altro
|
|
//
|
|
// @rdesc Ritorna i seguenti valori
|
|
//
|
|
// @flag TRUE | Se <p a> e' uguale a <p b>
|
|
// @flag FALSE | Se <p a> non e' uguale a <p b>
|
|
bool operator == (
|
|
const fraction & a, // @parm Prima frazione da confrontare
|
|
const fraction & b) // @parm Seconda frazione da confrontare
|
|
|
|
// @syntax operator == (const fraction &a, const fractio &b);
|
|
// @syntax operator == (const real & a, const fraction &b);
|
|
// @syntax operator == (const fraction &a, const real & b);
|
|
{
|
|
fraction f = a - b;
|
|
return f.sign() == 0;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func bool | operator != | Controlla se 2 reali dono diversi
|
|
//
|
|
// @rdesc Ritorna i seguenti valori
|
|
//
|
|
// @flag TRUE | Se <p a> e' diverso da <p b>
|
|
// @flag FALSE | Se <p a> e' uguale a <p b>
|
|
bool operator != (
|
|
const fraction & a, // @parm Prima frazione da confrontare
|
|
const fraction & b) // @parm Seconda frazione da confrontare
|
|
|
|
// @syntax operator != (const fraction &a, const fractio &b);
|
|
// @syntax operator != (const real & a, const fraction &b);
|
|
// @syntax operator != (const fraction &a, const real & b);
|
|
{
|
|
return ! ::operator ==(a, b);
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func Scambia la frazione <p a> con la frazione <p b>
|
|
void swap (
|
|
fraction & a, // @parm Prima frazione da scambiare
|
|
fraction & b) // @parm Seconda frazione da scambiare
|
|
|
|
{
|
|
fraction f = a;
|
|
a = b;
|
|
b = f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func Ritorna il numero reale piu' piccolo tra <p a> e <p b>
|
|
const fraction& fnc_min (
|
|
const fraction & a, // @parm Prima frazione da confrontare
|
|
const fraction & b) // @parm Seconda frazione da confrontare
|
|
|
|
// @syntax const real& fnc_min (const fraction & a, const fraction & b)
|
|
|
|
{
|
|
return a < b ? a : b;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @func Ritorna il numero reale piu' grande tra <p a> e <p b>
|
|
const fraction& fnc_max (
|
|
const fraction & a, // @parm Prima frazione da confrontare
|
|
const fraction & b) // @parm Seconda frazione da confrontare
|
|
|
|
// @syntax const real& fnc_max (const fraction & a, const fraction & b)
|
|
|
|
{
|
|
return a > b ? a : b;
|
|
}
|
|
|