Newsgroup: it.comp.lang.c++
Titolo: Mi sa tanto che butto il compilatore

E' da tempo che sto combattendo con questa porzione di codice: non so pių se
buttare il mio compilatore o cambiare mestiere :-) (spero per la prima
possibilita').
Mi farestre il piacere di provare a compilare il tutto e dirmi come č
andata?
<CODE>
#include <math.h>
class CFixedPointNumber
{
friend CMath;
public:
   inline CFixedPointNumber() {};
   inline CFixedPointNumber(long _lNum) : lFPNumber(_lNum << 8) {};
   inline CFixedPointNumber(float _fNum) : lFPNumber((long)(_fNum *
(float)256.0)) {};
   inline void Set(long _lNum) { lFPNumber = _lNum << 8; };
   inline void Set(float _fNum) { lFPNumber = (long)(_fNum *
(float)256.0); };
   inline long GetLong() { return (lFPNumber >> 8); };
   inline float GetFloat() { return (float)(lFPNumber / (float)256.0); };
   inline CFixedPointNumber operator+(CFixedPointNumber _FPNumber)
CFixedPointNumber FPTemp; FPTemp.SetDirect((long)(lFPNumber +
_FPNumber.lFPNumber)); return FPTemp; };
   inline CFixedPointNumber operator-(CFixedPointNumber _FPNumber)
CFixedPointNumber FPTemp; FPTemp.SetDirect((long)(lFPNumber -
_FPNumber.lFPNumber)); return FPTemp; };
   inline CFixedPointNumber operator*(CFixedPointNumber _FPNumber)
CFixedPointNumber FPTemp; FPTemp.SetDirect((long)(lFPNumber *
_FPNumber.lFPNumber) >> 8); return FPTemp; };
   inline CFixedPointNumber operator/(CFixedPointNumber _FPNumber)
CFixedPointNumber FPTemp; FPTemp.SetDirect((long)(lFPNumber /
_FPNumber.lFPNumber) << 8); return FPTemp; };
   inline void operator+=(CFixedPointNumber _FPNumber) { lFPNumber +=
_FPNumber.lFPNumber; };
   inline void operator-=(CFixedPointNumber _FPNumber) { lFPNumber -=
_FPNumber.lFPNumber; };
   inline void operator*=(CFixedPointNumber _FPNumber) { lFPNumber =
(lFPNumber * _FPNumber.lFPNumber) >> 8; };
   inline void operator/=(CFixedPointNumber _FPNumber) { lFPNumber =
(lFPNumber / _FPNumber.lFPNumber) << 8; };
   inline CFixedPointNumber operator=(CFixedPointNumber _FPNumber)
lFPNumber = _FPNumber.lFPNumber;  return _FPNumber; };
   inline CFixedPointNumber operator=(float _fNumber) { lFPNumber =
(long)(_fNumber * (float)256.0);  return *this; };
   inline CFixedPointNumber operator=(long _lNumber) { lFPNumber =
(long)(_lNumber << 8);  return *this; };
protected:
   inline void SetDirect(long _lNum) { lFPNumber = _lNum; };
   inline long GetDirect() { return lFPNumber; };
   long lFPNumber;
};
class CMath
{
public:
   static void Initialize();
   inline static CFixedPointNumber Sin(CFixedPointNumber _FPNum) { return
SIN[_FPNum.GetDirect() >> 5]; };
   inline static CFixedPointNumber Cos(CFixedPointNumber _FPNum) { return
COS[_FPNum.GetDirect() >> 5]; };
   inline static CFixedPointNumber ASin(CFixedPointNumber _FPNum) { return
ASIN[(char)_FPNum.GetDirect()]; };
   inline static CFixedPointNumber ACos(CFixedPointNumber _FPNum) { return
ACOS[(char)_FPNum.GetDirect()]; };
protected:
   static CFixedPointNumber SIN[2880], COS[2880], ASIN[256], ACOS[256];
};
void CMath::Initialize()
{
  int iIndex;
  float fIndex, fDelta;
  fDelta = (3.1415 * 2.0) / 2880.0;
  fIndex=0;
  for(iIndex=0; iIndex<2880; iIndex++)
  {
    SIN[iIndex] = (float)sin(fIndex);
    COS[iIndex] = (float)cos(fIndex);
    fIndex+=fDelta;
  };
};
void main()
{
  CFixedPointNumber Angle((float)30);
  CMath::Initialize();
  CFixedPointNumber b = CMath::Sin(Angle);
  float a = b.GetFloat();
};
</CODE>
Ciao e grazie a chi si interesserā, Giuseppe
---------------------------------------------------------------------------
_Guybrush su IRCNet canale #programmazione
---------------------------------------------------------------------------

 };
}
EMG

