NSPredicate 不适用于双值 (%f)?
Posted
技术标签:
【中文标题】NSPredicate 不适用于双值 (%f)?【英文标题】:NSPredicate dont work with double values (%f)? 【发布时间】:2010-01-08 09:42:14 【问题描述】:我的托管对象有 2 个双字段:“纬度”、“经度”。 我需要获取所有具有特定坐标的对象
此代码不起作用,fetchedObjects count = 0
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude == %f AND longitude == %f", coordinate.latitude, coordinate.longitude];
但是这段代码工作正常,fetchedObjects count = 3:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude == 53.012667 AND longitude == 36.113000"];
【问题讨论】:
【参考方案1】:它适用于长浮点数,%lf
【讨论】:
正如 jdeprez 所说,您不应该比较浮点值。比较浮点值是危险且不好的做法。相反,使用一个相当大的区域作为谓词,然后从返回的对象数组中计算最接近您正在搜索的点的距离。【参考方案2】:永远不要使用==
来比较浮点值。
如果要查找具有“特定”值的对象,请与小范围进行比较。否则,浮点表示错误会咬你。
所以考虑使用:
const float epsilon = 0.000001;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude > %f AND latitude < %f AND longitude > %f AND longitude < %f", coordinate.latitude - epsilon, coordinate.latitude + epsilon, coordinate.longitude - epsilon, coordinate.longitude + epsilon];
【讨论】:
Clang 的 float.h 定义了许多与浮点数和双精度数相关的常量。其中两个是FLT_EPSILON
(1E-5) 和 DBL_EPSILON
(1E-9),应该使用它们来代替这里给出的 epsilon 1E-6。这些常量的特征由C99 5.2.4.2.2 定义。
如果您要与双打进行比较,请使用 %lf
现在 Double.ulpOfOne
而不是 DBL_EPSILON(后者已被弃用)。【参考方案3】:
这是因为浮点数的精度不是 100%。所以你也可以这样做:
[NSPredicate predicateWithFormat:@"abs(latitude - %f) < 0.0001 AND abs(longitude - %f) < 0.0001", coordinate.latitude, coordinate.longitude]
【讨论】:
我收到此错误消息:'Invalid predicate', reason: 'The 'abs:' function is not supported.'
【参考方案4】:
使用这个转换为 NSNumber:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude == %@ AND longitude == %@", @(coordinate.latitude), @(coordinate.longitude)];
【讨论】:
以上是关于NSPredicate 不适用于双值 (%f)?的主要内容,如果未能解决你的问题,请参考以下文章
python PyQt - 用于浮点或双值+测试的QSlider