bre*_*ntf 4 c++ rounding ofstream
我正在开发一个 C++ 程序,其中包含许多 double 类型的数字(数百万和数十亿的值,小数点右侧只有几个位置)。我正在对这些数字进行计算,然后将结果打印到文本/CSV 文件中。我注意到在文本文件中,我的所有数字似乎都四舍五入(到六位数)。因此,值 13,169,911 在我的输出文件中显示为 13,169,900。
这种四舍五入只发生在印刷品上吗?为了获得变量中的完整位数,我是否只需要在写入文件时指定一些内容?我在下面包含了我写入文件代码的示例:
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;
}
Run Code Online (Sandbox Code Playgroud)
问题可能与输出流为doubles生成输出的方式有关:如果13169911以“科学记数法”打印,它看起来像1.31699E7. Excel 会很好地读取这个符号,但会为它没有“看到”的数字加上零,使数字看起来像13,169,900.
要解决此问题,请fixed在输出时添加操纵器double以确保打印所有数字:
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;
Run Code Online (Sandbox Code Playgroud)
您需要使用std::setprecision来提高流的精度。默认情况下 aniostream只有 6 位精度。
尝试这个:
OutFile << std::setprecision(std::numeric_limits<long double>::digits10 << PF[i].CurLoanBal;
Run Code Online (Sandbox Code Playgroud)
请记住,这将影响流上的所有后续操作。老实说,这可能就是您想要的!
作为std::setprecision和之间的比较std::fixed,该程序:
#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'
;
}
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
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
Run Code Online (Sandbox Code Playgroud)
所以我认为你可能想要std::setprecision而不是std::fixed。尽管我想无论如何你都只会有两位小数,所以也许这并不重要。
在这里阅读更多内容:http ://en.cppreference.com/w/cpp/io/manip/set precision