2016-11-15 17 views
0

Я хотел бы сохранить числа с плавающей точкой в ​​двоичном файле и прочитать их впоследствии для дальнейшей обработки. К сожалению, fwrite и afterfread изменяет число.fread и fwrite in matlab не точно

После простой пример:

% Number to store 
A = 0.123456789101112 

% Generate and open txt file 
fid = fopen('test_fread.txt','w','b'); 

% write A into test_fread.txt 
fwrite(fid,A,'float32'); 

% close file 
fclose(fid) 

% open txt file 
fid = fopen('test_fread.txt','r','b'); 

% read the file 
fread(fid,'float32') 

ans = 0.123456791043282 

Ответ отличается от входного сигнала. Как я могу это исправить? Что я должен искать? Это округление, точность или другая проблема?

+3

32-битные поплавки [имеют только 6-9 десятичных значений точности] (https://en.wikipedia.org/wiki/Single-precision_floating-point_format). Если вам нужна более высокая точность, один вариант состоит в том, чтобы умножить на известную мощность 10 и сохранить значение как целочисленное значение соответствующего размера, с оговоркой, что тип данных по умолчанию MATLAB, 'double' имеет только 15-17 значащих десятичных цифр. – excaza

ответ

1

Номера с плавающей запятой are never exact. single прецизионные поплавки (float32) only have 6-9 decimals of precision. Для чистого десятичного кода это означает проблему, которую вы видите. Эффект более преувеличенными, если у вас также есть целое число компонент:

% Sample number 
A = 123456789.123456789; 

% Write, rewind, and read back in 
fID = fopen('test_fread.txt', 'w+', 'b'); 
fwrite(fID, A, 'float32'); 
frewind(fID); 
B = fread(fID,'float32'); 
fclose(fID); 

fprintf('A: %15.15f\nB: %15.15f\n', A, B); 

Который возвращает:

A: 123456789.123456790000000 
B: 123456792.000000000000000 

Обратите внимание, что MATLAB бросает B как double здесь.

Тип данных по умолчанию MATLAB, double (float64) имеет двойные биты, которые предоставят вам 15-17 significant decimal digits. Используя предыдущий пример, мы можем попробовать:

% Sample number 
A = 123456789.123456789; 

% Write, rewind, and read back in 
fID = fopen('test_fread.txt', 'w+', 'b'); 
fwrite(fID, A, 'float64'); 
frewind(fID); 
B = fread(fID,'float64'); 
fclose(fID); 

fprintf('A: %15.15f\nB: %15.15f\n', A, B); 

который возвращает:

A: 123456789.123456790000000 
B: 123456789.123456790000000 

Yay.

Если вам нужна более высокая точность в MATLAB, чем double, вам нужно будет изучить vpa, который является частью Symbolic Math Toolbox или аналогичного пакета, который предлагает более высокую/переменную точность.

 Смежные вопросы

  • Нет связанных вопросов^_^