tags:

views:

438

answers:

3

I'm trying to learn to use namespaces declarations more definitive than not just say "using namespace std". I'm trying to format my data to 2 decimal places, and set the format to be fixed and not scientific. This is my main file:

#include <iostream>
#include <iomanip>

#include "SavingsAccount.h"
using std::cout;
using std::setprecision;
using std::ios_base;

int main()
{
    SavingsAccount *saver1 = new SavingsAccount(2000.00);
    SavingsAccount *saver2 = new SavingsAccount(3000.00);

    SavingsAccount::modifyInterestRate(.03);

    saver1->calculateMonthlyInterest();
    saver2->calculateMonthlyInterest();

    cout << ios_base::fixed << "saver1\n" << "monthlyInterestRate: " << saver1->getMonthlyInterest()
        << '\n' << "savingsBalance: " << saver1->getSavingsBalance() << '\n';
    cout << "saver2\n" << "monthlyInterestRate: " << saver2->getMonthlyInterest()
        << '\n' << "savingsBalance: " << saver2->getSavingsBalance() << '\n';
}

On Visual Studio 2008, when I run my program, I get an output of "8192" before the data I want. Is there a reason for that?

Also, I don't think I am setting the fixed part or 2 decimal places correctly since I seem to get scientific notation once I added the setprecision(2). Thanks.

+2  A: 
cout << setiosflags(ios::fixed) << setprecision(2) << 1/3.;

ios_base::fixed is not manipulator it is a value (1 << 13) for the ios flag.

J.F. Sebastian
+2  A: 

You want std::fixed (the other one just inserts its value into the stream, which is why you see 8192), and I don't see a call to setprecision in your code anywhere.
This'll fix it:

#include <iostream>
#include <iomanip>

using std::cout;
using std::setprecision;
using std::fixed;

int main()
{
    cout << fixed << setprecision(2)
         << "saver1\n" 
         << "monthlyInterestRate: " << 5.5 << '\n' 
         << "savingsBalance: " << 10928.8383 << '\n';
    cout << "saver2\n" 
         << "monthlyInterestRate: " << 4.7 << '\n' 
         << "savingsBalance: " << 22.44232 << '\n';
}
tzaman
+2  A: 

It might not be the answer you're looking for, but floating-point numbers are not suited to financial calculations because fractions like 1/100 cannot be represented exactly. You might be better off doing the formatting yourself. This can be encapsulated:

class money {
    int cents;
public:
    money( int in_cents ) : cents( in_cents ) {}

    friend ostream &operator<< ( ostream &os, money const &rhs )
        { return os << '$' << m.cents / 100 << '.' << m.cents % 100; }
};

cout << money( 123 ) << endl; // prints $1.23

Better(?) yet, C++ has a facility called the monetary locale category which includes a money formatter which takes cents as an argument.

locale::global( locale("") );
use_facet< money_put<char> >( locale() ).put( cout, false, cout, ' ', 123 );

This should Do the Right thing internationally, printing the user's local currency and hiding the number of decimal places from your implementation. It even accepts fractions of a cent. Unfortunately, this does not seem to work on my system (Mac OS X), which has generally poor locale support. (Linux and Windows should fare better.)

Potatoswatter
`money_put` variant prints `123` instead of `$1.23` on my machine. It should not be acceptable output on any locale.
J.F. Sebastian
@J.F. - The expected output is `$1.23`. What platform are you using?
Potatoswatter
@Potatoswatter: http://codepad.org/EY5PqSIw
J.F. Sebastian
@J.F. That's unfortunate, but it only means that your platform is broken. (For example, your `LANG` environment variable isn't set.) Whatever.
Potatoswatter
@Potatoswatter: You mean mine *and* `codepad.org`'s platforms are broken. `codepad.org` compiles/runs code on the server side. btw, `LANG` is `en_US.UTF-8` on the machine I've tested.
J.F. Sebastian
@J.F. http://codepad.org/Adxmw6fC CodePad certainly hasn't set `LANG`, and being an international site, what should their local currency be, anyway? Poor support for this is widespread, but the standard is quite clear about what the output is supposed to look like.
Potatoswatter
@J.F. What's up with refusing to tell what OS you're using, anyway? That's the only information here that could be useful to anyone.
Potatoswatter
@Potatoswatter: I don't see how it might help but the platform is `Linux-2.6.32-21-generic-x86_64-with-Ubuntu-10.04-lucid`
J.F. Sebastian