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 精确。
我想将浮点数保存在二进制文件中,然后读取它们以进行进一步处理。不幸的是, 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 精确。