Unexpected rounding of double types in C ++ write to file

I am working on a C ++ program with a large number of numbers that are double types (values ​​in millions and billions with just a couple of places to the right of the decimal point). I do the calculations on these numbers and then print the result into text / CSV files. I noticed that in text files all my numbers are rounded (up to six digits). So the value 13,169,911 is displayed as 13,169,900 in my output file.

Is this rounding only on print? To get the total number of digits in a variable, I just need to specify something when I write to a file? I have included sample code to write to the file 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; } 
+4
source share
2 answers

You need to use std::setprecision to increase the accuracy of the stream. By default, iostream has only 6 digits of accuracy.

Try the following:

 OutFile << std::setprecision(std::numeric_limits<long double>::digits10 << PF[i].CurLoanBal; 

Keep in mind that this will affect all subsequent operations on the stream. To be honest, then maybe you want to!

As a 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 conclusion:

 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 might need std::setprecision , not std::fixed . Although I think you will only have two decimal places, so maybe that doesn't matter.

More details here: http://en.cppreference.com/w/cpp/io/manip/setprecision

+3
source

The problem is most likely related to how the output stream generates output for double s: if 13169911 is printed in "scientific notation", it will look like 1.31699E7 . Excel would read this notation just fine, but would put zeros for numbers that it doesn't β€œsee”, making the number look like 13,169,900 .

To fix this problem, add a fixed manipulator when outputting double to ensure that all digits are 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; 
+4
source

Source: https://habr.com/ru/post/1495989/


All Articles