您遇到的问题与如何浮点数字都在计算机上表示。关于浮点表示的更详细讨论出现在我的答案的末尾(“浮点表示”部分)。这TL;DR版本:由于计算机的内存量有限,因此数字只能以有限的精度表示。因此,浮点数的精度被限制在一定数量的小数位(对于浮点数来说大约是16位有效数字)双精度值,MATLAB 中使用的默认值)。
实际精度与显示精度
现在解决问题中的具体示例......while 24.0000
and 24.0000
are 显示的以同样的方式,事实证明,在这种情况下,它们实际上相差非常小的小数。您看不到它是因为 MATLAB默认只显示4位有效数字,保持整体陈列整洁。如果您想查看完整的精度,您应该发出format long
命令或查看十六进制表示号码:
>> pi
ans =
3.1416
>> format long
>> pi
ans =
3.141592653589793
>> num2hex(pi)
ans =
400921fb54442d18
初始化值与计算值
由于浮点数只能表示有限数量的值,因此计算结果可能会落在这两个表示形式之间。在这种情况下,结果必须四舍五入为其中之一。这就介绍了一个小机器精度误差。这也意味着直接初始化值或通过某些计算初始化值可能会给出略有不同的结果。例如,值0.1
没有exact浮点表示(即,它会稍微四舍五入),因此由于舍入误差累积的方式,您最终会得到这样的反直觉结果:
>> 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
如何正确处理浮点比较
由于浮点值可能相差非常小,因此任何比较都应该通过检查这些值是否在彼此的某个范围(即容差)内来完成,而不是彼此完全相等。例如:
a = 24;
b = 24.000001;
tolerance = 0.001;
if abs(a-b) < tolerance, disp('Equal!'); end
将显示“等于!”。
然后您可以将代码更改为:
points = points((abs(points(:,1)-vertex1(1)) > tolerance) | ...
(abs(points(:,2)-vertex1(2)) > tolerance),:)
浮点表示
对浮点数(特别是浮点运算的 IEEE 754 标准) is 每个计算机科学家都应该了解的浮点运算知识作者:大卫·戈德堡。
二进制浮点数实际上由三个整数表示:一个符号位s
, 有效数(或系数/分数)b
,和一个指数e
. 对于双精度浮点格式,每个数字由在内存中排列的 64 位表示,如下所示:
然后可以通过以下公式找到实际值:
此格式允许 10^-308 到 10^308 范围内的数字表示。对于 MATLAB,您可以从以下位置获取这些限制realmin and realmax:
>> realmin
ans =
2.225073858507201e-308
>> realmax
ans =
1.797693134862316e+308
由于用于表示浮点数的位数是有限的,因此在上述给定范围内只能表示有限的数字。计算通常会产生与这些有限表示之一不完全匹配的值,因此必须对这些值进行四舍五入。这些机器精度误差正如上面的例子中所讨论的那样,它们以不同的方式变得明显。
为了更好地理解这些舍入误差,查看函数提供的相对浮点精度很有用eps,它量化从给定数字到下一个最大浮点表示形式的距离:
>> eps(1)
ans =
2.220446049250313e-16
>> eps(1000)
ans =
1.136868377216160e-13
请注意,精度是relative所表示的给定数字的大小;较大的数字在浮点表示之间的距离较大,因此小数点后的精度位数较少。对于某些计算来说,这可能是一个重要的考虑因素。考虑以下示例:
>> 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
请注意,当我们改变值时x
从范围[0 1]
到范围[10000 10001]
,计算平均值,然后减去平均值偏移进行比较,我们得到最后 3 位有效数字不同的值。这说明了数据的偏移或缩放如何改变对其执行的计算的准确性,这是某些问题必须考虑的问题。