【问题标题】:Matlab Double Precision Digits: Variable Editor vs. fprintfMatlab 双精度数字:变量编辑器与 fprintf
【发布时间】:2016-01-15 02:49:40
【问题描述】:

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

【问题讨论】:

  • 我已经通过双击变量编辑器中的变量来访问它。这样,显示的数字比指定的short 格式多。 AFAIK 无法更改“双击输出”的精度。

标签: matlab variables printf precision


【解决方案1】:

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


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

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

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

对于变量编辑器,请转到 Preferences -> Variables -> Formatshort 格式默认显示变量,精确到小数点后 4 位。

在我看来,您已将变量编辑器中变量的默认显示格式更改为 long 格式。此格式显示精度为小数点后 15 位的双变量。 longshort 都格式化了舍入变量,因此 pi3.14159 会舍入为 3.1416,因为当使用 short 格式显示时,9 在小数点后 5 位

>> 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 变量存储在工作区中
  • 命令行窗口和变量编辑器中可用的变量都来自工作区并使用相同的精度

预计算值

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

fprintf怪癖

tl;dr MATLAB 的 shortlong 格式在 %d%.f%.g%.e 说明符之间切换,具体取决于最合适的输入方法.


@horchler 指出%.f 仅直接等效于特定输入的shortlong 格式,这是真的。 fprintf 和 MATLAB 的 shortlong 格式之间的所有输入没有直接等效。

例如,让我们看看 eps100.5 并尝试完全按照 MATLAB 的 shortlong 格式打印数字。

>> 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); 直接等效于pishortlong 但它们是eps100.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 语句是直接等价的。但是,我们可以使用long 格式生成eps 的直接等价物

>> fprintf(1, '%.16g\n', eps);
2.220446049250313e-16

因为紧跟在%g 格式说明符的. 之后的数字指定了有效位数(包括小数点之前的那些,.),我们需要使用16 和不是15

要为short 格式的所有这些输入类型生成直接等效项,我们需要混合%.f%.g%.e 说明符并调整@ 987654322@.

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

short 格式还要糟糕。

简而言之,MATLAB 的 shortlong 格式在 %d%.f%.g%.e 说明符之间切换,具体取决于最合适的输入方法。

补充阅读

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

【讨论】:

  • 因此没有 fprintf 就无法在工作区或变量编辑器中以全精度显示双变量。 :)
  • 精度超过 15 位小数,没有。
  • 您的fprintf 示例仅对一系列值“直接等效”。 %g 选项需要用于一般情况,即便如此,我不确定 Matlab 打印的内容是否仅基于此。
  • @horchler 您是对的,我的示例仅直接等效于特定值。 %g 选项虽然不涵盖一般情况。 MATLAB 的 shortlong 格式在 %d%.f%.g%.e 之间交替,具体取决于输入。我已经用反映这一点的部分更新了答案。
猜你喜欢
  • 2013-05-07
  • 1970-01-01
  • 2013-09-06
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
相关资源
最近更新 更多