Как работать с большими числами при записи и чтении файла? - PullRequest
1 голос
/ 05 марта 2011

Я написал коды для записи своих данных из одного входного файла в другой выходной файл, я использовал для чтения всех строк моего входного файла

while (!inputfile.eof())

но в моем выходном файле последняя строка отсутствует. Поэтому я хотел бы знать, как предотвратить эту ошибку?

Мой второй вопрос: для записи данных в файл я использовал

Outputfile.write((char*)&a,sizeof(double));
Outputfile.write((char*)&b,sizeof(double));

здесь a = 289814.150 и b = 4320978.613, но в выходном файле это выглядит как

289814 4.32098e+006

(значение a округлено, а значение b показано со значениями e). В чем причина этого и как решить эту проблему?

Здесь я попытался использовать cout.setf(ios::fixed);, но если это работает для данных, записанных на экране, я не знаю, как это исправить, чтобы записать двойные данные внутри моего файла.

Я хочу записать реальные значения с 3 десятичными знаками только в моем выходном файле. Пожалуйста, кто-нибудь может помочь спасибо.

1 Ответ

2 голосов
/ 05 марта 2011

Хорошо, основываясь на комментариях, намерение здесь (по крайней мере, я надеюсь) стало достаточно ясным: преобразовать пары чисел в текстовом формате в двоичный формат и иметь возможность убедиться, что преобразованные числа точно представляют оригиналы.

Есть несколько способов сделать это, но первое, что нужно иметь в виду, это то, что независимо от того, что вы делаете, преобразование чисел с плавающей запятой в / из текстового (десятичного) формата может и обычно приводит кнекоторая степень неточности.Проблема довольно проста: с плавающей запятой (обычно) делается в двоичном виде.Это означает, что он может представлять только дроби, в которых знаменатель является степенью 2 (или суммой степеней 2).Десятичная, очевидно, использует основание 10, поэтому дроби могут состоять из суммы степеней 2 и степеней 5. Любая из тех, в которых используется степень 2 (например, 0,2), может только быть аппроксимированнойв двоичном формате - почти как попытка представить 1/3 rd в десятичном формате.

Это означает, что ваш единственный разумный выбор - разрешить некоторое расхождение между десятичным ибинарные версии.Лучшее, на что вы можете надеяться, это сводить ошибки к минимуму.Чтобы проверить это, то, что вам, вероятно, нужно / нужно сделать, - это преобразовать двоичную плавающую точку обратно в десятичную в исходном формате и проверить, является ли она близкой к исходной (например, игнорировать ошибки в последней цифре, по крайней мере, ошибки +/- 1).

Само преобразование должно быть довольно тривиальным:

#include <fstream>

int main(int argc, char **argv) {
    // checking argc omitted for clarity.
    std::ifstream infile(argv[1]);
    std::ofstream outfile(argv[2], std::ios::binary);

    double a, b;
    while (infile >> a && infile >> b) {
        outfile.write((char const *)&a, sizeof(a));
        outfile.write((char const *)&b, sizeof(b));
    }
    return 0;
}

Проверка данных не так проста.Одна из возможностей будет выглядеть примерно так (начиная с двух файлов, одного двоичного файла и одного текста):

#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>

int main(int argc, char **argv) { 

    std::string text;
    std::ostringstream converter;

    std::ifstream text_file(argv[1]);
    std::ifstream bin_file(argv[2], std::ios::binary);

    double bin_value;

    while (text_file >> text) {
        bin_file.read((char *)&bin_value, sizeof(bin_value));
        // the manipulators will probably need tweaking to match original format.
        converter << std::fixed << std::setw(3) << std::setprecision(3) << bin_value;
        if (converter.str() != text)
            ;// they're identical
        else if (converter.str().substr(0,3) == text.substr(0,3))
            ;// the first three digits are equal
        else
            ;// bigger error
    }
    return 0;
}

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

...