matlab 算24点,为什么在MATLAB中24.0000不等于24.0000?

您遇到的问题与计算机上如何表示浮点数有关。在我的答案结尾处出现了对浮点表示的更详细讨论(“浮点表示”部分)。的TL; DR版本:因为计算机具有有限数量的存储器,数字只能用有限精度表示。因此,浮点数的精度限制在一定的小数位数(双精度值约为16位有效数字,MATLAB中默认使用)。

实际与显示精度

现在,以解决具体的示例中的问题...... 而24.0000与24.0000被显示在相同的方式,事实证明,他们实际上是在这种情况下非常小的小数金额不同。您没有看到它,因为MATLAB 默认只显示4位有效数字,保持整体显示整洁。如果要查看完整精度,则应发出format long命令或查看数字的十六进制表示形式:

>> pi

ans =

3.1416

>> format long

>> pi

ans =

3.141592653589793

>> num2hex(pi)

ans =

400921fb54442d18

初始值与计算值

由于只能为浮点数表示有限数量的值,因此计算可能会产生一个落在其中两个表示之间的值。在这种情况下,结果必须四舍五入到其中一个。这引入了小的机器精度误差。这也意味着直接或通过某些计算初始化值可能会产生略微不同的结果。例如,该值0.1没有精确的浮点表示(即它略微四舍五入),因此您最终会得到类似这样的反直觉结果,这是由于累积错误累积的方式:

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

将显示“Equal!”。

然后,您可以将代码更改为:

points = points((abs(points(:,1)-vertex1(1)) > tolerance) | ...

(abs(points(:,2)-vertex1(2)) > tolerance),:)

浮点表示

浮点数(特别是浮点运算的IEEE 754标准)的一个很好的概述是David Goldberg 每个计算机科学家应该知道的关于浮点运算的内容。

二进制浮点数实际上由三个整数表示:符号位s,有效数(或系数/分数)b和指数e。对于双精度浮点格式,每个数字由内存中的64位表示,如下所示:

651d16e0a55eb05a8c8f278e490a1566.gif

然后可以使用以下公式找到实际值:

f9dba9233c6a18c12e429b173d77c12b.png

该格式允许10 ^ -308到10 ^ 308范围内的数字表示。对于MATLAB你可以从这些限制realmin和realmax:

>> realmin

ans =

2.225073858507201e-308

>> realmax

ans =

1.797693134862316e+308

由于存在用于表示浮点数的有限数量的比特,因此只有很多有限数可以在上述给定范围内表示。计算通常会导致一个值与这些有限表示中的一个不完全匹配,因此必须舍入值。这些机器精度误差使它们以不同的方式显现出来,如上面的例子中所讨论的。

为了更好地理解这些舍入误差,查看函数提供的相对浮点精度很有用eps,它可以量化从给定数字到下一个最大浮点表示的距离:

>> eps(1)

ans =

2.220446049250313e-16

>> eps(1000)

ans =

1.136868377216160e-13

请注意,精度是相对于所表示的给定数字的大小; 较大的数字在浮点表示之间将具有较大的距离,因此在小数点之后具有较少的精度位数。这可能是一些计算的重要考虑因素。请考虑以下示例:

>> 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位有效数字不同。这说明了数据的偏移或缩放如何改变对其执行的计算的准确性,这是某些问题必须考虑的因素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值