2016-11-15 141 views
0

我想將浮點數保存在一個二進制文件中,然後讀取它們以供進一步處理。不幸的是,fwrite和之後的fread確實會改變這個數字。fread和matlab中的fwrite不準確

下面這個簡單的例子:

% 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。精密花車(float32only 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蒙上Bdouble在這裏。

MATLAB的默認數據類型,doublefloat64)有兩倍的位可用,這會給你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 

耶。

如果您在MATLAB中需要的精度要高於double,您需要使用符號數學工具箱的一部分vpa或提供更高/可變精度的類似包。