C ++: запись удваивается в файл с большей точностью, чем по умолчанию - PullRequest
4 голосов
/ 11 июля 2011

Я хочу записать дубликаты в файл, но приведение строки снижает точность.Редактировать: я на самом деле не разыгрываю, но помещаю двойные числа в поток ostring.

Есть ли другой способ, кроме синтаксического анализа каждой цифры с использованием модуля и деления для записи двойных чисел с большей точностью?

Редактировать:Мое приложение должно быть переносимым

Вот мой текущий код:

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 ]

9 голосов
/ 11 июля 2011

Вы можете использовать точность функцию.

3 голосов
/ 11 июля 2011

После объявления потока строки измените его поведение:

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 сообщает, сколько цифр система может представлять без потери точности.

Вам нужно будет #include из-за этого std::numeric_limits<double>::digits10.

1 голос
/ 11 июля 2011

Запишите это в двоичном виде.По умолчанию он не переносимый (в том смысле, что сериализованный формат зависит от архитектуры)

вместо

double myvalue = 123.4;
file << myvalue;

do

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

Конечно, это предполагаетчто вам не нужно, чтобы люди читали это (хотя, используя инструмент UNIX, такой как od они могут)

0 голосов
/ 11 июля 2011

Если вы просто работаете в одной системе, вы можете записать действительные двоичные данные в файл, который даст вам точную копию.Если вы хотите записать в текстовый файл, преобразуйте двоичный файл в 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, обратите внимание, что длинный двойной тип обычно составляет всего 10 байтов, поэтому вы можете игнорировать заполнение, которое обычно получается при сериализации.чтобы обмениваться данными между различными платформами, но все из которых используют плавающие объекты IEEE, вам, вероятно, следует быть более осторожными и документировать порядок файлов в формате.В этом случае запись строки ASCII с кодировкой base64 будет более переносимой.Чтобы обмениваться данными между платформами, которые не все используют одно и то же двоичное представление с плавающей запятой, вам придется работать еще усерднее ...

...