Files correlati : omnia0.exe Ricompilazione Demo : [ ] Commento : Prima release Acqua Omnia git-svn-id: svn://10.65.10.50/trunk@11726 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1810 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1810 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <ctype.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #include "real.h"
 | |
| 
 | |
| const real ZERO(0.0);
 | |
| const real UNO(1.0);
 | |
| const real CENTO(100.0);
 | |
| 
 | |
| #ifdef __LONGDOUBLE__
 | |
| 
 | |
| #include <math.h>
 | |
| 
 | |
| #include <stdio.h>
 | |
| inline long double _atold(const char* str)
 | |
| {
 | |
|   long double num = 0.0;
 | |
|   sscanf(str, "%Lf", &num);
 | |
|   return num;
 | |
| }
 | |
| 
 | |
| real::real () : _dec(0.0)
 | |
| { }
 | |
| 
 | |
| real::real (const real& b) : _dec(b._dec)
 | |
| { }
 | |
| 
 | |
| real::real (long double a) : _dec(a)
 | |
| { }
 | |
| 
 | |
| void real::set_int64(__int64 b)
 | |
| {
 | |
| 	_dec = (long double)b;
 | |
| }
 | |
| 
 | |
| bool real::is_real (const char *s)
 | |
| {             
 | |
|   if (s && *s)
 | |
|   {  
 | |
|     const long double n = _atold(s);
 | |
|     if (n == 0.0)
 | |
|     {
 | |
|       for(; *s; s++) if (*s != '0' && *s != ' ' && *s != '.')
 | |
|         return FALSE;
 | |
|     }    
 | |
|   }  
 | |
|   return TRUE;
 | |
| }               
 | |
| 
 | |
| real::real (const char *s)
 | |
| {                        
 | |
|   _dec = (s && *s) ? _atold(s) : 0.0;
 | |
| }
 | |
| 
 | |
| real& real::operator = (const real& b)
 | |
