• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - objective-c : Safe float comparison fails strangely

[复制链接]
菜鸟教程小白 发表于 2022-12-13 08:58:22 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我写了一段代码,遇到了一个非常奇怪的问题。即使实际比较为真,两个 float 之间的比较也会返回 NO。我什至通过与 FLT_EPSILON 进行比较来使用安全浮点比较。这是代码:

//To start the process run this:
[self increment:0.0f];




- (void)incrementfloat)f {
    f += 0.02f;

    if ((fabs(f - 1.0f) < FLT_EPSILON)) {
        NSLog(@"STOP");
    }
    else {
        NSLog(@"F %f", f);
        [self increment:f];
    }
}

而且比较总是会失败,代码会进入无限循环。我已经在 iOS 7 上的 32 位设备和 iOS 8 上的 iPhone 5S 模拟器上对此进行了测试。



Best Answer-推荐答案


问题是您正在累积不精确的值。 FLT_EPSILON 应定义为 1.0f + FLT_EPSILON != 1.0f 的最小值。

发生的情况是,在每一步中,您都将一个有限精度值添加到另一个有限精度值,并且会累积一个小误差。由于您正在检查一个足够接近 1.0f1.0f 无法区分的值,因此检查总是失败。

如果你需要在 1.0 停止,你应该直接检查 if (f > 1.0f),或者使用更宽松的约束。请注意,使用 f > 1.0f 可能会产生额外的迭代,如果值比所需的值稍早一点,因此如果迭代量必须精确,则它可能不适合。像 f > 1.0 - 0.02f/2 这样的东西应该更精确。

0.98            1.0-0.02/2              1.0
 |                 |      ACCEPTABLE     |   ACCEPTABLE...   

Xcode 5.1 上的 lldb

(lldb) p f
(float) $0 = 0.999999582
(lldb) p -(f - 1.0f)
(float) $1 = 0.000000417232513
(lldb) p __FLT_EPSILON__
(float) $2 = 0.00000011920929
(lldb) p (-(f - 1.0)) < __FLT_EPSILON__
(bool) $3 = false

关于ios - objective-c : Safe float comparison fails strangely,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25563407/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap