Загрузка данных из файла в C - PullRequest
2 голосов
/ 06 декабря 2009

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

Я попытался сохранить это в массиве строк, а затем преобразовать их в масштабированные целые числа. но я не могу загрузить его в массив строк. Может кто-нибудь сказать мне, где я иду не так. что я сделал, это что-то вроде этого.

unsigned char **data
............
data = malloc(sizeof(unsigned char *) * fileSize);  
............
while (!feof(fp))
{
if (fscanf (fp, "%s",  &data[j]) == 1) // if converted, increment counter
 ++j; 
}
...........

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

Ответы [ 5 ]

3 голосов
/ 06 декабря 2009

У вас может не быть большого выбора, когда речь идет о числах с плавающей запятой, например 123.45, отображаемых как 123.44999

«Неточность» представлений с плавающей точкой много раз обсуждалась на SO, вот один пример .

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

1 голос
/ 06 декабря 2009

не используйте float, используйте double.

также вы можете использовать

двойной д;

чтения (г);

(int) (d * 100), чтобы получить int.

0 голосов
/ 06 декабря 2009

Насколько важна эта точность для вашего приложения? Числа с плавающей запятой часто могут быть немного неточными, потому что они хранят числа в представлении с основанием 2 (двоичное), которое не может должным образом представлять некоторые числа с основанием 10.

У вас есть несколько вариантов, в зависимости от того, насколько важна эта точность для вашего приложения.

  1. Жить с этим. Может быть, эта неточность не является проблемой для вашего приложения
  2. Используйте Double. В два раза больше места представлять числа, и будет более точным. Это все еще может быть неточным в некоторых случаях.
  3. Использовать математику с фиксированной точкой. Если вам нужно перейти только на n десятичных знаков, возможно, стоит поискать этот подход (так как он устраняет источник неточностей).
  4. Сохраняйте число с плавающей запятой в виде строки символов или сохраняйте ее в виде двоичного десятичного числа. Вам нужно будет написать функции для любых математических операций, которые вам нужны, и производительность будет самой плохой из этих 4 опций. Но вы сможете работать с десятичными числами произвольной точности, не беспокоясь о какой-либо потере точности.

Варианты 3 или 4 требуют либо использования внешней библиотеки, либо развертывания собственной реализации. Если 1 или 2 достаточно хороши, я не стал бы беспокоиться об этих параметрах.

0 голосов
/ 06 декабря 2009

Я бы посоветовал вам использовать ifstream для чтения в строку, а затем преобразовать ее в double.

string number;
ifstream yourfile("yourfile", ios::in);

if(yourfile)
    while(yourfile >> number){
     double yourFloat=strtod( number.c_str() );
    }
0 голосов
/ 06 декабря 2009

К сожалению, все, что вас поражает, это тот факт, что некоторые числа не могут быть точно представлены с типом данных с плавающей запятой. Если вы вручную присвоили 124,45 с плавающей точкой в ​​C (то есть с плавающей точкой f = 123,45), вы получите точно такую ​​же проблему.

Вам действительно нужен уровень точности? Какие у вас планы на данные?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...