| {
 | |
|   _dec = b._dec;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator = (long double b)
 | |
| {
 | |
|   _dec = b;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator += (long double b)
 | |
| {     
 | |
|   _dec += b;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator -= (long double b)
 | |
| {     
 | |
|   _dec -= b;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator *= (long double b)
 | |
| {
 | |
|   _dec *= b;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator /= (long double b)
 | |
| { 
 | |
|   CHECK(b != 0.0, "Division by zero");
 | |
|   _dec /= b;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Ritorna il segno del reale                       
 | |
| //
 | |
| // @rdesc Ritorna i seguenti valori:
 | |
| // 
 | |
| // @flag <lt> 0 | Se il numero e' minore di 0
 | |
| // @flag = 0 | Se il numero e' uguale a 0
 | |
| // @flag <gt> 0 | Se il numero e' maggiore di 0
 | |
| int real::sign () const
 | |
| {
 | |
|   const int s = _dec > 0.0 ? +1 : (_dec < 0.0 ? -1 : 0);
 | |
|   return s;
 | |
| }
 | |
| 
 | |
| real real::operator - () const
 | |
| {
 | |
|   real n(-_dec);
 | |
|   return n;
 | |
| }
 | |
| 
 | |
| long real::integer () const
 | |
| {
 | |
|   return (long)floorl(_dec);
 | |
| }
 | |
| 
 | |
| // Certified 91%
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Trasforma un reale in stringa
 | |
| //
 | |
| // @rdesc Ritorna la stringa nella lunghezza richiesta
 | |
| const char *real::string (
 | |
|   int len,        // @parm Lunghezza della stringa (compreso decimali)
 | |
|   int dec,        // @parm Numero di decimali (default UNDEFINED)
 | |
|   char pad) const // @parm Carattere di riempimento (default ' ')
 | |
|   // @parm char * | picture | Formato della stringa
 | |
| 
 | |
|   // @syntax string (int len, int dec, char pad);
 | |
|   // @syntax string (const char *picture);
 | |
|   //
 | |
|   // @comm Nel primo caso ritorna una stringa lunga <p len> con <p dec> decimali e
 | |
|   //       inserisce nella stringa stessa il carattere <p pad> nel caso la
 | |
|   //       lunghezza richiesta sia maggiore di quella che risulterebbe per la
 | |
|   //       completa rappresentazione del reale.
 | |
|   //       <nl>Nel secondo caso ritorna la stringa con il formato stabilito in
 | |
|   //       <p picture>.
 | |
| 
 | |
| {          
 | |
|   TString16 fmt("%");
 | |
|   if (pad != ' ') fmt << '0';
 | |
|   if (len != 0) fmt << len;
 | |
|   if (dec != UNDEFINED) fmt << '.' << dec;
 | |
|   fmt << "Lf";
 | |
| 
 | |
|   TString& tmp = get_tmp_string();
 | |
| 	char* __string = tmp.get_buffer(len);
 | |
| 
 | |
|   sprintf(__string, fmt, _dec);
 | |
| 
 | |
|   if (len == 0 && dec == UNDEFINED && strchr(__string, '.') != NULL)
 | |
|   {                                              
 | |
|     int cut = strlen (__string);
 | |
|     for (int i = cut-1; i >= 0; i--)
 | |
|     {
 | |
|       if (__string[i] == '0')
 | |
|         cut--;
 | |
|       else
 | |
|       {  
 | |
|         if(__string[i] == '.')
 | |
|           cut--;
 | |
|         break;
 | |
|       }    
 | |
|     }  
 | |
|     __string[cut] = '\0';    
 | |
|   }  
 | |
|   return __string;
 | |
| }
 | |
| 
 | |
| // Childish algorithm faster and more accurate than powl(10.0, pow)
 | |
| HIDDEN void ipow10(int pow, double& m, double& d)
 | |
| {                         
 | |
|   m = d = 1.0;
 | |
|   if (pow > 0)
 | |
|   {
 | |
|     for (int i = pow; i > 0; i--)   
 | |
|     {
 | |
|       m *= 10.0;
 | |
|       d *= 0.1;
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     for (int i = pow; i < 0; i++)   
 | |
|     {
 | |
|       m *= 0.1;
 | |
|       d *= 10.0;
 | |
|     }
 | |
|   }        
 | |
| }
 | |
| 
 | |
| int real::precision() const
 | |
| {
 | |
|   const TFixed_string s(string());
 | |
|   const int d = s.find('.');
 | |
|   const int p = d < 0 ? 0 : (s.len()-d-1);
 | |
|   return p;
 | |
| }
 | |
| 
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc real& | real | round | Arrotonda al numero di decimali passati
 | |
| real& real::round (
 | |
|   int prec)  // @parm Numero di decimali a cui arrotondare il numero (default 0)
 | |
| 
 | |
|   // @comm Nel caso <p prec> sia:    
 | |
|   //
 | |
|   // @flag <gt> 0 | Arrotonda al decimale
 | |
|   // @flag = 0 | Arrotonda all'intero
 | |
|   // @flag <lt> 0  | Arrotonda al valore passato (es. -3 arrotonda alle mille)
 | |
| {    
 | |
|   if (abs(prec) < 20)
 | |
|   {
 | |
|     double m, d;
 | |
|     if (prec != 0)
 | |
|     {                  
 | |
|       ipow10(prec, m, d);
 | |
|       if (prec < 0)
 | |
|         _dec /= d;
 | |
|       else  
 | |
|         _dec *= m;
 | |
|     }  
 | |
|     
 | |
|     if (_dec >= 0.0)
 | |
|       _dec = floorl(_dec + 0.5);
 | |
|     else
 | |
|       _dec = ceill(_dec - 0.5);  
 | |
|     
 | |
|     if (prec != 0)
 | |
| 		{
 | |
|       if (prec < 0)
 | |
|         _dec *= d;
 | |
|       else  
 | |
|         _dec /= m;
 | |
| 		}
 | |
|   }  
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::ceil (int prec)
 | |
| {
 | |
|   double m, d;
 | |
|   if (prec != 0)
 | |
|   {
 | |
|     ipow10(prec, m, d);
 | |
|     _dec *= m;
 | |
|   }
 | |
|   _dec = ceill(_dec);
 | |
|   if (prec != 0)
 | |
| //      _dec *= d;   Risulta stranamente molto impreciso!
 | |
|     _dec /= m;
 | |
| 
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::floor (int prec)
 | |
| {
 | |
|   double m, d;
 | |
|   if (prec != 0)
 | |
|   {
 | |
|     ipow10(prec, m, d);
 | |
|     _dec *= m;
 | |
|   }
 | |
|   _dec = floorl(_dec);
 | |
|   if (prec != 0)
 | |
| //      _dec *= d;   Risulta stranamente molto impreciso!
 | |
|     _dec /= m;
 | |
| 
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::trunc(int prec)
 | |
| {
 | |
|   double m, d;
 | |
|   if (prec != 0)
 | |
|   {
 | |
|     ipow10(prec, m, d);
 | |
|     _dec *= m;
 | |
|   }
 | |
|   _dec = floorl(_dec);
 | |
|   if (prec != 0)
 | |
| //      _dec *= d;   Risulta stranamente molto impreciso!
 | |
|     _dec /= m;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Scambia il numero reale <p a> con il numero real <p b>
 | |
| void swap (
 | |
|   real& a,  // @parm Primo numero da scambiare
 | |
|   real& b)  // @parm Secondo numero da scambiare
 | |
| 
 | |
| {
 | |
|   const real n = a;
 | |
|   a = b;
 | |
|   b = n;
 | |
| }           
 | |
| 
 | |
| long double operator%(const real& a, const real& b)
 | |
| {
 | |
|   const long double times = floorl(a / b);
 | |
|   const long double resto = a - b * times;
 | |
|   return resto;
 | |
| }
 | |
| 
 | |
| long double sqrt(long double a) 
 | |
| {  
 | |
|   return sqrtl(a); 
 | |
| }
 | |
| 
 | |
| long double sqr(long double a)
 | |
| {
 | |
|   return a*a; 
 | |
| }
 | |
| 
 | |
| long double exp10(long double a) 
 | |
| {
 | |
|   return powl(10.0, a);
 | |
| }
 | |
| 
 | |
| long double pow(long double a, long double b)
 | |
| {
 | |
|   return powl(a, b);
 | |
| }
 | |
| 
 | |
| long double exp(long double a) 
 | |
| {
 | |
|   return expl(a);
 | |
| }
 | |
| 
 | |
| long double log10(long double a)
 | |
| {
 | |
|   return log10l(a);
 | |
| }
 | |
| 
 | |
| long double log(long double a)
 | |
| {                             
 | |
|   return logl(a);
 | |
| }
 | |
| 
 | |
| long double sin(long double a)
 | |
| {
 | |
|   return sinl(a);
 | |
| }
 | |
| 
 | |
| long double cos(long double a)
 | |
| {
 | |
|   return cosl(a);
 | |
| }
 | |
| 
 | |
| long double tan(long double a)
 | |
| {
 | |
|   return tanl(a);
 | |
| }
 | |
| 
 | |
| long double abs(long double a)
 | |
| {
 | |
|   return fabsl(a);
 | |
| }
 | |
| 
 | |
| #else
 | |
| 
 | |
| #include <gm.h>
 | |
| 
 | |
| extern "C"
 | |
| {
 | |
|   double pow (double, double);
 | |
| }                               // Should be #include <math.h>
 | |
| 
 | |
| 
 | |
| HIDDEN real __tmp_real;
 | |
| 
 | |
| real::real ()
 | |
| {
 | |
|   dzero (ptr ());
 | |
|   trail();
 | |
| }
 | |
| 
 | |
| real::real (const real & b)
 | |
| {
 | |
|   dcpy (ptr (), b.ptr ());
 | |
| }
 | |
| 
 | |
| real::real (double a)
 | |
| {
 | |
|   dftodr (ptr (), a, 9);        // Round the number (1.0 is NOT 0.999999999)
 | |
| 
 | |
|   trail( );      // Delete Trailing zeroes
 | |
| 
 | |
| }
 | |
| 
 | |
| void real::set_int64(__int64 b)
 | |
| {
 | |
| 	TString80 s; s.format("%I64d", b);
 | |
| 
 | |
|   atod (ptr (), (char *) (const char *) s);
 | |
|   trail();
 | |
| }
 | |
| 
 | |
| void real::trail( )
 | |
| {
 | |
|   deltrz (ptr (), ptr () );      // Delete Trailing zeroes
 | |
| }
 | |
| 
 | |
| bool real::is_real (const char *s)
 | |
| {
 | |
|   bool ok = TRUE;
 | |
|   if (s)
 | |
|   {
 | |
|     while (*s == ' ')
 | |
|       s++;                    // Remove leading spaces before atod
 | |
|     if (*s)
 | |
|       ok = atod (__tmp_real.ptr (), (char *) s) != GM_NULL;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| real::real (const char *s)
 | |
| {
 | |
|   if (s)
 | |
|     while (*s == ' ')
 | |
|       s++;                      // Remove leading spaces before atod
 | |
| 
 | |
|   if (s && *s)
 | |
|     atod (ptr (), (char *) s);
 | |
|   else
 | |
|     dzero (ptr ());
 | |
|   
 | |
|   trail();
 | |
| }
 | |
| 
 | |
| real& real::operator =(const real & b)
 | |
| {
 | |
|   dcpy (ptr (), b.ptr ());
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator =(double a)
 | |
| {
 | |
|   const real n (a);
 | |
|   operator = (n);
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator += (const real & b)
 | |
| {
 | |
|   dadd (ptr (), ptr (), b.ptr ());
 | |
|   trail( );
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator += (double a)
 | |
| {
 | |
|   adddfd (ptr (), ptr (), a);
 | |
|   trail( );
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator -= (const real & b)
 | |
| {
 | |
|   dsub (ptr (), ptr (), b.ptr ());
 | |
|   trail( );
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator *= (const real & b)
 | |
| {
 | |
|   dmul (ptr (), ptr (), b.ptr ());
 | |
|   trail( );
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real& real::operator /= (const real & b)
 | |
| {
 | |
|   const DEC *dst = ddiv (ptr (), ptr (), b.ptr ());
 | |
| 
 | |
| #ifdef DBG
 | |
|   if (dst == GM_NULL)
 | |
|   {
 | |
|     char * s = get_tmp_string().get_buffer(256);
 | |
| 		errname (s, gmec ());
 | |
|     error_box ("Division error: %s", s);
 | |
| 
 | |
|   }
 | |
| #endif
 | |
|   trail( );
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| bool real::is_zero () const
 | |
| {
 | |
|   return diszero (ptr ()) != 0;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Ritorna il segno del reale                       
 | |
| //
 | |
| // @rdesc Ritorna i seguenti valori:
 | |
| // 
 | |
| // @flag <lt> 0 | Se il numero e' minore di 0
 | |
| // @flag = 0 | Se il numero e' uguale a 0
 | |
| // @flag <gt> 0 | Se il numero e' maggiore di 0
 | |
| int real::sign () const
 | |
| 
 | |
| {
 | |
|   return dsign (ptr ());
 | |
| }
 | |
| 
 | |
| real real::operator - () const
 | |
| {
 | |
|   real n;
 | |
|   dchgs (n.ptr (), ptr ());
 | |
|   //  n.trail( );
 | |
|   return n;
 | |
| }
 | |
| 
 | |
| long real::integer () const
 | |
| {
 | |
|   return (long)dtodf(ptr ());
 | |
| }
 | |
| 
 | |
| // Certified 91%
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Trasforma un reale in stringa
 | |
| //
 | |
| // @rdesc Ritorna la stringa nella lunghezza richiesta
 | |
| const char *real::string (
 | |
|   int len,        // @parm Lunghezza della stringa (compreso decimali)
 | |
|   int dec,        // @parm Numero di decimali (default UNDEFINED)
 | |
|   char pad) const // @parm Carattere di riempimento (default ' ')
 | |
|   // @parm char * | picture | Formato della stringa
 | |
| 
 | |
|   // @syntax string (int len, int dec, char pad);
 | |
|   // @syntax string (const char *picture);
 | |
|   //
 | |
|   // @comm Nel primo caso ritorna una stringa lunga <p len> con <p dec> decimali e
 | |
|   //       inserisce nella stringa stessa il carattere <p pad> nel caso la
 | |
|   //       lunghezza richiesta sia maggiore di quella che risulterebbe per la
 | |
|   //       completa rappresentazione del reale.
 | |
|   //       <nl>Nel secondo caso ritorna la stringa con il formato stabilito in
 | |
|   //       <p picture>.
 | |
| 
 | |
| {
 | |
|   __tmp_real = *this;
 | |
|   if (dec != UNDEFINED)
 | |
|     __tmp_real.round (dec);
 | |
|   else
 | |
|     __tmp_real.trail();
 | |
| 
 | |
|   char * s = get_tmp_string().get_buffer(80);
 | |
| 	dtoa (s, __tmp_real.ptr ());
 | |
|   int lun = strlen (s);
 | |
| 
 | |
| 
 | |
|   if (lun < len)
 | |
|   {
 | |
|     const int delta = len - lun;
 | |
|     for (int i = lun; i >= 0; i--)
 | |
|       s[i + delta] = s[i];
 | |
|     for (i = 0; i < delta; i++)
 | |
|       s[i] = pad;
 | |
|   }
 | |
| 
 | |
|   return s;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func ostream& | operator <lt><lt> | Permette di reindirizzare il numero
 | |
| //                                      reale per la stampa
 | |
| //
 | |
| // @rdesc Ritorna l'utput sul quale e' stata reindirizzata la stampa
 | |
| ostream & operator << (
 | |
|   ostream & out,   // @parm Indica l'output sul quale stampare il numero
 | |
|   const real & a)  // @parm Numero da stampare
 | |
| 
 | |
| {
 | |
|   return out << a.string ();
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func istream& | operator <gt><gt> | Permette di leggere un numero reale
 | |
| //
 | |
| // @rdesc Ritorna l'output sul quale e' stato letto il numero
 | |
| istream & operator >> (
 | |
|   istream & in,  // @parm Input da cui leggere il numero
 | |
|   real & a)      // @parm Indirizzo in cui posizionare il numero
 | |
| 
 | |
| {
 | |
|   TString80 s;
 | |
|   in >> s;
 | |
|   atod (a.ptr (), s.get_buffer());
 | |
| 
 | |
|   a.trail();
 | |
|   return in;
 | |
| }
 | |
| 
 | |
| 
 | |
| int real::precision() const
 | |
| {
 | |
|   return dprec(ptr());
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc real& | real | round | Arrotonda al numero di decimali passati
 | |
| real & real ::round (
 | |
|   int prec)  // @parm Numero di decimali a cui arrotondare il numero (default 0)
 | |
| 
 | |
|   // @comm Nel caso <p prec> sia:    
 | |
|   //
 | |
|   // @flag <gt> 0 | Arrotonda al decimale
 | |
|   // @flag = 0 | Arrotonda all'intero
 | |
|   // @flag <lt> 0  | Arrotonda al valore passato (es. -3 arrotonda alle mille)
 | |
| {
 | |
|   if (abs(prec < 20))
 | |
|   {
 | |
|     if (prec < 0)
 | |
|     {
 | |
|       const double p = ::pow (10.0, -prec);
 | |
|       divdfd (ptr (), ptr (), p);
 | |
|       dround (ptr (), ptr (), 0);
 | |
|       muldfd (ptr (), ptr (), p);
 | |
|       trail();
 | |
|     }
 | |
|     else
 | |
|       dround (ptr (), ptr (), prec);
 | |
|   }
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real & real ::ceil (int prec)
 | |
| {
 | |
|   double p = 1.0;
 | |
|   if (prec != 0)
 | |
|   {
 | |
|     p = ::pow (10.0, -prec);
 | |
|     divdfd (ptr (), ptr (), p);
 | |
|   }
 | |
| 
 | |
|   DEC integer;
 | |
|   dint (&integer, ptr ());      // Extract the integer part
 | |
|   
 | |
|   if (disgt (ptr (), &integer))   // If positive ...
 | |
|     addid (ptr (), &integer, 1);  // ... add 1
 | |
|   else
 | |
|     dcpy(ptr(), &integer);        // If negative
 | |
| 
 | |
|   if (prec != 0)
 | |
|     muldfd (ptr (), ptr (), p);
 | |
|   
 | |
|   trail();
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real & real ::floor (int prec)
 | |
| {
 | |
|   double p = 1.0;
 | |
|   if (prec != 0)
 | |
|   {
 | |
|     p = ::pow (10.0, -prec);
 | |
|     divdfd (ptr (), ptr (), p);
 | |
|   }
 | |
| 
 | |
|   DEC integer;
 | |
|   dint (&integer, ptr ());      // Extract the integer part
 | |
| 
 | |
|   if (dislt (ptr (), &integer))   // If negative ...
 | |
|     addid (ptr (), &integer, -1);  // ... subtract 1
 | |
|   else
 | |
|     dcpy(ptr(), &integer);        // If positive
 | |
| 
 | |
|   if (prec != 0)
 | |
|     muldfd (ptr (), ptr (), p);
 | |
|   
 | |
|   trail();
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| real & real ::trunc (int prec)
 | |
| {
 | |
|   dtrunc (ptr (), ptr (), prec);
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func real | operator + | Somma due numeri reali
 | |
| //
 | |
| // @rdesc Ritorna il valore della somma
 | |
| real operator + (
 | |
|   const real & a,  // @parm Primo addendo da sommare
 | |
|   const real & b)  // @parm Secondo addendo da sommare
 | |
| 
 | |
|   // @syntax operator +(const real &a, const real &b);
 | |
|   // @syntax operator +(double a, const real &b);
 | |
|   // @syntax operator +(const real &a, double b);
 | |
| 
 | |
| {
 | |
|   dadd (__tmp_real.ptr (), a.ptr (), b.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| real operator + (double a, const real & b)
 | |
| 
 | |
| {
 | |
|   __tmp_real = a;
 | |
|   return __tmp_real += b;
 | |
| }
 | |
| 
 | |
| real operator + (const real & a, double b)
 | |
| 
 | |
| {
 | |
|   __tmp_real = a;
 | |
|   return __tmp_real += b;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func real | operator - | Sottrae due numeri reali
 | |
| //
 | |
| // @rdesc Ritorna il valore della sottrazione
 | |
| real operator - (
 | |
|   const real & a,  // @parm Primo addendo da sottrarre
 | |
|   const real & b)  // @parm Secondo addendo da sottrarre
 | |
| 
 | |
|   // @syntax operator -(const real &a, const real &b);
 | |
|   // @syntax operator -(double a, const real &b);
 | |
|   // @syntax operator -(const real &a, double b);
 | |
| {
 | |
|   dsub (__tmp_real.ptr (), a.ptr (), b.ptr ());
 | |
|   __tmp_real.trail();
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| real operator - (double a, const real & b)
 | |
| {
 | |
|   __tmp_real = a;
 | |
|   dsub (__tmp_real.ptr (), __tmp_real.ptr (), b.ptr ());
 | |
|   __tmp_real.trail( );
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| real operator - (const real & a, double b)
 | |
| {
 | |
|   __tmp_real = -b;
 | |
|   __tmp_real += a;    
 | |
|   __tmp_real.trail();
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func real | operator * | Moltiplica due numeri reali
 | |
| //
 | |
| // @rdesc Ritorna il valore della moltiplicazione
 | |
| real operator *(
 | |
|   const real & a,  // @parm Primo numero da moltiplicare
 | |
|   const real & b)  // @parm Secondo numero da moltiplicare
 | |
| 
 | |
|   // @syntax operator *(const real &a, const real &b);
 | |
|   // @syntax operator *(double a, const real &b);
 | |
|   // @syntax operator *(const real &a, double b);
 | |
| 
 | |
| {
 | |
|   dmul (__tmp_real.ptr (), a.ptr (), b.ptr ());
 | |
|   __tmp_real.trail( );
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| real operator *(double a, const real & b)
 | |
| {
 | |
|   __tmp_real = a;
 | |
|   dmul(__tmp_real.ptr (), __tmp_real.ptr (), b.ptr ());
 | |
|   __tmp_real.trail( );
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| real operator *(const real & a, double b)
 | |
| {
 | |
|   __tmp_real = b;
 | |
|   dmul (__tmp_real.ptr (), a.ptr (), __tmp_real.ptr ());
 | |
|   __tmp_real.trail( );
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func real | operator / | Divide due numeri reali
 | |
| //
 | |
| // @rdesc Ritorna il valore della divisione
 | |
| real operator / (
 | |
|   const real & a,  // @parm Primo numero da dividere
 | |
|   const real & b)  // @parm Secondo numero da dividere
 | |
| 
 | |
|   // @syntax operator /(const real &a, const real &b);
 | |
|   // @syntax operator /(double a, const real &b);
 | |
|   // @syntax operator /(const real &a, double b);
 | |
| {
 | |
|   ddiv (__tmp_real.ptr (), a.ptr (), b.ptr ());
 | |
|   __tmp_real.trail( );
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| real operator / (double a, const real & b)
 | |
| {
 | |
|   __tmp_real = a;
 | |
|   ddiv (__tmp_real.ptr (), __tmp_real.ptr (), b.ptr ());
 | |
|   __tmp_real.trail( );
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| real operator / (const real & a, double b)
 | |
| {
 | |
|   __tmp_real = b;
 | |
|   ddiv (__tmp_real.ptr (), a.ptr (), __tmp_real.ptr ());
 | |
|   __tmp_real.trail( );
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @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 real & a,  // @parm Primo numero da conforntare
 | |
|   const real & b)  // @parm Secondo numero da confrontare
 | |
| 
 | |
|   // @syntax operator <gt> (const real &a, const real &b);
 | |
|   // @syntax operator <gt> (double a, const real &b);
 | |
| {
 | |
|   return disgt (a.ptr (), b.ptr ()) != 0;
 | |
| }
 | |
| 
 | |
| bool operator > (double a, const real & b)
 | |
| {
 | |
|   // dftod(__tmp_real.ptr(), a);
 | |
|   // return disgt(__tmp_real.ptr(), b.ptr());
 | |
|   const double n = dtodf (b.ptr ());
 | |
|   return a > n;
 | |
| }
 | |
| 
 | |
| // @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 real & a,  // @parm Primo numero da conforntare
 | |
|   const real & b)  // @parm Secondo numero da confrontare
 | |
| 
 | |
|   // @syntax operator <lt> (const real &a, const real &b);
 | |
|   // @syntax operator <lt> (double a, const real &b);
 | |
| 
 | |
| {
 | |
|   return dislt (a.ptr (), b.ptr ()) != 0;
 | |
| }
 | |
| 
 | |
| bool operator < (double a, const real & b)
 | |
| 
 | |
| {
 | |
|   // dftod(__tmp_real.ptr(), a);
 | |
|   // return dislt(__tmp_real.ptr(), b.ptr());
 | |
|   const double n = dtodf (b.ptr ());
 | |
|   return a < n;
 | |
| }
 | |
| 
 | |
| // @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 real & a,  // @parm Primo numero da conforntare
 | |
|   const real & b)  // @parm Secondo numero da confrontare
 | |
| 
 | |
|   // @syntax operator <gt>= (const real &a, const real &b);
 | |
|   // @syntax operator <gt>= (double a, const real &b);
 | |
| 
 | |
| {
 | |
|   return disge (a.ptr (), b.ptr ()) != 0;
 | |
| }
 | |
| 
 | |
| bool operator >= (double a, const real & b)
 | |
| 
 | |
| {
 | |
|   // dftod(__tmp_real.ptr(), a);
 | |
|   // return disge(__tmp_real.ptr(), b.ptr());
 | |
|   const double n = dtodf (b.ptr ());
 | |
|   return a >= n;
 | |
| }
 | |
| 
 | |
| // @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 real & a,  // @parm Primo numero da conforntare
 | |
|   const real & b)  // @parm Secondo numero da confrontare
 | |
| 
 | |
|   // @syntax operator <lt>= (const real &a, const real &b);
 | |
|   // @syntax operator <lt>= (double a, const real &b);
 | |
| {
 | |
|   return disle (a.ptr (), b.ptr ()) != 0;
 | |
| }
 | |
| 
 | |
| bool operator <= (double a, const real & b)
 | |
| 
 | |
| {
 | |
|   // dftod(__tmp_real.ptr(), a);
 | |
|   // return disle(__tmp_real.ptr(), b.ptr());
 | |
|   const double n = dtodf (b.ptr ());
 | |
|   return a <= n;
 | |
| }
 | |
| 
 | |
| // @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 real & a,  // @parm Primo numero da conforntare
 | |
|   const real & b)  // @parm Secondo numero da confrontare
 | |
| 
 | |
|   // @syntax operator == (const real &a, const real &b);
 | |
|   // @syntax operator == (double a, const real &b);
 | |
| {
 | |
|   return diseq (a.ptr (), b.ptr ()) != 0;
 | |
| }
 | |
| 
 | |
| bool operator == (double a, const real & b)
 | |
| {
 | |
|   const double n = dtodf (b.ptr ());
 | |
|   return a == n;
 | |
| }
 | |
| 
 | |
| // @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 real & a,  // @parm Primo numero da conforntare
 | |
|   const real & b)  // @parm Secondo numero da confrontare
 | |
| 
 | |
|   // @syntax operator != (const real &a, const real &b);
 | |
|   // @syntax operator != (double a, const real &b);
 | |
| {
 | |
|   return !diseq (a.ptr (), b.ptr ());
 | |
| }
 | |
| 
 | |
| bool operator != (double a, const real & b)
 | |
| 
 | |
| {
 | |
|   const double n = dtodf (b.ptr ());
 | |
|   return a != n;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func real | operator % | Ritorna il modulo di due numeri
 | |
| //
 | |
| // @rdesc Ritorna il resto della divisione tra due numeri
 | |
| real operator % (
 | |
|   const real& a,    // @parm Primo membro della divisione
 | |
|   const real& b)    // @parm Secondo membro della divisione
 | |
|   
 | |
| // @syntax long double operator%(const real& a, const real& b)
 | |
| // @syntax real operator % (const real& a, const real& b)
 | |
| 
 | |
| {                                      
 | |
|   const long l = b.integer();
 | |
|   dmodl (__tmp_real.ptr (), a.ptr (), l);
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Scambia il numero reale <p a> con il numero real <p b>
 | |
| void swap (
 | |
|   real & a,  // @parm Primo numero da scambiare
 | |
|   real & b)  // @parm Secondo numero da scambiare
 | |
| 
 | |
| {
 | |
|   SwapDecimal (a.ptr (), b.ptr ());
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Ritorna il numero reale piu' piccolo tra <p a> e <p b>
 | |
| const real& fnc_min (
 | |
|   const real & a,  // @parm Primo numero da confrontare
 | |
|   const real & b)  // @parm Secondo numero da confrontare
 | |
|                    // @parm long double | a | Primo numero da confrontare
 | |
|                    // @parm long double | b | Secondo numero da confrontare
 | |
|   
 | |
| // @syntax const real& fnc_min (const real & a, const real & b)
 | |
| // @syntax inline long double fnc_min(long double a, long double b) 
 | |
|   
 | |
| 
 | |
| {
 | |
|   dmin (__tmp_real.ptr (), a.ptr (), b.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Ritorna il numero reale piu' grande tra <p a> e <p b>
 | |
| const real& fnc_max (
 | |
|   const real & a,  // @parm Primo numero da confrontare
 | |
|   const real & b)  // @parm Secondo numero da confrontare
 | |
|              // @parm long double | a | Primo numero da confrontare
 | |
|                    // @parm long double | b | Secondo numero da confrontare
 | |
| 
 | |
| // @syntax const real& fnc_max (const real & a, const real & b)
 | |
| // @syntax inline long double fnc_max(long double a, long double b) 
 | |
| 
 | |
| {
 | |
|   dmax (__tmp_real.ptr (), a.ptr (), b.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Ritorna la radice quadrata del numero
 | |
| real sqrt (
 | |
|   const real & a)  // @parm Numero del quale calcolare la radice
 | |
|              // @parm long double | a | Numero del quale calcolare la radice
 | |
|   
 | |
| // @syntax real sqrt (const real)
 | |
| // @syntax long double sqrt(long double)
 | |
| 
 | |
| {
 | |
|   dsqrt (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Ritorna il quadarato del numero
 | |
| real sqr (
 | |
|   const real & a)  // @parm Numero del quale calcolare il quadrato
 | |
|                    // @parm long double | a | Numero del quale calcolare il quadrato
 | |
|                    
 | |
| // @syntax real sqr (const real)
 | |
| // @syntax long double sqr(long double)
 | |
|                    
 | |
| {
 | |
|   dmul (__tmp_real.ptr (), a.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Calcola 10 a potenza <p a>
 | |
| real exp10 (
 | |
|      const real & a)  // @parm Esponente al quale elevare
 | |
|                       // @parm long double | a | Esponente al quale elevare
 | |
|                       
 | |
| // @syntax real exp10 (const real)
 | |
| // @syntax long double exp10 (long double)
 | |
|                       
 | |
|                       
 | |
| {
 | |
|   dalog (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Calcola l'elevamento a potenza <p b> del numero <p a>
 | |
| real pow (
 | |
|      const real & a, // @parm Numero da elevare a potenza
 | |
|      const real & b) // @parm Esponente
 | |
|              // @parm long double | a | Numero da elevare a potenza
 | |
|              // @parm long double | b | Esponente
 | |
| 
 | |
| // @syntax real pow (const real & a, const real & b)             
 | |
| // @syntax long double pow(long double a, long double b)
 | |
| 
 | |
| {
 | |
|   dpow (__tmp_real.ptr (), a.ptr (), b.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Calcola e (nepero) elevato ad <p a>
 | |
| real exp (
 | |
|      const real & a) // @parm Esponente
 | |
|              // @parm long double | a | Esponente
 | |
| 
 | |
| // @syntax real exp (const real & a)             
 | |
| // @syntax long double exp(long double a)
 | |
| 
 | |
| {
 | |
|   dexp (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Calcola il logaritmo in base 10 del numero
 | |
| real log10 (
 | |
|   const real & a)  // @parm Numero del quale calcolare il logaritmo
 | |
|              // @parm long double | a | Numero del quale calcolare il logaritmo
 | |
| 
 | |
| // @syntax real log10 (const real & a)             
 | |
| // @syntax long double log10(long double a)            
 | |
| 
 | |
| {
 | |
|   dlog (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Calcoa il logaritmo naturale (base e) del numero
 | |
| real log (
 | |
|   const real & a)  // @parm Numero del quale calcolare il logaritmo
 | |
|                    // @parm long double | a | Numero del quale calcolare il logaritmo
 | |
|                    
 | |
| // @syntax real log (const real & a)
 | |
| // @syntax long double log(long double a)
 | |
| 
 | |
| {
 | |
|   dln (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Calcola il seno dell'angolo
 | |
| real sin (
 | |
|   const real & a)  // @parm Angolo passato in radianti 
 | |
|              // @parm long double | a | Angolo passato in radianti 
 | |
|              
 | |
| // @syntax real sin (const real & a)
 | |
| // @syntax long double sin (long double a)
 | |
| 
 | |
| {
 | |
|   dsin (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Calcola il coseno dell'angolo
 | |
| real cos (
 | |
|   const real & a)  // @parm Angolo passato in radianti
 | |
|                    // @parm long double | a | Angolo passato in radianti 
 | |
|                    
 | |
| // @syntax real cos (const real & a)
 | |
| // @syntax long double cos (long double a)
 | |
|                    
 | |
| 
 | |
| {
 | |
|   dcos (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Calcola la tangente dell'angolo
 | |
| real tan (
 | |
|   const real & a)  // @parm Angolo passato in radianti 
 | |
|                    // @parm long double | a | Angolo passato in radianti 
 | |
|                    
 | |
| // @syntax real tan (const real & a)
 | |
| // @syntax long double tan (long double a)
 | |
|                    
 | |
| 
 | |
| {
 | |
|   dtan (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Ritorna il valore assoluto di un numero
 | |
| real abs (
 | |
|   const real & a)  // @parm Numero del quale si vuole conoscere il valore assoluto
 | |
|                    // @parm long double | a | Numero del quale si vuole conoscere il valore assoluto
 | |
|                    
 | |
| // @syntax real abs (const real & a)
 | |
| // @syntax long double abs(long double a)
 | |
| 
 | |
| {
 | |
|   dabs (__tmp_real.ptr (), a.ptr ());
 | |
|   return __tmp_real;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| // Funzioni comuni dei due real
 | |
| 
 | |
| TObject* real::dup () const
 | |
| {
 | |
|   return new real(*this);
 | |
| }
 | |
| 
 | |
| const char *real::eng2ita (char *s)
 | |
| {
 | |
|   if (s)
 | |
|   {
 | |
|     char *dot = strchr (s, '.');
 | |
|     if (dot)
 | |
|       *dot = ',';
 | |
|   }
 | |
|   return s;
 | |
| }
 | |
| 
 | |
| // Elimina gli spazi ed i punti, converte le virgole in punti
 | |
| const char *real::ita2eng (const char *s)
 | |
| {
 | |
|   TString& tmp = get_tmp_string();
 | |
| 	char* __string = tmp.get_buffer(strlen(s));
 | |
| 
 | |
|   int j = 0;
 | |
|   if (s)
 | |
|     for (int i = 0; s[i]; i++)
 | |
|     {
 | |
|       switch (s[i])
 | |
|       {
 | |
|       case ' ':
 | |
|       case '.':
 | |
|         break;
 | |
|       case ',':
 | |
|         __string[j++] = '.';
 | |
|         break;
 | |
|       default:
 | |
|         __string[j++] = s[i];
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|   __string[j] = '\0';
 | |
|   return __string;
 | |
| }           
 | |
| 
 | |
| bool real::is_null(const char *s)
 | |
| {  
 | |
|   bool z = TRUE;
 | |
|   if (s != NULL) for (const char* n = s; *n; n++)
 | |
|   {
 | |
|     if (strchr("123456789", *n) != NULL)
 | |
|     {
 | |
|       z = FALSE;
 | |
|       break;
 | |
|     }
 | |
|     if (strchr(" ,-.0", *n) == NULL)
 | |
|       break;
 | |
|   }
 | |
|   return z;
 | |
| }
 | |
| 
 | |
| bool real::is_natural (const char *s)
 | |
| {
 | |
|   bool ok = s && *s != '\0';
 | |
|   if (ok)
 | |
|   {
 | |
|     while (*s == ' ')
 | |
|       s++;                    // Remove leading spaces before
 | |
| 
 | |
|     if (*s)
 | |
|     {
 | |
|       while (isdigit(*s))
 | |
|         s++;
 | |
|       ok = *s == '\0';
 | |
|     }
 | |
|     else 
 | |
|       ok = FALSE;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| // Certified 75%
 | |
| const char* real::literals() const
 | |
| {
 | |
|   const char *primi20[] =
 | |
|   {"", "uno", "due", "tre", "quattro",
 | |
|    "cinque", "sei", "sette", "otto",
 | |
|    "nove", "dieci", "undici", "dodici",
 | |
|    "tredici", "quattordici", "quindici", "sedici",
 | |
|    "diciassette", "diciotto", "diciannove"};
 | |
|   const char *decine[] =
 | |
|   {"zero", "dieci", "venti", "trenta", "quaranta",
 | |
|    "cinquanta", "sessanta", "settanta", "ottanta",
 | |
|    "novanta", "cento"};
 | |
|   const char *uni[] =
 | |
|   {"uno", "mille", "unmilione", "unmiliardo"};
 | |
| 
 | |
|   const char *potenze[] =
 | |
|   {"", "mila", "milioni", "miliardi"};
 | |
| 
 | |
|   real tmp_real = *this;
 | |
|   tmp_real.trunc();
 | |
|   
 | |
|   TString r (tmp_real.string (0, 0));
 | |
|   const bool negativo = r[0] == '-';
 | |
|   if (negativo)
 | |
|     r.ltrim (1);
 | |
| 
 | |
|   TString& risultato = get_tmp_string(128);
 | |
|   risultato.cut (0);
 | |
| 
 | |
|   TString centinaia;
 | |
| 
 | |
|   for (int migliaia = 0;; migliaia++)
 | |
|   {
 | |
|     int v = r.len () - 3;
 | |
|     if (v < -2)
 | |
|       break;
 | |
| 
 | |
|     if (v < 0)
 | |
|       v = 0;
 | |
|     const int val = atoi (&r[v]);
 | |
|     r.cut (v);          // Elimina ultimi 3 caratteri
 | |
| 
 | |
|     v = val;
 | |
|     if (v >= 100)
 | |
|     {
 | |
|       const int c = v / 100;
 | |
|       if (c > 1)
 | |
|         centinaia = primi20[c];
 | |
|       else
 | |
|         centinaia.cut(0);
 | |
|       v -= c * 100;
 | |
|       centinaia << "cento";
 | |
|     } else centinaia.cut(0);
 | |
|     const int d = v / 10;
 | |
|     if (d > 1)
 | |
|     {
 | |
|       if (d == 8 && centinaia.right(1)[0] == 'o')
 | |
|         centinaia.rtrim(1);
 | |
|       centinaia << decine[d];
 | |
|       v -= d * 10;
 | |
|     }
 | |
| 
 | |
|     if (val > 0)
 | |
|     {
 | |
|       if (v != 1)
 | |
|       {         
 | |
|         if (v == 8) 
 | |
|           centinaia.rtrim(1);
 | |
|         centinaia << primi20[v] << potenze[migliaia];
 | |
|       }
 | |
|       else if (val > 1)
 | |
|       {
 | |
|         if (d > 1) 
 | |
|           centinaia.rtrim(1);
 | |
|         centinaia << "un" << (migliaia ? potenze[migliaia] : "o");
 | |
|       }
 | |
|       else
 | |
|         centinaia = uni[migliaia];
 | |
|     }
 | |
| 
 | |
|     risultato.insert(centinaia, 0);
 | |
|   }
 | |
|   
 | |
|   if (tmp_real != *this)  // Ci sono dei decimali!
 | |
|   {
 | |
|     TString80 res = risultato;
 | |
|     const real tmp_dec = abs(*this - tmp_real);
 | |
|     TString80 str = tmp_dec.string();
 | |
|     str.ltrim(2); str.cut(3);
 | |
|     res << '/' << str;
 | |
|     risultato = res;
 | |
|   }
 | |
| 
 | |
|   if (negativo)
 | |
|     risultato.insert ("meno", 0);
 | |
|   return risultato;
 | |
| }
 | |
| 
 | |
| // Certified 75%
 | |
| const char* real::points (int dec) const
 | |
| {
 | |
|   const char *str = stringa (0, dec);
 | |
|   const int neg = (*str == '-') ? 1 : 0;
 | |
|   TFixed_string n ((char *)str, 64);
 | |
|   int i;
 | |
| 
 | |
|   int dot = n.find (',');
 | |
|   if (dot < 0)
 | |
|     dot = n.len ();
 | |
| 
 | |
|   if (dec > 0)
 | |
|   {
 | |
|     if (n[dot] == '\0')
 | |
|       n << ',';
 | |
|     const int d = strlen (str + dot + 1);       // Decimals already there
 | |
| 
 | |
|     if (d <= dec)
 | |
|       for (i = d; i < dec; i++)
 | |
|         n << '0';
 | |
|     else
 | |
|       n.cut (dot + dec + 1);
 | |
|   }
 | |
| 
 | |
|   for (i = dot - 3; i > neg; i -= 3)
 | |
|     n.insert (".", i);
 | |
| 
 | |
|   return str;
 | |
| }
 | |
| 
 | |
| HIDDEN int get_picture_decimals (const TString& picture, char& decsep)
 | |
| {
 | |
|   int decimali = 0; 
 | |
|   int virgola = -1;
 | |
|   
 | |
|   if (decsep == ',')
 | |
|   {
 | |
|     int firstcomma = -1, lastcomma = -1, firstdot = -1, lastdot = -1;
 | |
|     for (int i = 0; picture[i]; i++)
 | |
|     {
 | |
|       if (picture[i] == ',')
 | |
|       { 
 | |
|         if (firstcomma < 0) firstcomma = i;
 | |
|         lastcomma = i;  
 | |
|       }
 | |
|       else if (picture[i] == '.')
 | |
|       { 
 | |
|         if (firstdot < 0) firstdot = i;
 | |
|         lastdot = i;  
 | |
|       }
 | |
|     }
 | |
|     if (lastcomma >= 0 && lastdot >= 0)
 | |
|     {
 | |
|       virgola = lastcomma >  lastdot ? lastcomma : lastdot;
 | |
|       decsep = picture[virgola];
 | |
|     }
 | |
|     else
 | |
|       if (lastcomma >= 0) virgola = lastcomma;
 | |
|   }
 | |
|   else virgola = picture.find('.');   
 | |
|   
 | |
|   if (virgola >= 0)
 | |
|   {
 | |
|     const int len = picture.len ();
 | |
|     for (int i = virgola + 1; i < len; i++)
 | |
|       if (strchr ("#@^", picture[i]))
 | |
|         decimali++;
 | |
|   }
 | |
|   return decimali;
 | |
| }           
 | |
| 
 | |
| const char* real::string(const char *picture) const
 | |
| {
 | |
|   if (*picture == '\0')
 | |
|     return string ();
 | |
|   if (*picture == '.')
 | |
|     return points (atoi (picture + 1));
 | |
|   if (stricmp (picture, "LETTERE") == 0)
 | |
|     return literals ();
 | |
| 
 | |
|   TString v (string());
 | |
|   TString& f = get_tmp_string();
 | |
| 	f = picture;                                       
 | |
|   
 | |
| 	char decsep =  ',';                            // Separatore dei decimali
 | |
|   if (f[f.len() - 1] == 'E')
 | |
|   { 
 | |
|     f.rtrim(1);
 | |
|     decsep = '.';
 | |
|   }
 | |
| 
 | |
|   // Calcola il numero di decimali voluti ed eventualmente 
 | |
|   // determina il vero separatore dei decimali
 | |
|   const int voluti = get_picture_decimals (f, decsep);
 | |
|   const char migsep = decsep == '.' ? ',' : '.'; // Separatore delle migliaia
 | |
|   
 | |
|   const int virgola = v.find ('.'); // v e' la nostra cifra, certamente in english format
 | |
|   int decimali = (virgola >= 0) ? v.len () - virgola - 1 : 0;
 | |
| 
 | |
|   for (; voluti > decimali; decimali++)
 | |
|     v << '@';
 | |
|   if (voluti < decimali)
 | |
|     v.cut (virgola + voluti + (voluti > 0));
 | |
| 
 | |
|   int j = v.len () - 1;
 | |
|   bool sign(FALSE);
 | |
|   for (int i = f.len () - 1; i >= 0 && j >= 0; i--)
 | |
|   {
 | |
|     char &z = f[i];
 | |
|     if (strchr ("#@^", z))
 | |
|     {
 | |
|       char c = v[j--];
 | |
|       if (j >= 0 && v[j] == '.')
 | |
|         j--;
 | |
|       if (z == '^')
 | |
|         c = ' ';
 | |
|       else
 | |
|       {
 | |
|         if (c == '@')
 | |
|           c = (z == '@') ? '0' : ' ';
 | |
|         else
 | |
|           if (c == '-')
 | |
|           {
 | |
|             if (z == '@') // Altrimenti -10 con picture @@@@@ diventa "00-10"
 | |
|             {
 | |
|               if (f[i+1] == migsep)  
 | |
|                 f[i+1] = '0';
 | |
|               sign=TRUE; // posticipa l'append del segno
 | |
|               i++;
 | |
|               c=z; 
 | |
|             } else {
 | |
|               if (f[i+1] == migsep )   // Altrimenti -100 diventa -.100
 | |
|               {
 | |
|                 f[i+1] = '-';
 | |
|                 c = ' ';   //OK
 | |
|               } 
 | |
|             } 
 | |
|           }
 | |
|       }
 | |
| 
 | |
|       z = c;
 | |
|     }   
 | |
|   }
 | |
|   for (int i2=0; i2 <= i; i2++)
 | |
|     if (f[i2] == '@')
 | |
|     {
 | |
|       if (sign)
 | |
|       {
 | |
|         f[i2] = '-'; // add sign in first pos
 | |
|         sign=FALSE;
 | |
|       }
 | |
|       else
 | |
|         f[i2] = '0';
 | |
|     }
 | |
|   for (; i >=0 ; i--)
 | |
|     switch (f[i])
 | |
|     {
 | |
|     case '#':
 | |
|     case '^':
 | |
|     case '.':
 | |
|     case ',':
 | |
|       f[i] = ' ';
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|     }
 | |
|   return f;
 | |
| }                 
 | |
| 
 | |
| // Certified 99%
 | |
| const char* real::stringa (int len, int dec, char pad) const
 | |
| {
 | |
|   char* str = (char*)string(len, dec, pad);
 | |
|   if (dec > 0 || dec == UNDEFINED)
 | |
|     eng2ita (str);
 | |
|   return str;
 | |
| }
 | |
| 
 | |
| void real::print_on(ostream& out) const
 | |
| {
 | |
|   out << string();
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Distrib
 | |
| // Oggetto per dividere un real in varie sue percentuali
 | |
| // in modo che la loro somma dia sempre il real di partenza
 | |
| // /////////////////////////////////////////////////////////
 | |
| 
 | |
| void TDistrib::add(real slice)
 | |
| {
 | |
|   if (slice > real (1.0))
 | |
|     slice /= 100.0;
 | |
|   CHECK (!_ready, "TDistrib: les jeux sont faits");
 | |
|   _slices.add (slice);
 | |
| }
 | |
| 
 | |
| real TDistrib::get ()
 | |
| {
 | |
|   _ready = TRUE;
 | |
|   CHECK (_current < _slices.items(), "TDistrib: too many gets");
 | |
|   real r = _tot * ((real &) _slices[_current++]);
 | |
|   r.round (_decs);
 | |
|   if (r > _tot - _prog)
 | |
|   {
 | |
|     r = _tot - _prog; _prog = _tot;
 | |
|   }
 | |
|   else
 | |
|     _prog += r;
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Inizializza l'oggetto
 | |
| void TDistrib::init (
 | |
|   const real & r,  // @parm Importo da dividere
 | |
|   bool zap)        // @parm Permette di cancellare le percenutali immesse (default FALSE)
 | |
|   
 | |
|   // @comm Se <p zap> e' vero cancella tutte le percentuali immesse, altrimenti
 | |
|   //       cambia solo il totale
 | |
| {
 | |
|   _current = 0; _prog = 0;
 | |
|   _tot = r; _ready = FALSE;
 | |
|   if (zap) _slices.destroy();
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Generic_distrib
 | |
| // Oggetto per dividere un real in parti prefissate 
 | |
| // in modo che la loro somma dia sempre il real di partenza
 | |
| // /////////////////////////////////////////////////////////
 | |
| 
 | |
| 
 | |
| void TGeneric_distrib::add(real slice)
 | |
| {
 | |
|   CHECK (!_ready, "TGeneric_distrib: les jeux sont faits");
 | |
|   _totslices += slice;
 | |
|   _slices.add (slice);
 | |
| }
 | |
| 
 | |
| real TGeneric_distrib::get ()
 | |
| {
 | |
|   _ready = TRUE;
 | |
|   CHECK (_current < _slices.items(), "TGeneric_distrib: too many gets");
 | |
|   real & currslice = (real &) _slices[_current++];
 | |
|   real r = currslice;
 | |
|   if (_tot != _totslices)
 | |
|   {
 | |
|     if (_tot < 1E9 && currslice < 1E9)
 | |
|       r = (_tot * currslice) / _totslices;
 | |
|     else
 | |
|       r *= (_tot / _totslices);
 | |
|   }
 | |
|   r.round (_decs);
 | |
|   _tot -= r;
 | |
|   _totslices -= currslice;
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Inizializza l'oggetto
 | |
| void TGeneric_distrib::init (
 | |
|   const real & r,  // @parm Importo da dividere
 | |
|   bool zap)        // @parm Permette di cancellare le percenutali immesse
 | |
|   //       (default FALSE)
 | |
| 
 | |
|   // @comm Se <p zap> e' vero cancella tutte le percentuali immesse, altrimenti
 | |
|   //       cambia solo il totale
 | |
| {
 | |
|   _current = 0; _totslices = 0;
 | |
|   _tot = r; _ready = FALSE;
 | |
|   if (zap) _slices.destroy();
 | |
|   else                                 
 | |
|   {
 | |
|     const int items = _slices.items();
 | |
|     for (int i = 0; i < items; i++)
 | |
|       _totslices += (real &) _slices[i];
 | |
|   }
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Importo
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| const TImporto& TImporto::add_to(TToken_string& s, int pos) const
 | |
| {
 | |
|   const bool dare = sezione() == 'D';
 | |
|   const char* v = valore().string();
 | |
|   s.add(dare ? v : "", pos);
 | |
|   s.add(dare ? "" : v, pos+1);
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| // Cerified 99%
 | |
| const TImporto& TImporto::operator =(TToken_string& sv)
 | |
| {
 | |
|   _valore = real(sv.get(0));
 | |
|   if (_valore.is_zero())
 | |
|   {
 | |
|     _valore = real(sv.get());
 | |
|     _sezione = 'A';
 | |
|   }
 | |
|   else
 | |
|     _sezione = 'D';
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| const TImporto& TImporto::set(char s, const real& v)
 | |
| {
 | |
|   if (s <= ' ' && v.is_zero())   // Accetta sezioni nulle per importi nulli
 | |
|     s = 'D';
 | |
|   CHECKD(s == 'D' || s == 'A', "Sezione errata per importo: codice ", (int)s);
 | |
|   _sezione = s; _valore = v;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| const TImporto& TImporto::operator += (const TImporto& i)
 | |
| {
 | |
|   if (_valore.is_zero())
 | |
|     _sezione = i._sezione;
 | |
| 
 | |
|   if (_sezione == i._sezione)
 | |
|     _valore += i._valore;
 | |
|   else
 | |
|     _valore -= i._valore;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| const TImporto& TImporto::operator -= (const TImporto& i)
 | |
| {
 | |
|   if (_valore.is_zero())
 | |
|     _sezione = i._sezione;
 | |
| 
 | |
|   if (_sezione == i._sezione)
 | |
|     _valore -= i._valore;
 | |
|   else
 | |
|     _valore += i._valore;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| const TImporto& TImporto::swap_section()
 | |
| {
 | |
|   _sezione = (_sezione == 'D') ? 'A' : 'D';
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Normalizza il segno o la sezione in base al parametro s
 | |
| const TImporto& TImporto::normalize(
 | |
|       char s) // @parm Tipo di normalizzazione da effettuare:
 | |
|             //
 | |
|             // @flag A | Forza la sezione Avere
 | |
|             // @flag D | Forza la sezione Dare
 | |
|         // @flag <gt>0 | Forza il segno negativo
 | |
|         // @flag <lt>=0 | Forza il segno positivo
 | |
| 
 | |
| {   
 | |
|   bool ex = FALSE;
 | |
|   switch (s)
 | |
|   {
 | |
|   case 'A':
 | |
|   case 'D':
 | |
|     ex = s != _sezione;
 | |
|     break;
 | |
|   default:
 | |
|     if (s < 0)
 | |
|       ex = _valore.sign() > 0;
 | |
|     else  
 | |
|       ex = _valore.sign() < 0;
 | |
|     break;
 | |
|   }  
 | |
|   if (ex)
 | |
|   {
 | |
|     _valore = -_valore;
 | |
|     swap_section();
 | |
|   }
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TImporto::compare(const TSortable& s) const
 | |
| {
 | |
|   const TImporto& i = (const TImporto&)s;
 | |
|   const real v = i.sezione() == sezione() ? i.valore() : -i.valore();
 | |
|   const real d = valore() - v;
 | |
|   const int res = d.sign();
 | |
|   return res;
 | |
| }
 | |
| 
 | |
| bool TImporto::is_zero() const
 | |
| { 
 | |
| #ifdef __LONGDOUBLE__
 | |
|   return fabsl(_valore) < 0.00001;
 | |
| #else
 | |
|   return _valore.is_zero(); 
 | |
| #endif  
 | |
| } |