Files correlati : agalib Ricompilazione Demo : [ ] Commento : Implementato di meccanismo generico di blocco degli inserimenti, attivabile nelle singole applicazioni (cg2 e ve0) git-svn-id: svn://10.65.10.50/branches/R_10_00@22420 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			554 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			554 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;
 | 
						|
 | 
						|
	__int64 r;
 | 
						|
	while (b > 0)
 | 
						|
	{
 | 
						|
    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.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 = 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(",.-+/[]");
 | 
						|
#ifdef WIN32
 | 
						|
	  sscanf(n, "%I64d", &_num);
 | 
						|
#else	  
 | 
						|
	  sscanf(n, "%Ld", &_num);
 | 
						|
#endif
 | 
						|
		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 == 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)
 | 
						|
{
 | 
						|
	__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;
 | 
						|
}
 | 
						|
 |