campo-sirio/include/fraction.cpp
alex 132452fd50 Patch level : Aga 2.0.349
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Riportata la versione P@rtners 2.0 patch 349


git-svn-id: svn://10.65.10.50/trunk@10573 c028cbd2-c16b-5b4b-a496-9718f37d4682
2002-10-24 10:47:49 +00:00

440 lines
9.8 KiB
C++
Executable File

#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <fraction.h>
#include <utility.h>
void fraction::simplify()
{
__int64 div = mcd(_num, _den);
if (div > 1)
{
_num /= div;
_den /= div;
}
if (_den < 0)
{
_num = -_num;
_den = -_den;
}
}
void fraction::build_fraction (const char *s)
{
TString n = get_tmp_string(80); n = s;
_num = 0;
_den = 1;
if (n.not_empty())
{
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;
for (const char * pc = (const char *)n + pdec + 1; !found && *pc != NULL;pc++)
{
int max_period = strlen(pc) / 3;
for (j = max_period; !found && j > 0 ; j--)
{
int len, pos;
for (int 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(n, "%Ld", &_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::operator =(const fraction & b)
{
_num = b._num;
_den = b._den;
return *this;
}
fraction& fraction::operator += (const fraction & b)
{
__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)
{
__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);
return n / d;
}
// @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 numeri reali
//
// @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 real &a, const real &b);
// @syntax operator *(double a, const real &b);
// @syntax operator *(const real &a, double b);
{
fraction f = a;
f *= b;
return f;
}
// @doc EXTERNAL
// @func real | operator / | Divide due numeri reali
//
// @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 real &a, const real &b);
// @syntax operator /(double a, const real &b);
// @syntax operator /(const real &a, double b);
{
fraction f = a;
f /= b;
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;
}