Programowanie > C/C++

jak w C++ robić operacje na pieniądzach

<< < (2/2)

Paweł Kraszewski:
money.h

--- Kod: ---
#ifndef MONEY_H
#define MONEY_H

#include <inttypes.h>
#include <iomanip>
#include <iostream>

template <typename T>
class Money {
 private:
  T amount;

 public:

  // Konstruktory
  Money() : amount( 0 ) {}
  Money( const Money<T>& m ) : amount( m.amount ) {}

  // Explicit daje to, że nie robią się automatyczne konwersje typów
  explicit Money( T am ) : amount( am ) {}
  explicit Money( double d ) : amount( d * 100 ) {}

  // Operator przypisanie

  Money<T>& operator=( const Money<T>& m ) { amount = m.amount; }
  Money<T>& operator=( T am ) { amount = am; }

  // Dodawać i odejmować mozemy tylko 2 obiekty Money

  inline friend Money<T> operator+( const Money<T>& m1, const Money<T>& m2 ) {
    return Money<T>( m1.amount + m2.amount );
  }
  inline friend Money<T> operator-( const Money<T>& m1, const Money<T>& m2 ) {
    return Money<T>( m1.amount - m2.amount );
  }

  // W mnożeniu i dzieleniu drugi argument NIE JEST typu Money.
  // Dzięki temu Money64(5.0)*5 działa jak oczekiwano, dając 25zł

  inline friend Money<T> operator*( const Money<T>& m1, double v ) {
    return Money<T>( T( m1.amount * v ) );
  }

  inline friend Money<T> operator/( const Money<T>& m1, double v ) {
    return Money<T>( T( m1.amount / v ) );
  }

  // Argumenty w odwrotnej kolejności, dzielenie nie ma sensu.

  inline friend Money<T> operator*( double v, const Money<T>& m1 ) {
    return Money<T>( T( m1.amount * v ) );
  }

  // Wyświetlenie sformatowanej wartości

  inline friend std::ostream& operator<<( std::ostream& o, const Money<T>& m ) {
    return ( o << ( m.amount / 100 ) << '.' << std::setfill( '0' )
               << std::setw( 2 ) << ( m.amount % 100 ) )<<" PLN";
  }

  // Zaokrąglenie w górę

  inline Money<T> RoundUp( Money<T> to ) const {
    T r = to.amount * T( ( amount + to.amount - 1 ) / to.amount );
    return Money<T>( r );
  }

  // Explicit wyłącza automatyczne rzutowanie.
  // Nie działa
  //  Money64 M(5.0);
  //  double d = M;
  // Trzeba zrobić
  //  double d = static_cast<double>(M);
  //
  // Upierdliwe, ale pozwala uniknąć błędów gdy coś się automatycznie ale
  // nieplanowo zrzutuje w tle.
  explicit operator double() const { return double( amount ) / 100.0; }
  explicit operator T() const { return amount / 100; }
};

// Rozmiar 64bity
typedef Money<int64_t> Money64;

// Rozmiar 32bity
typedef Money<int32_t> Money32;

#endif  // MONEY_H

--- Koniec kodu ---

main.cpp

--- Kod: ---
#include "money.h"
#include <iostream>

using std::cout;
using std::endl;

int main( int argc, char *argv[] ) {
  Money64 m1( 3.50 );
  Money64 m2( 13.0 );
  Money64 m3 = m1 + m2;

  cout << "M1=" << m1 << endl;
  cout << "M2=" << m2 << endl;
  cout << "M1+M2=" << m3 << endl;

  cout << m3 << " zaokrąglone w górę do 1zł=" << m3.RoundUp( Money64( 1.0 ) )
       << " reszta " << m3.RoundUp( Money64( 1.0 ) ) - m3 << endl;
  cout << m3 << " zaokrąglone w górę do 5zł=" << m3.RoundUp( Money64( 5.0 ) )
       << " reszta " << m3.RoundUp( Money64( 5.0 ) ) - m3 << endl;
  cout << m3 << "  zaokrąglone w górę do 50zł=" << m3.RoundUp( Money64( 50.0 ) )
       << " reszta " << m3.RoundUp( Money64( 50.0 ) ) - m3 << endl;

  cout << m3 << " * 3 = " << m3 * 3 << endl;
  cout << "3 * " << m3 << " = " << 3 * m3 << endl;

  cout << m3 << " / 3 = " << m3 / 3 << endl;

  return 0;
}

--- Koniec kodu ---

Wynik

--- Kod: ---
M1=3.50 PLN
M2=13.00 PLN
M1+M2=16.50 PLN
16.50 PLN zaokrąglone w górę do 1zł=17.00 PLN reszta 0.50 PLN
16.50 PLN zaokrąglone w górę do 5zł=20.00 PLN reszta 3.50 PLN
16.50 PLN  zaokrąglone w górę do 50zł=50.00 PLN reszta 33.50 PLN
16.50 PLN * 3 = 49.50 PLN
3 * 16.50 PLN = 49.50 PLN
16.50 PLN / 3 = 5.50 PLN

--- Koniec kodu ---

KelThuzad:
Powiem tak nie bardzo to rozumiem :D

Mateusz Leśmian:
też się chyba jeszcze muszę podszkolić
__________________________
http://trans-ziem.pl/

Nawigacja

[0] Indeks wiadomości

[*] Poprzednia strona

Idź do wersji pełnej