第一:
似乎sprintf和fprintf在不同版本的MATLAB上有不同的行为例如在MATLAB 2018中
num=2.7182818284590666666666;
sprintf('%0.70f', num)
ans =
'2.7182818284590668511668809514958411455154418945312500000000000000000000'
第二个:
浮点数字
MATLAB®以双精度或单精度格式表示浮点数。 默认值是双精度,但您可以使用简单的转换函数使任何数字单精度。
双精度浮点
MATLAB根据IEEE®Standard754构造双精度(或双精度)数据类型,以实现双精度。 存储为double的任何值都需要64位,格式如下表所示:
比特:63
用法:符号(0 =正,1 =负)
比特:62到52 用法:指数,偏向1023
比特:51比0 用法:数字1.f的分数f
有关详细信息,请参阅此链接
在252 = 4,503,599,627,370,496和253 = 9,007,199,254,740,992之间,可表示的数字正好是整数。 对于下一个范围,从253到254,一切都乘以2,所以可表示的数字是偶数,等等。相反,对于之前的范围从2 ^ 51到2 ^ 52,间距是0.5,等等。
作为2 ^ n到2 ^ n + 1范围内的数字的分数的间隔是2 ^ n-52。 将数字四舍五入到最接近的可表示的一个(机器epsilon)时的最大相对舍入误差因此是2 ^ -53。
所以在你的情况下,n = 1(2 ^ 1< = num< = 2 ^ 2),间距是2 ^ -51,
我认为可以安全地假设用于显示数字的sprintf和sprintf算法很棘手且MATLAB Double类型基于IEEE标准,
关于VPA:
vpa使用防护数字来保持精确度
digits函数的值指定使用的最小有效位数。 在内部,vpa可以使用比数字指定更多的数字。 这些附加数字称为保护数字,因为它们可防止后续计算中的舍入错误。
数值约为1/3,使用四位有效数字。
a = vpa(1/3, 4)
a =
0.3333
使用20位数近似结果。 结果显示,在计算a时,工具箱内部使用了超过四位数。 由于舍入错误,结果中的最后一位数字不正确。
vpa(a, 20)
ans =
0.33333333333303016843
你可能遇到的问题是因为间距,gaurd数字算法和舍入问题,
例如,使用matlab 2018 a:
sprintf('%0.28f', 8.0)
ans =
'8.0000000000000000000000000000'
但:
sprintf('%0.28f', 8.1)
ans =
'8.0999999999999996447286321199'
因为数字介于2 ^ 3和2 ^ 4之间,所以间距为2 ^ -49(= 1.77 e-15)所以这个数字有效到小数点后15位和
sprintf('%0.28f', 64.1)
ans =
'64.0999999999999943156581139192'
因为数字介于2 ^ 6和2 ^ 7之间,所以间距为2 ^ -46(= 1.42 e-14)所以这个数字有效到小数点后14位