matlab 中的 fread 和 fwrite 不准确

fread and fwrite in matlab not exact

我想将浮点数保存在二进制文件中,然后读取它们以进行进一步处理。不幸的是, fwrite 和之后的 fread 确实改变了这个数字。

以下简单示例:

% 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. single precision floats (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);

哪个returns:

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);

哪个returns:

A: 123456789.123456790000000
B: 123456789.123456790000000

赞。

如果您在 MATLAB 中需要比 double 更高的精度,您将需要考虑使用 vpa,它是 Symbolic Math Toolbox 的一部分,或提供 higher/variable 精确。