【问题标题】:Matlab gives wrong answerMatlab给出错误答案
【发布时间】:2012-06-07 11:17:57
【问题描述】:

如果执行以下代码,MATLAB 会出错。有人可以验证吗?

floor([0.1:0.1:2]/0.01)

那么 129 在这里做什么??

ans = 10 20 30 40 50 60 70 80 90 100 110 120 129 140 150 160 170 180 190 200

【问题讨论】:

标签: matlab precision numerical


【解决方案1】:

这是一个浮点舍入误差,因为冒号生成的向量。
正如拉斯曼所说,如果你这样做:

floor((0.1:0.1:2 + eps) / 0.01)

不会有舍入误差。

但是,基于how the colon operator works,我建议你做同样的计算:

floor([(1:20)/10] / 0.01)

[编辑根据 Rasman 的评论,我将补充说后一种方法也适用于负值,而添加 eps 有时会失败 em>]

最重要的是,最好使用带有 整数 数字的冒号运算符来最大程度地减少舍入误差。

【讨论】:

    【解决方案2】:

    它可能正在执行浮点计算,导致 129.99999999999999 的不精确值......而不是 130。然后你将它降低到 129。

    【讨论】:

      【解决方案3】:

      这是数组构造带来的舍入近似值。解决方案是添加 eps:

      floor([0.1:0.1:2]/0.01+ eps([0.1:0.1:2]/0.01))
      

      【讨论】:

      • 谢谢,这是针对这种特定情况的解决方法吗?还是在这种情况下你总是推荐这种代码?
      • 大多数时候我看到一个舍入问题是因为它偏离了一个最低有效位(也许是 2,虽然我不记得见过一个。你可以超级安全通过添加 2*eps,但是对于这种类型的问题它可以工作:any((floor([0.1:0.1:200]/0.01 + eps([0.1:0.1:200]/0.01))) - (10:10:20000))
      • 我收回这一点,当你处于积极领域时它会起作用
      • @EitanT 我完全不同意,您正在尝试添加特定于值的 eps,而不是一些通用数字。使用我的示例并进行比较:any((floor([0:0.1:2]/0.01 +eps)) - (0:10:200)) vs any((floor([0:0.1:2]/0.01 +eps([0:0.1:2]/0.01))) - (0:10:200))
      • @Rasman +1 用eps 击败了我的答案,+1 用于对负值的评论;)关于第二条评论,看看我在回答中写的内容,在第一种方法。将eps 添加到冒号生成的向量中,除法之前。
      猜你喜欢
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 2014-11-19
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多