浮点数不能代表所有实数。这就是所谓的浮点误差。
有无数个浮点数,它们可以无限长(例如π),因此要完美表示它们将需要无限量的内存。看到这是一个问题,因此设计了一种用于计算机中“实数”存储的特殊表示形式,即IEEE 754标准。简而言之,它描述了计算机如何以指数和尾数形式存储此类数字,例如,
floatnum = sign * 2^exponent * mantissa
对于这些位中的每一个,只有有限的位数,才能达到有限的精度。数字越小,可能的数字之间的距离越小(反之亦然!)。您可以在此在线演示中尝试您的真实数字。
请注意此行为,并尝试避免所有浮点数比较以及将其用作循环中的停止条件。请参阅以下两个示例:
>> 0.1 + 0.1 + 0.1 == 0.3 ans = logical 0
如前例所示,使用浮点比较是不明智的做法。您可以通过取其差异的绝对值并将其与(较小)公差级别进行比较来克服它。
下面是另一个示例,其中在while循环中将浮点数用作停止条件:**
k = 0.1; while k <= 0.3 disp(num2str(k)); k = k + 0.1; end % --- Output: --- 0.1 0.2
它错过了最后一个预期的循环(0.3 <= 0.3)。
x = 0.1 + 0.1 + 0.1; y = 0.3; tolerance = 1e-10; % A "good enough" tolerance for this case. if ( abs( x - y ) <= tolerance ) disp('x == y'); else disp('x ~= y'); end % --- Output: --- x == y
需要注意的几件事:
正如预期的那样,现在x和y被视为等效。
在上面的示例中,公差的选择是任意进行的。因此,选择的值可能不适用于所有情况(尤其是使用小得多的数字时)。可以使用函数(即,其中是一些特定于问题的数字)来智能地选择界限。对的合理选择也是允许的(即使在上述问题中也足够了)。epsN*eps(max(x,y))NN1E2N=1
有关浮点错误的更多信息,请参见以下问题:
为什么在MATLAB中24.0000不等于24.0000?
浮点数学运算是否被破坏?