789 lines
13 KiB
C++
789 lines
13 KiB
C++
|
#include <ctype.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <gm.h>
|
||
|
|
||
|
extern "C" { double pow(double, double); } // Should be #include <math.h>
|
||
|
|
||
|
#include <strings.h>
|
||
|
#include <real.h>
|
||
|
|
||
|
HIDDEN real __tmp_real;
|
||
|
HIDDEN char __string[80];
|
||
|
const real ZERO(0.0);
|
||
|
|
||
|
real::real()
|
||
|
{ dzero(ptr()); }
|
||
|
|
||
|
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)
|
||
|
deltrz(ptr(), ptr()); // Delete Trailing zeroes
|
||
|
}
|
||
|
|
||
|
char* real::eng2ita(char* s)
|
||
|
{
|
||
|
if (s)
|
||
|
{
|
||
|
char* dot = strchr(s, '.');
|
||
|
if (dot) *dot = ',';
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
char* real::ita2eng(const char* 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_real(const char* s)
|
||
|
{
|
||
|
bool ok = FALSE;
|
||
|
if (s)
|
||
|
{
|
||
|
while(*s == ' ') s++; // Remove leading spaces before atod
|
||
|
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());
|
||
|
}
|
||
|
|
||
|
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());
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
real& real::operator +=(double a)
|
||
|
{
|
||
|
__tmp_real = *this;
|
||
|
adddfd(ptr(), __tmp_real.ptr(), a);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
real& real::operator -=(const real& b)
|
||
|
{
|
||
|
__tmp_real = *this;
|
||
|
dsub( ptr(), __tmp_real.ptr(), b.ptr());
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
real& real::operator *=(const real& b)
|
||
|
{
|
||
|
dmul( ptr(), ptr(), b.ptr());
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
real& real::operator /=(const real& b)
|
||
|
{
|
||
|
const DEC* dst = ddiv(ptr(), ptr(), b.ptr());
|
||
|
|
||
|
#ifdef DBG
|
||
|
if (dst == GM_NULL)
|
||
|
{
|
||
|
errname(__string, gmec());
|
||
|
error_box("Division error: %s", __string);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
TObject* real::dup() const
|
||
|
{ return new real(*this); }
|
||
|
|
||
|
bool real::is_zero() const
|
||
|
{
|
||
|
return diszero(ptr());
|
||
|
}
|
||
|
|
||
|
int real::sign() const
|
||
|
{ return dsign(ptr()); }
|
||
|
|
||
|
|
||
|
real real::operator -() const
|
||
|
{
|
||
|
real n;
|
||
|
dchgs(n.ptr(), ptr());
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
|
||
|
int real::integer() const
|
||
|
{ return dtoi(ptr()); }
|
||
|
|
||
|
|
||
|
// Certified 91%
|
||
|
char* real::string(int len, int dec, char pad) const
|
||
|
{
|
||
|
__tmp_real = *this;
|
||
|
if (dec != UNDEFINED) __tmp_real.round(dec);
|
||
|
else deltrz(__tmp_real.ptr(), __tmp_real.ptr());
|
||
|
|
||
|
// if (len == 0)
|
||
|
dtoa(__string, __tmp_real.ptr());
|
||
|
/*
|
||
|
else
|
||
|
{
|
||
|
char f[16];
|
||
|
if (dec == UNDEFINED) sprintf(f, "%%%dt", len);
|
||
|
else
|
||
|
sprintf(f, "%%%d.%dt", len, dec);
|
||
|
dsprintf(__string, f, __tmp_real.ptr());
|
||
|
}
|
||
|
|
||
|
if (dec <= 0 || dec == UNDEFINED) // Toglie una eventuale parte decimale .00
|
||
|
{
|
||
|
if (dot)
|
||
|
{
|
||
|
for (const char* z = dot + 1; *z; z++)
|
||
|
if (*z != '0') break;
|
||
|
if (!*z) *dot = '\0';
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
int lun = strlen(__string);
|
||
|
|
||
|
/*
|
||
|
char* dot = strchr(__string, '.');
|
||
|
|
||
|
int d = dot ? strlen(dot+1) : 0; // Decimals already there
|
||
|
|
||
|
if (d < dec)
|
||
|
{
|
||
|
if (dot == NULL) __string[lun++] = '.');
|
||
|
for (;d < dec; d++) __string[lun++] = '0';
|
||
|
__string[lun] = '\0';
|
||
|
} else
|
||
|
if (dec >= 0 && d > dec)
|
||
|
{
|
||
|
*(dot+dec+(dec>0)) = '\0';
|
||
|
lun = strlen(__string);
|
||
|
}
|
||
|
*/
|
||
|
if (lun < len)
|
||
|
{
|
||
|
const int delta = len - lun;
|
||
|
for (int i = lun; i >= 0; i--)
|
||
|
__string[i+delta] = __string[i];
|
||
|
for (i = 0; i < delta; i++) __string[i] = pad;
|
||
|
}
|
||
|
|
||
|
return __string;
|
||
|
}
|
||
|
|
||
|
// Certified 99%
|
||
|
char* real::stringa(int len, int dec, char pad) const
|
||
|
|
||
|
{
|
||
|
string(len, dec, pad);
|
||
|
if (dec > 0 || dec == UNDEFINED)
|
||
|
eng2ita(__string);
|
||
|
return __string;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Certified 75%
|
||
|
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" };
|
||
|
|
||
|
__tmp_real = *this;
|
||
|
__tmp_real.round(0);
|
||
|
TString r(__tmp_real.string(0, 0));
|
||
|
const bool negativo = r[0] == '-';
|
||
|
if (negativo) r.ltrim(1);
|
||
|
|
||
|
TFixed_string risultato(__string, 80);
|
||
|
risultato.cut(0);
|
||
|
|
||
|
TString centinaia(16);
|
||
|
|
||
|
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";
|
||
|
}
|
||
|
const int d = v/10;
|
||
|
if (d > 1)
|
||
|
{
|
||
|
centinaia << decine[d];
|
||
|
v -= d*10;
|
||
|
}
|
||
|
if (v != 1)
|
||
|
{
|
||
|
centinaia << primi20[v] << potenze[migliaia];
|
||
|
} else
|
||
|
if (val > 1)
|
||
|
{
|
||
|
if (d > 1) centinaia.cut(centinaia.len()-1);
|
||
|
centinaia << "un" << (migliaia ? potenze[migliaia] : "o");
|
||
|
} else centinaia = uni[migliaia];
|
||
|
|
||
|
risultato.insert(centinaia, 0);
|
||
|
}
|
||
|
|
||
|
if (negativo) risultato.insert("meno", 0);
|
||
|
return __string;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Certified 75%
|
||
|
char* real::points(int dec) const
|
||
|
{
|
||
|
const char* str = stringa();
|
||
|
const int neg = (*str == '-') ? 1 : 0;
|
||
|
TFixed_string n((char*)str, 24);
|
||
|
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 __string;
|
||
|
}
|
||
|
|
||
|
|
||
|
HIDDEN int get_picture_decimals(const TString& picture)
|
||
|
{
|
||
|
int decimali = 0;
|
||
|
const int 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
char* real::string(const char* picture) const
|
||
|
{
|
||
|
if (*picture == '\0') return string();
|
||
|
if (*picture == '.') return points(atoi(picture+1));
|
||
|
if (strcmp(picture, "LETTERE") == 0) return literals();
|
||
|
|
||
|
TString v(string());
|
||
|
TString f(picture);
|
||
|
|
||
|
const int voluti = get_picture_decimals(f);
|
||
|
const int virgola = v.find('.');
|
||
|
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;
|
||
|
for (int i = f.len()-1; i >= 0 && j >= 0; i--)
|
||
|
{
|
||
|
char& z = f[i];
|
||
|
if (strchr("#@~", z))
|
||
|
{
|
||
|
char c = v[j--];
|
||
|
if (v[j] == '.') j--;
|
||
|
if (z == '~') c = ' '; else
|
||
|
if (c == '@') c = (z == '@') ? '0' : ' ';
|
||
|
z = c;
|
||
|
}
|
||
|
}
|
||
|
for (; i >= 0; i--)
|
||
|
switch (f[i])
|
||
|
{
|
||
|
case '#':
|
||
|
case '~':
|
||
|
case '.': f[i] = ' '; break;
|
||
|
case '@': f[i] = '0'; break;
|
||
|
default :break;
|
||
|
}
|
||
|
return strcpy(__string, f);
|
||
|
}
|
||
|
|
||
|
|
||
|
ostream& operator <<(ostream& out, const real& a)
|
||
|
|
||
|
{
|
||
|
return out << a.string();
|
||
|
}
|
||
|
|
||
|
|
||
|
istream& operator >>(istream& in, real& a)
|
||
|
|
||
|
{
|
||
|
in >> __string;
|
||
|
atod(a.ptr(), __string);
|
||
|
return in;
|
||
|
}
|
||
|
|
||
|
|
||
|
int real::precision()
|
||
|
{
|
||
|
return dprec(ptr());
|
||
|
}
|
||
|
|
||
|
|
||
|
real& real::round(int prec)
|
||
|
{
|
||
|
if (prec < 0)
|
||
|
{
|
||
|
const double p = ::pow(10.0, -prec);
|
||
|
divdfd(ptr(), ptr(), p);
|
||
|
dround(ptr(), ptr(), 0);
|
||
|
muldfd(ptr(), ptr(), p);
|
||
|
}
|
||
|
else
|
||
|
dround(ptr(), ptr(), prec);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
real& real::ceil(int prec)
|
||
|
{
|
||
|
double p = 1.0;
|
||
|
if (prec)
|
||
|
{
|
||
|
p = ::pow(10.0, -prec);
|
||
|
divdfd(ptr(), ptr(), p);
|
||
|
}
|
||
|
|
||
|
DEC integer; dint(&integer, ptr()); // Extract the integer part
|
||
|
if (disgt(ptr(), &integer)) // If different ...
|
||
|
addid(ptr(), &integer, 1); // add 1
|
||
|
|
||
|
if (prec)
|
||
|
muldfd(ptr(), ptr(), p);
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
real& real::trunc(int prec)
|
||
|
{
|
||
|
dtrunc(ptr(), ptr(), prec);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator +(const real& a, const real& 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator -(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
dsub(__tmp_real.ptr(), a.ptr(), b.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator -(double a, const real& b)
|
||
|
|
||
|
{
|
||
|
__tmp_real = a;
|
||
|
dsub(__tmp_real.ptr(), __tmp_real.ptr(), b.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator -(const real& a, double b)
|
||
|
|
||
|
{
|
||
|
__tmp_real = b;
|
||
|
return __tmp_real -= a;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator *(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
dmul(__tmp_real.ptr(), a.ptr(), b.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator *(double a, const real& b)
|
||
|
|
||
|
{
|
||
|
muldfd(__tmp_real.ptr(), b.ptr(), a);
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator *(const real& a, double b)
|
||
|
|
||
|
{
|
||
|
muldfd(__tmp_real.ptr(), a.ptr(), b);
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator /(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
ddiv(__tmp_real.ptr(), a.ptr(), b.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator /(double a, const real& b)
|
||
|
|
||
|
{
|
||
|
__tmp_real = a;
|
||
|
ddiv(__tmp_real.ptr(), __tmp_real.ptr(), b.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator /(const real& a, double b)
|
||
|
|
||
|
{
|
||
|
__tmp_real = b;
|
||
|
ddiv(__tmp_real.ptr(), a.ptr(), __tmp_real.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool operator >(const real& a, const real& b)
|
||
|
{
|
||
|
return disgt(a.ptr(), b.ptr());
|
||
|
}
|
||
|
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool operator <(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
return dislt(a.ptr(), b.ptr());
|
||
|
}
|
||
|
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool operator >=(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
return disge(a.ptr(), b.ptr());
|
||
|
}
|
||
|
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool operator <=(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
return disle(a.ptr(), b.ptr());
|
||
|
}
|
||
|
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool operator ==(const real& 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool operator !=(const real& 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
real operator %(const real& a, const long b)
|
||
|
|
||
|
{
|
||
|
dmodl(__tmp_real.ptr(), a.ptr(), b);
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
void swap(real& a, real& b)
|
||
|
|
||
|
{
|
||
|
SwapDecimal(a.ptr(), b.ptr());
|
||
|
}
|
||
|
|
||
|
|
||
|
real fnc_min(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
dmin(__tmp_real.ptr(), a.ptr(), b.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real fnc_max(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
dmax(__tmp_real.ptr(), a.ptr(), b.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real sqrt(const real& a)
|
||
|
|
||
|
{
|
||
|
dsqrt(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real sqr(const real& a)
|
||
|
|
||
|
{
|
||
|
dmul(__tmp_real.ptr(), a.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real exp10(const real& a)
|
||
|
|
||
|
{
|
||
|
dalog(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real pow(const real& a, const real& b)
|
||
|
|
||
|
{
|
||
|
dpow(__tmp_real.ptr(), a.ptr(), b.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real exp(const real& a)
|
||
|
|
||
|
{
|
||
|
dexp(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
real log10(const real& a)
|
||
|
|
||
|
{
|
||
|
dlog(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real log(const real& a)
|
||
|
|
||
|
{
|
||
|
dln(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real sin(const real& a)
|
||
|
|
||
|
{
|
||
|
dsin(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real cos(const real& a)
|
||
|
|
||
|
{
|
||
|
dcos(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real tan(const real& a)
|
||
|
|
||
|
{
|
||
|
dtan(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
real abs(const real& a)
|
||
|
|
||
|
{
|
||
|
dabs(__tmp_real.ptr(), a.ptr());
|
||
|
return __tmp_real;
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// 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;
|
||
|
}
|
||
|
|
||
|
void TDistrib::init(const real& r)
|
||
|
{
|
||
|
_current = 0; _prog = 0;
|
||
|
_tot = r; _ready = FALSE;
|
||
|
}
|
||
|
|
||
|
|