我正在使用ofstream
输出浮动CSV。 99%的浮点数的精确度为1-2位小数,因此只需使用fileOut.precision(3)
就足以强制使用正确的精度。
一次又一次浮动将具有极低的值,因此将以科学记数法1e-007
输出。在这种情况下,我最好是0
。
这里有很多答案建议使用类似于fileOut.setf(std::ios::fixed, std::ios::floatfield);
的内容来阻止这种情况,但这会使每个字段输出为0.000
,无论它是否需要那么多数字。
我希望所有花车能够正常运行并且不显示科学记数法。
无论如何要做到这一点,还是我必须创建一个简单的函数来检查一个数字是否低于0.001
,如果这样设置为0?
更新
我现在使用以下代码来包装任何浮点数,它不是理想的但是有效。
float _RoundToZero(float in, int precision = 2)
{
return in <= (1 / powf(10,precision)) ? 0.0 : in;
}
答案 0 :(得分:0)
考虑将值乘以100打印为整数(舍入精度)。这样,虽然有时你会得到尾随的零,你将永远不必打印小数位,这将为每个值浪费1个字符。
或者,以二进制形式写入float。由于所有浮点数都具有相同的大小(4个字节),因此您可以保留原始数据的所有精度,而不必担心尾随零,您的文件大小非常可预测,并且您不必浪费空间来区分值。 100个值需要400个字节。在文本格式中,值至少需要2个字节(数字+字段分隔符)和格式允许的最大值(包括小数点一个)加上分隔符。在这种格式中,4个字节可以获得2个有效精度数字,而不是5或6个浮点数。
答案 1 :(得分:-1)
抱歉,使用iostream
和 printf
无法实现。唯一的选择是:
第一个是复杂的,最后一个是不准确的(在二进制浮点数中不能完全代表10 -n )。
所有这些都可以通过覆盖numput facet来实现,这将允许您像以前一样保持格式化代码。
以下是最后一个选项的实现:
#include <iostream>
#include <locale>
#include <math.h>
using namespace std;
class my_put : public std::num_put<char> {
iter_type do_put (iter_type out, ios_base& str, char_type fill, double val) const
{
streamsize prec = str.precision();
if((str.flags() & ios_base::floatfield) == ios_base::fixed && fabs(val)*2 <= pow(10.0, -(int)prec))
str.precision(0);
out = std::num_put<char>::do_put(out, str, fill, val);
str.precision(prec);
return out;
}
};
int main()
{
double a[] = {123, 0, 0.001, 0.0001 };
cout.imbue(locale(cout.getloc(), new my_put));
cout.precision(3);
cout.setf(ios_base::fixed, ios_base::floatfield);
for(int i = 0; i < 4; ++i)
cout << a[i] << '\n';
}
请在此处查看输出:http://ideone.com/qaV0w
请注意,边界情况(0.0005)的正确性取决于下划线浮点格式和实现。