Classe montant



#include <stdlib.h>

#include <ctype.h>

#include <iomanip.h>

#include <values.h>

#include <string.h>

#include <strstrea.h>

#include "montant.h"



void TMontant::corrige_valeur ()

{

  // Corrige les problemes de signes

  if (Francs > 0) {

    if (Centimes < 0) {

      Centimes += 100;

      Francs --;

      corrige_valeur ();

    }

  }

  else if (Francs < 0) {

    if (Centimes > 0) {

      Centimes -= 100;

      Francs ++;

      corrige_valeur ();

    }

  }

  // Corrige les problemes de retenu

  if (Centimes >= 100) {

    Francs ++;

    Centimes -= 100;

    corrige_valeur ();

  }

  else if (Centimes <= -100) {

    Francs --;

    Centimes += 100;

    corrige_valeur ();

  }

}



TMontant::TMontant (long francs, int centimes)

{

  Francs = francs;

  Centimes = centimes;

  Valid = 1;

  corrige_valeur ();

}



/*TMontant::TMontant (double d)

{

  Francs = d;

  Centimes = (int) (d*100) % 100;

  Valid = (d <= MAXLONG) && (d >= -MAXLONG);

} */



TMontant::TMontant (char* montant, int Long_Champ)

{

int i=0;

int signe=+1;

int decimal=0;



  Centimes = 0;

  Francs = 0;

  while ((i < Long_Champ) && (montant[i] == ' ')) i++; // saute les espaces de fin

  if ((i < Long_Champ) && (montant[i] == '-')) {

    signe = -1;

    i++;

  }

  else {

    if ((i < Long_Champ) && (montant[i] == '+')) {

      i++;

    }

  }

  while ((i < Long_Champ) && (isdigit(montant[i]))) {

    Francs = Francs * 10 + montant[i++] - '0';

  }

  if ((i < Long_Champ) && (montant[i] == '.')) {

    // on passe aux decimales

    i++;

    while ((i < Long_Champ) && (isdigit(montant[i])) && (decimal < 2)) {

      Centimes = Centimes * 10 + montant[i++] - '0';

      decimal++;

    }

  }

  // 2 decimales obligatoirement

  while (decimal++ < 2) {

    Centimes = Centimes * 10;

  }

  if ((montant[i] == 0) // fin

    || (isdigit(montant[i])) // ou decimal en trop

    || (montant[i] == ' ')) { // fin normale

    Centimes *= signe;

    Francs *= signe;

    Valid = 1;

  }

  else {

    Valid = 0;

    cerr << "Erreur init Montant a partir de chaine\n";

  }

}



TMontant TMontant::operator + (const TMontant &M2)

{

TMontant M;



  M.Centimes = Centimes + M2.Centimes;

  M.Francs = Francs + M2.Francs;

  M.corrige_valeur ();

  return M;

}



TMontant TMontant::operator - (const TMontant &M2)

{

TMontant M;



  M.Centimes = Centimes - M2.Centimes;

  M.Francs = Francs - M2.Francs;

  M.corrige_valeur ();

  return M;

}



TMontant TMontant::operator - ()

{

TMontant M;



  M.Centimes = -Centimes;

  M.Francs = -Francs;

  return M;

}



TMontant& TMontant::operator += (const TMontant &M2)

{

  *this = *this + M2;

  return *this;

}



TMontant& TMontant::operator -= (const TMontant &M2)

{

  *this = *this - M2;

  return *this;

}







TMontant& TMontant::operator *= (const TMontant &M )

{

long produit_centimes;



  Francs *= M.Francs;

  produit_centimes = M.Centimes*Francs+M.Francs*Centimes+(

              M.Centimes*Centimes)/100;

  Francs += produit_centimes / 100;

  Centimes = (int) (produit_centimes % 100);



  return *this;

}



int TMontant::operator <  ( const TMontant & M ) const

{

  return ((Francs < M.Francs)

      || ((Francs == M.Francs) && (Centimes < M.Centimes)));

}



int TMontant::operator >  ( const TMontant & M ) const

{

  return ((Francs > M.Francs)

      || ((Francs == M.Francs) && (Centimes > M.Centimes)));

}



int TMontant::operator <=  ( const TMontant & M ) const

{

  return ((Francs < M.Francs)

      || ((Francs == M.Francs) && (Centimes <= M.Centimes)));

}



int TMontant::operator >=  ( const TMontant & M ) const

{

  return ((Francs > M.Francs)

      || ((Francs == M.Francs) && (Centimes >= M.Centimes)));

}



int TMontant::operator ==  ( const TMontant & M ) const

{

  return ((Francs == M.Francs) && (Centimes == M.Centimes));

}



TMontant abs (TMontant & M)

{

  return TMontant(labs(M.Francs), abs(M.Centimes));

}



ostream & operator << (ostream &out, TMontant &M)

{

  int largeur=out.width();

  char Chaine[LONG_MAX_MONTANT+1];

  ostrstream out_ch(Chaine, LONG_MAX_MONTANT+1);



  if ((M.Francs == 0) && (M.Centimes < 0)) { // cas particulier sinon perte signe

    out_ch << "-0." << setw (2) << setfill ('0') << abs (M.Centimes) << ends;

  }

  else {

    out_ch << M.Francs << '.' << setw (2) << setfill ('0') << abs (M.Centimes) << ends;

  }

  if (strlen(Chaine) > largeur) {

    Chaine[largeur] = 0;

  }

  out << Chaine;

  return out;

}



#ifdef pasbon

istream & operator >> (istream &in, TMontant &M)

{

char c;

  in >> M.Francs >> c >> setw (2) >> setfill ('0') >> M.Centimes;

  if (c != '.') {

    cerr << "Erreur lecture Montant\n";

  }

  if (M.Francs < 0) {

    M.Centimes = -M.Centimes;

  }

  return in;

}

#endif