<p>您遇到的问题与<a href="https://www.mathworks.com/help/matlab/matlab_prog/floating-point-numbers.html" rel="noreferrer">floating-point numbers</a>在计算机上的表示方式有关。关于浮点表示法的更详细讨论出现在我的答案的末尾(“浮点表示法”部分)。<strong>TL;DR</strong>版本:由于计算机内存有限,数字只能以有限的精度表示。因此,浮点数的精度被限制在一定的小数位数(大约16位有效数字表示<a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format" rel="noreferrer">double-precision values</a>,这是MATLAB中使用的默认值)</p>
<h2>实际精度与显示精度</h2>
<p>现在来解决问题中的具体例子<strong>虽然<code>24.0000</code>和<code>24.0000</code>以相同的方式显示<em>,</em>,但在这种情况下,它们的差异实际上非常小。您看不到它,因为MATLAB <a href="https://www.mathworks.com/help/matlab/ref/format.html" rel="noreferrer">only displays 4 significant digits by default</a>保持了整体显示的整洁。</strong>如果您想看到完整的精度,您应该发出<code>format long</code>命令或查看<a href="https://www.mathworks.com/help/matlab/ref/num2hex.html" rel="noreferrer">hexadecimal representation</a>的数字:</p>
<pre><code>>> pi
ans =
3.1416
>> format long
>> pi
ans =
3.141592653589793
>> num2hex(pi)
ans =
400921fb54442d18
</code></pre>
<h2>初始化值与计算值</h2>
<p>由于浮点数只能表示有限数量的值,因此计算结果可能介于这两种表示之间。在这种情况下,结果必须四舍五入到其中一个。这引入了一个小的<a href="https://en.wikipedia.org/wiki/Machine_epsilon" rel="noreferrer">machine-precision error</a>。这也意味着直接初始化一个值或通过某些计算初始化一个值可以得到稍微不同的结果。例如,值<code>0.1</code>没有<em>精确的</em>浮点表示法(即,它会稍微四舍五入),因此由于四舍五入错误的累积方式,最终会出现这样的反直觉结果:</p>
<pre><code>>> a=sum([0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]); % Sum 10 0.1s
>> b=1; % Initialize to 1
>> a == b
ans =
logical
0 % They are unequal!
>> num2hex(a) % Let's check their hex representation to confirm
ans =
3fefffffffffffff
>> num2hex(b)
ans =
3ff0000000000000
</code></pre>
<h2>如何正确处理浮点比较</h2>
<p>由于浮点值之间的差异可能非常小,因此任何比较都应通过检查值是否在彼此的某个范围(即公差)内(而不是完全相等)来完成。例如:</p>
<pre><code>a = 24;
b = 24.000001;
tolerance = 0.001;
if abs(a-b) < tolerance, disp('Equal!'); end
</code></pre>
<p>将显示“相等!”</p>
<p>然后,您可以将代码更改为:</p>
<pre><code>points = points((abs(points(:,1)-vertex1(1)) > tolerance) | ...
(abs(points(:,2)-vertex1(2)) > tolerance),:)
</code></pre>
<hr/>
<h2>浮点表示法</h2>
<p>David Goldberg的<a href="http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html" rel="noreferrer"><em>What Every Computer Scientist Should Know About Floating-Point Arithmetic</em></a>对浮点数(特别是<a href="https://en.wikipedia.org/wiki/IEEE_floating_point" rel="noreferrer">IEEE 754 standard for floating-point arithmetic</a>)有一个很好的概述</p>
<p>二进制浮点数实际上由三个整数表示:符号位<code>s</code>、有效位(或系数/分数)<code>b</code>和指数<code>e</code><a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format" rel="noreferrer">For double-precision floating-point format</a>,每个数字由内存中的64位表示,如下所示:</p>
<p><a href="https://i.stack.imgur.com/KTTPX.png" rel="noreferrer"><img src="https://i.stack.imgur.com/KTTPX.png" alt="enter image description here"/></a></p>
<p>然后可通过以下公式找到实际值:</p>
<p><a href="https://i.stack.imgur.com/nV0ly.png" rel="noreferrer"><img src="https://i.stack.imgur.com/nV0ly.png" alt="enter image description here"/></a></p>
<p>此格式允许在10^-308到10^-308范围内表示数字。对于MATLAB,您可以从<a href="https://www.mathworks.com/help/matlab/ref/realmin.html" rel="noreferrer">^{<cd8>}</a>和<a href="https://www.mathworks.com/help/matlab/ref/realmax.html" rel="noreferrer">^{<cd9>}</a>获得这些限制:</p>
<pre><code>>> realmin
ans =
2.225073858507201e-308
>> realmax
ans =
1.797693134862316e+308
</code></pre>
<p>由于用于表示浮点数的位数是有限的,因此在上述给定范围内只能表示这么多的有限位数。计算通常会导致一个值与这些有限表示形式中的一个不完全匹配,因此这些值必须舍入。这些{a13}以不同的方式表现出来,如上述示例所述</p>
<p>为了更好地理解这些舍入错误,有必要查看函数<a href="https://www.mathworks.com/help/matlab/ref/eps.html" rel="noreferrer">^{<cd10>}</a>提供的相对浮点精度,该函数量化从给定数字到下一个最大浮点表示的距离:</p>
<pre><code>>> eps(1)
ans =
2.220446049250313e-16
>> eps(1000)
ans =
1.136868377216160e-13
</code></pre>
<p>请注意,精度与所表示的给定数字的大小有关;数字越大,浮点表示之间的距离越大,因此小数点后的精度位数越少。这在一些计算中可能是一个重要的考虑因素。考虑下面的例子:</P>
<pre><code>>> format long % Display full precision
>> x = rand(1, 10); % Get 10 random values between 0 and 1
>> a = mean(x) % Take the mean
a =
0.587307428244141
>> b = mean(x+10000)-10000 % Take the mean at a different scale, then shift back
b =
0.587307428244458
</code></pre>
<p>请注意,当我们将<code>x</code>的值从范围<code>[0 1]</code>移动到范围<code>[10000 10001]</code>时,计算平均值,然后减去用于比较的平均偏移量,我们得到一个与最后3个有效数字不同的值。这说明了数据的偏移或缩放如何改变对其执行的计算的准确性,这是必须考虑到某些问题的</p>