将复制值与原始值进行比较时是否存在精度问题?

Are there precision issues when comparing a copied value with the original value?

考虑以下工作流程:

A = [2/3 exp(1) 5];

match = interp1(A, A, 2, 'next');

第二个命令查找A的值,它在2之后的第一个。因此,match等于exp(1)

我有两个问题:

  1. 我可以期望 A == match 的计算结果总是 [0 1 0] 吗?
  2. 如果B = [exp(1) exp(1) exp(1)]B == match的结果是什么?

如果 exp(1) 被其他无理数或超越数代替,答案会改变吗?

  1. 在内存中复制一个值时,任何存在的浮点错误都将按原样复制,因为毕竟复制操作只是将位复制到内存中的新位置,然后实际上没有执行任何算术运算,也不会引入新的精度误差。 因此,浮点数(有精度错误)与该数字的精确副本之间的比较将始终相等。

    也就是说,您的示例假定 interp1 中的下一个邻居插值的实现只是复制数据。虽然这在当前版本中可能是正确的,但肯定会发生变化。如果将来 interp1 被重写以代替执行一些浮点运算来进行下一个邻居插值,那么您的比较将意外失败。因此,即使在这种情况下,我也不鼓励使用 == 进行比较。

  2. 浮点错误的差异(对于相同的计算)通常是由不同的 typesorder 引起的操作。对于 exp(1) 的示例,人们会期望内置的 exp 函数会执行相同的操作顺序,因此,对于相同的(相同的)输入,输出值都将具有相同的精度误差。因此,您的比较将产生 [1 1 1].

    同样,这对内置函数的内部构成了一个假设,最终可能会反噬你。同样对于这种比较,我会避免使用 == 只是为了确保您的代码按预期运行,而不管 MATLAB 的函数内部实现如何。

更新

我可能不会像您所示那样进行比较来尝试确定下一个邻居的位置,而只是执行以下操作以获得相同的结果。

ind = find(A > 2);

或者如果你真的需要一个逻辑数组。

[0 diff(A > 2) == 1]

或者,您始终可以在 A 中找到最接近匹配项的值,方法如下:

[~, ind] = min(abs(A - match))

更新 2

对于您在评论中提供的示例

C = [exp(1) exp(1) exp(1) 1 1 pi*4 pi*4 pi*4 pi*4];
C == mode(C);

您正在做出(合理的)假设,即 mode return 是被发现为众数的值的精确副本。尽管在上面的比较中,问题是您 also 假设输入数组中出现的所有 pi*4 都是 also 完全相等。所以基本上,如果 mode return 是一个精确副本,比较 C == mode(C) 将 return 在 至少 1 匹配但可以 return 多达 4 个匹配项,具体取决于 "equal" 所有 4*pi 条目的匹配程度。