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

时间:2016-05-05 01:59:21

标签: matlab double precision

考虑以下工作流程:

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

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

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

我有两个问题:

  1. 我可以期望A == match始终评估为[0 1 0]吗?
  2. 如果B = [exp(1) exp(1) exp(1)]B == match的结果是什么?
  3. 如果exp(1)被其他一些非理性或超越数字所取代,答案是否会改变?

1 个答案:

答案 0 :(得分:3)

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

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

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

    同样,这会产生关于内置函数内部的假设,它最终可能会让你感到厌烦。对于这种比较,我将避免使用==只是为了确保您的代码按预期运行,而不管MATLAB的函数内部实现。

  3. <强>更新

    我可能只是尝试识别下一个邻居的位置,而不是像你一样进行比较,我可能会做以下事情来获得相同的结果。

    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返回被发现为模式的值的精确副本。在上面的比较中,问题是您假设输入数组中所有出现的pi*4 完全相同。所以基本上,如果mode返回精确副本,则比较C == mode(C)将返回至少 1匹配,但可以返回多达4个匹配,具体取决于&#34;等于& #34;所有4*pi条目都是。