2016-11-15 72 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或提供更高/可变精度的类似包。