关注this question,我在研究Matlab中双变量的精度。在那里,建议使用fprintf
更密切地查看变量。
奇怪的是,变量编辑器和fprintf
显示不同的结果,fprintf显示更多的数字。
% pi
Variable Editor: 3.141592653589793
fprintf('0.16f\n',pi): 3.1415926535897931
vpa('pi'): 3.1415926535897932384626433832795
% pi / 180
pi180 = pi/180
Variable Editor (pi180) 0.017453292519943
fprintf('%0.16f\n',pi180) 0.0174532925199433
vpa('pi/180') 0.017453292519943295769236907684886
在内部,Matlab似乎正在使用由fprintf
打印的精度>> fprintf('%0.16f\n',0.0174532925199433*10) % value from fprintf
0.1745329251994330
>> fprintf('%0.16f\n',0.017453292519943*10) % value from Variable Editor
0.1745329251994300
>> fprintf('%0.16f\n',pi180*10) % internal calculation
0.1745329251994330
为什么会这样?
如果我在函数中使用预先计算的pi/180
,我应该使用fprintf中的值还是变量编辑器中的值?
tl; dr 在变量编辑器中,Matlab截断为15位而不是16位。
答案 0 :(得分:3)
tl; dr MATLAB中的变量使用双精度。命令窗口和变量编辑器中的变量使用相同的精度。唯一的区别是显示格式和打印到的精确度的小数位数。
默认情况下,MATLAB对其变量使用双精度。 MATLAB中的这些变量存储在Workspace中。命令窗口和变量编辑器都从同一个工作区中提取变量,因此在下面使用相同的精度。
在变量编辑器和命令窗口中显示变量的默认格式是short
格式。您可以使用
>> get(0, 'format')
ans =
short
并转到Preferences -> Variables -> Format
进行变量编辑。默认情况下,short
格式会将变量显示为精确到4位小数。
在我看来,您已将变量编辑器中变量的默认显示格式更改为long
格式。此格式显示具有15位小数精度的双变量。 long
和short
格式都围绕变量,因此pi
3.14159
四舍五入为3.1416
,因为小数点后的9
以short
格式
>> format short
>> pi
ans =
3.1416
这直接等同于fprintf
>> fprintf(1, '%.4f\n', pi);
3.1416
然而,我猜测的long
格式,你已经设置为变量编辑器的默认值,将其舍入到15位小数,因此显示
>> format long
>> pi
ans =
3.141592653589793
直接等同于
>> fprintf(1, '%.15f\n', pi);
3.141592653589793
当您使用fprintf(1, '%.16f\n', pi);
时,您将pi
打印到16位小数,不 15打印long
格式。这就是你的输出
>> fprintf(1, '%.16f\n', pi);
3.1415926535897931
注意,最后是1
。这就是为什么在变量编辑器中显示时,它前面的3
未四舍五入为4
。
在MATLAB中,您应该在函数调用中或在操作其他数字数据时使用变量名pi180
。这将使用双精度并消除使用fprintf
或变量编辑器输出的值可能产生的任何复制和粘贴错误。
fprintf
Quirks tl; dr MATLAB的short
和long
格式在%d
,%.f
,%.g
和{{1}之间切换取决于最合适的输入方法。
@ horchler指出%.e
仅与特定输入的%.f
和short
格式直接等效,这是事实。对于long
与MATLAB fprintf
和short
格式之间的所有输入,无直接等效。
例如,让我们看一下long
和eps
,并尝试打印与MATLAB的100.5
和short
格式完全相同的数字。
long
和
>> format short
>> eps
ans =
2.2204e-16
>> 100.5
ans =
100.5000
现在我们从上面知道,>> format long
>> eps
ans =
2.220446049250313e-16
>> 100.5
ans =
1.005000000000000e+02
和fprintf(1, '%.4f\n', pi);
分别直接相当于fprintf(1, '%.15f\n', pi);
和short
long
,但它们是pi
}和eps
100.5
否它们不是唯一直接等效的>> fprintf(1, '%.4f\n', eps);
0.0000
>> fprintf(1, '%.15f\n', eps);
0.000000000000000
>> fprintf(1, '%.4f\n', 100.5);
100.5000
>> fprintf(1, '%.15f\n', 100.5);
100.500000000000000
。如果我们尝试使用fprintf(1, '%.4f\n', 100.5);
?
%.g
现在>> fprintf(1, '%.4g\n', eps);
2.22e-16
>> fprintf(1, '%.15g\n', eps);
2.22044604925031e-16
>> fprintf(1, '%.4g\n', 100.5);
100.5
>> fprintf(1, '%.15g\n', 100.5);
100.5
个语句都不是直接等价的。但是,我们可以使用fprintf
格式与
eps
的直接等效项
long
因为>> fprintf(1, '%.16g\n', eps);
2.220446049250313e-16
格式说明符的.
后面的数字指定了有效数字的位数(包括小数点之前的那些数字%g
),我们需要使用 16 而不是 15 。
要为.
格式生成所有这些输入类型的直接等效项,我们需要混合使用short
,%.f
和 %.g
说明符以及调整field width。
%.e
根本不重要。 >> format short
>> pi
ans =
3.1416
>> eps
ans =
2.2204e-16
>> 100.5
ans =
100.5000
>> fprintf(1, '%.4f\n', pi);
3.1416
>> fprintf(1, '%.5g\n', eps);
2.2204e-16
>> fprintf(1, '%.4f\n', 100.5);
100.5000
格式也可以这样做。
long
甚至比>> format long
>> pi
ans =
3.141592653589793
>> eps
ans =
2.220446049250313e-16
>> 100.5
ans =
1.005000000000000e+02
>> fprintf(1, '%.15f\n', pi);
3.141592653589793
>> fprintf(1, '%.16g\n', eps);
2.220446049250313e-16
>> fprintf(1, '%.15e\n', 100.5);
1.005000000000000e+02
格式更差。
简而言之,MATLAB的short
和short
格式在long
,%d
,%.f
和%.g
说明符之间切换,具体取决于最合适的输入方法。
您可以通过format
documentation找到有关MATLAB中可用的不同显示格式的信息。 Display Format for Numeric Values上还有一份有用的文件。最后,有关于Variable Editor and its preferences的信息。