#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