int main()
Si, l'ho scritto di fretta senza badare allo standard.
Il mio problema e che durante l'esecuzione di CMath::Initialize() sembra
come se le zone di memoria di SIN e COS si sovrappongano alle variabili
locali iIndex, fIndex e fDelta. Infatti, arrivati ad un certo valore di
iIndex (prima 939, da un po' 400 e qualcosa), le variabili fDelta e iIndex
divengono uguali a zero creando un ciclo infinito. Inoltre la maggior parte
delle volte il programma si blocca generando degli errori. Se invece non
dichiaro static nè SIN, COS, ASIN e ACOS nè Initialize tutto fila per il
verso giusto.
Volevo sapere se lo stesso tipo di errori capita anche a voi con i vostri
compilatori (io uso il Borland Turbo C++ 1.01).
Ciao e grazie a chi si interesserà, Giuseppe


 compilatori (io uso il Borland Turbo C++ 1.01).
Con il mio DJGPP non riesco neanche a compilare a causa di quell'errore
che ti ho detto.
EMG

   fDelta = (3.1415 * 2.0) / 2880.0;
Per pi conviene usare M_PI che e' definito con maggior
precisione.
Sommando ogni volta fDelta si sommano anche gli errori di
arrotondamento.
	Mauro

 capirne il motivo. Forse perché sono static.
SIN e COS devono anche essere definiti da qualche parte (di solito
nel file di implementazione della classe), la dichiarazione
all'interno della classe non vale come definizione.
Quindi bisogna aggiungere, fuori dalla classe:
  CFixedPointNumber CMath::SIN[2880];
  CFixedPointNumber CMath::COS[2880];
	Mauro


Ma certo! Che idiota che sono... :-(
EMG

che ti ho detto.
Da una mail che mi è arrivata in risposta a questo argomento ho capito che
bisogna ridichiarare le variabili static all'esterno della classe, oltre che
all'interno. Fuori della classe bisogna quindi scrivere:
CFixedPointNumber CMath::COS[2880];
CFixedPointNumber CMath::SIN[2880];
Ciao e grazie dell'interessamento, Giuseppe


arrotondamento.
Grazie per avermelo fatto notare ma ti ricordo che queste classi sono ancora
in una fase di "bozza".
Ciao e graie per l'interessamento, Giuseppe


 Scusami, non conoscevo l'esistenza di una classe standard di nome cmath.
No, non è una classe ma un semplice header file.
EMG

 a += b += 3;
Istruzioni cosi' non si vedono, pero' capita abbastanza spesso di
utilizzare il risultato di +=.  Peresempio un modo molto comune
di definire l'operatore + di una classe e':
Pippo operator + ( Pippo& lhs, Pippo& rhs )
{
  Pippo p = lhs;
  return p += rhs;
}
Se poi si vuole utilizzare la propria classe con algoritmi (magari
template, magari scritti da altri) pensati per i tipi standard, 
conviene avere operatori con la stessa sintassi di quelli standard.
	Mauro

Ciao e grazie a chi si interesserà, Giuseppe


Tanks, queste informazioni mi sono utili. Anche se, ad essere sincero, il
mio compilatore non cambia comportamento anche di fronte alle modifiche.
Ciao, Giuseppe
PS. Scusate per il post "GRAZIE!!, sono riuscito", non era mia intenzione
quotare tutto il mio precedente messaggio.
