-2

In my program im trying to read in a file with money like this "$876,725.38" I was able to remove the comma and dollar sign and I am now trying to convert the string to a double using atof but the issue im having now is after printing MONEYS after the conversion I get everything before the period on majority of these, but some with less than 6 digits before the period do print either one or two digits after the period. If anyone has a solution to this it would be greatly appreciated. I'm new to C++ and need help. Thanks!

MAIN ISSUE: Converting from string to double, the data after decimal does not print.

    void readFile()
{
    string line, nuMoney, munney, cents;
    unsigned long dollarSign, period;


    ifstream myfile("MONEY.txt");

    int numLines = countLines("MONEY.txt");
    //cout << "NUMLINES: " << numLines << endl;

    if (!myfile.is_open())
    {
        cout << "ERROR: File could not be opened." << endl;
    }

    for (int i=0; i < numLines-1; i++)
    {
        getline(myfile, line, '\n');
        dollarSign = line.find('$');
        period = line.find('.');

        line.erase (remove(line.begin(), line.end(), ','), line.end()); //remove commas

        munney = line.substr(dollarSign+1);
        //cout << munney << endl;

        //cents = line.substr(period);
        //cout << "Cents: " << cents << endl;

        //double CENTUS = atof(cents.c_str());
        //cout << "CENTUS: " << CENTUS << endl;

        double MONEYS = atof(munney.c_str());
        cout << MONEYS << endl;

        list<double> acct;
        acct.push_back(MONEYS);

    }

}

sample output:

937380
404261
814158
30218.1
69340.1
479891
517241
7203.55
975619
59219.4
900052
539774
336799
347700
532466
83496.8

3 Answers3

1

Floating point (float, double and long double) aren't great for storing exact values. They are great because they make it easy to do lots of different math on a wide range of values, but there are many values which can't be represented exactly using IEEE floating points. Values as simple as 0.1 can't be exactly expressed by the type, but the input and output routines often round to make it seem like they are handled correctly.

To store decimal perfect values I suggest treating the 2 parts of the value as separate integers when reading in, converting the fractional point based on how many digits after the decimal place were read in, and then doing a little bit of math to convert both pieces into a single integer. For US money the LSB (least significant bit) of this integer may represent 1 cent (unless fractional cents need to be represented accurately). A similar approach can be used for outputting the values.

nategoose
  • 12,054
  • 27
  • 42
  • thank you, im not really sure the math bit to convert the 2 pieces into a single int. Some more insight into that please. – Johnny Tran Mar 27 '15 at 19:23
0

It looks like it's due to default precision of cout stream for floating point values: http://www.cplusplus.com/reference/ios/ios_base/precision/

Alexandr Zarubkin
  • 899
  • 1
  • 11
  • 26
0

You have to tell the output stream that you want a fixed precision of 2 digits after the dot:

#include <iomanip>
// ...
std::cout << std::fixed << std::setprecision(2) << MONEYS << '\n';
fredoverflow
  • 256,549
  • 94
  • 388
  • 662