I am working on a C++ program with a lot of numbers that are type double (values in the millions and billions with just a couple places to the right of the decimal point). I am performing calculations on these numbers and then printing the result to text/CSV files. I noticed that in the text files, all of my numbers appear to be rounded (to six digits). So, a value of 13,169,911 is showing up as 13,169,900 in my output file.
Is this rounding only occuring on the print? In order to get the full number of digits in the variable, do I just need to specify something when I write to a file? I included a sample of my write to file code below:
void PrintPropFinance(vector<PropFinance>& PF, int NumProps, int Iterations, int ForecastLength,
string CurDeal, string ModelRunID, string ScenName, Assumptions& Ass) {
string filename;
ofstream OutFile;
ostringstream s1;
s1 << BASEPATH << "Output/" << CurDeal << "_" << ModelRunID << "_" <<
ScenName << "_PropFinance" << ".csv";
filename = s1.str();
OutFile.open(filename);
// Put in the column headers first
OutFile << "PropID" << ","
<< "Item" << ","
<< "StartDate" << ","
<< "NumOfPeriod" << ","
<< "Result" << ","
<< "Isap" << ","
<< "CurLoanBal" << ","
for (int i=1; i<=NumProps; ++i) {
// Populate the single-vector variables
OutFile << PF[i].PropID << ","
<< PF[i].Item << ","
<< PF[i].StartDate << ","
<< PF[i].NumOfPeriod << ","
<< PF[i].Result << ","
<< PF[i].Isap << ","
<< PF[i].CurLoanBal << ","
<< endl;
}
OutFile.close();
}
// Prop finance class definition
class PropFinance {
public:
string PropID;
int Item;
string StartDate;
int NumOfPeriod;
string Isap;
double CurLoanBal;
}
The problem is likely to do with the way the output stream produces the output for double
s: if 13169911
gets printed in "scientific notation", it would look like 1.31699E7
. Excel will read this notation just fine, but would put zeros for the digits it does not "see", making the number look like 13,169,900
.
To fix this problem, add fixed
manipulator when you output your double
to ensure that all digits get printed:
OutFile << PF[i].PropID << ","
<< PF[i].Item << ","
<< PF[i].StartDate << ","
<< PF[i].NumOfPeriod << ","
<< fixed << PF[i].Result << ","
<< PF[i].Isap << ","
<< fixed << PF[i].CurLoanBal << ","
<< endl;
You need to use std::setprecision
to increase the precision of the stream. By default an iostream
has only 6 digits of precision.
Try this:
OutFile << std::setprecision(std::numeric_limits<long double>::digits10 << PF[i].CurLoanBal;
Bear in mind that this will affect all subsequent operations on the stream. To be honest though, that's probably what you want!
As comparison between std::setprecision
and std::fixed
, this program:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <limits>
int main()
{
const long double test_value = 13169911.7777777;
std::cout << "default precision (6): " << test_value << '\n'
<< "std::fixed: " << std::fixed << test_value << '\n'
<< "std::precision(10): " << std::defaultfloat << std::setprecision(10) << test_value << '\n'
<< "std::precision(10) & std::fixed: " << std::fixed << std::setprecision(10) << test_value << '\n'
<< "max precision: " << std::defaultfloat << std::setprecision(std::numeric_limits<long double>::digits10) << test_value << '\n'
<< "max precision & std::fixed: " << std::fixed << std::setprecision(std::numeric_limits<long double>::digits10) << test_value << '\n'
;
}
Produces this output:
default precision (6): 1.31699e+007
std::fixed: 13169911.777778
std::precision(10): 13169911.78
std::precision(10) & std::fixed: 13169911.7777777000
max precision: 13169911.7777777
max precision & std::fixed: 13169911.777777700000000
So I think you may want std::setprecision
rather than std::fixed
. Though I imagine that you'll only have two decimal places anyway so perhaps it doesn't matter.
Read more here: http://en.cppreference.com/w/cpp/io/manip/setprecision
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With