Matlab双精度数字:变量编辑器与fprintf

时间:2015-10-16 11:06:29

标签: matlab variables printf precision

关注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位。

1 个答案:

答案 0 :(得分:3)

tl; dr MATLAB中的变量使用双精度。命令窗口和变量编辑器中的变量使用相同的精度。唯一的区别是显示格式和打印到的精确度的小数位数。

默认情况下,MATLAB对其变量使用双精度。 MATLAB中的这些变量存储在Workspace中。命令窗口和变量编辑器都从同一个工作区中提取变量,因此在下面使用相同的精度。

在变量编辑器和命令窗口中显示变量的默认格式是short格式。您可以使用

检查命令窗口
>> get(0, 'format')
ans =
   short

并转到Preferences -> Variables -> Format进行变量编辑。默认情况下,short格式会将变量显示为精确到4位小数。

在我看来,您已将变量编辑器中变量的默认显示格式更改为long格式。此格式显示具有15位小数精度的双变量。 longshort格式都围绕变量,因此pi 3.14159四舍五入为3.1416,因为小数点后的9short格式

显示的地方
>> 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中的变量默认使用双精度
  • MATLAB变量存储在Workspace
  • 命令窗口和变量编辑器中可用的变量都来自工作区并使用相同的精度

预先计算的值

在MATLAB中,您应该在函数调用中或在操作其他数字数据时使用变量名pi180。这将使用双精度并消除使用fprintf或变量编辑器输出的值可能产生的任何复制和粘贴错误。

fprintf Quirks

tl; dr MATLAB的shortlong格式在%d%.f%.g和{{1}之间切换取决于最合适的输入方法。

@ horchler指出%.e仅与特定输入的%.fshort格式直接等效,这是事实。对于long与MATLAB fprintfshort格式之间的所有输入,直接等效。

例如,让我们看一下longeps,并尝试打印与MATLAB的100.5short格式完全相同的数字。

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的shortshort格式在long%d%.f%.g说明符之间切换,具体取决于最合适的输入方法。

补充阅读

您可以通过format documentation找到有关MATLAB中可用的不同显示格式的信息。 Display Format for Numeric Values上还有一份有用的文件。最后,有关于Variable Editor and its preferences的信息。