C ++:在文件中写入双精度数,其精度高于默认值

时间:2011-07-11 09:50:34

标签: c++ file double portability precision

我想将双打写入文件,但字符串强制转换会降低精度。 编辑:我没有真正演员,但把双打放在一个ostringstream中。

除了使用modulo和division解析每个数字以更精确地编写双精度之外,还有其他方法吗?

编辑:我的应用程序需要可移植

这是我目前的代码:

std::string arraytocsv(double v[], int size) {  
    std::ostringstream oss;
    for (int i = 0; i < size; i++) {
        oss << v[i] << ";";
    }
    oss << std::endl;
    return oss.str();
}

我有了precision()函数,它有效。感谢

4 个答案:

答案 0 :(得分:9)

您可以使用precision功能。

答案 1 :(得分:3)

声明字符串流后改变其行为:

std::ostringstream oss;
oss.flags (std::ios::scientific);
oss.precision (std::numeric_limits<double>::digits10 + 1);

第一个调用oss.flags()强制C ++ I / O对此字符串流使用科学记数法,即使是像pi这样的东西。使用固定表示法打印数字小于1.0的数字将失去精确度,而以固定表示法打印大数字则极端过度。

第二个调用oss.precision()告诉C ++ I / O在小数点后打印多少位数。使用数字10 + 1告诉它打印一个多余的数字; digits10告诉系统能够在不损失精度的情况下表示多少位数。

由于std::numeric_limits<double>::digits10,您需要#include。

答案 2 :(得分:1)

用二进制写。默认情况下,这不是可移植的(因为序列化格式取决于体系结构)

而不是

double myvalue = 123.4;
file << myvalue;

double myvalue = 123.4;
file.write((const char*) &myvalue, sizeof(myvalue));

当然,这假设您不需要人类阅读此内容(尽管可能使用od这样的UNIX工具)

答案 3 :(得分:0)

如果您只是在一个系统上工作,您可以将实际的二进制数据写入文件,这将为您提供精确的副本。如果要写入文本文件,请将二进制文件转换为Base64或类似的内容。

std::ofstream myfile("file.bin");
double x;

myfile.write(reinterpret_cast<char*>(&x), sizeof(x));

// later

std::ifstream yourfile("file.bin");
double x;
myfile.read(reinterpret_cast<char*>(&x), sizeof(x));

可选地,将字节流编码为base64。如果你想存储长双精度并且你想要使用base64编码,请注意long double通常只有10个字节,所以你可以忽略序列化时通常会得到的填充。

如果您计划在不同平台之间交换数据,但所有平台都使用IEEE浮点数,那么您应该更加小心并记录文件格式的字节顺序。在这种情况下,使用base64编码编写ASCII字符串将更具可移植性。要在 not 的平台之间交换数据都使用相同的二进制浮点表示,你必须更加努力......