fread和matlab中的fwrite不准确
问题描述:
我想将浮点数保存在一个二进制文件中,然后读取它们以供进一步处理。不幸的是,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
答案是比输入不同。我怎样才能解决这个问题?我应该搜索什么?它是四舍五入,精确还是其他问题?
答
浮点数are never exact。精密花车(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
耶。
如果您在MATLAB中需要的精度要高于double
,您需要使用符号数学工具箱的一部分vpa
或提供更高/可变精度的类似包。
32位浮点数[只有6-9精度的十进制](https://en.wikipedia.org/wiki/Single-precision_floating-point_format)。如果您需要更高的精度,一个选项是乘以10的已知功率,并将该值保存为适当大小的整数,但要注意MATLAB的默认数据类型“double”只有15-17个重要的十进制数字。 – excaza