2010-01-08 39 views
14

我的托管对象有两个双字段:“纬度”,“经度”。 我需要获取的所有对象,具有一定的坐标NSPredicate不使用double值(%f)?

此代码不能正常工作,fetchedObjects数= 0

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude == %f AND longitude == %f", coordinate.latitude, coordinate.longitude]; 

但这个代码做工精细,fetchedObjects数= 3:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude == 53.012667 AND longitude == 36.113000"]; 

回答

25

它适用于很长时间的浮动,%lf

+0

接受你的答案是正确的,如果它解决您的问题 – Vladimir 2010-01-08 09:56:36

+3

作为jdeprez说你不应该比较浮点值。比较浮点值是危险且不好的做法。相反,使用相当大的区域作为谓词,然后计算从距离返回对象数组中最近的点到距离搜索点的距离。 – Christopher 2012-07-16 23:53:39

+0

您节省了我的一天..... :-) – 2016-12-28 07:24:06

14

哎呀...

请不要使用==比较浮点值。

如果要查找具有“特定”值的对象,请在小范围内进行比较。否则,浮点表示错误会咬你。

所以考虑使用:

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]; 
+1

Clang's ** float.h **定义了一些与浮点数和双精度相关的常量。其中两个是'FLT_EPSILON'(1E-5)和'DBL_EPSILON'(1E-9),应该用这个来代替这里给出的εE-6。这些常数的特征由[C99 5.2.4.2.2](http://c0x.coding-guidelines.com/5.2.4.2.2.html)定义。 – 2015-01-13 18:48:17

+1

如果你对双精度进行比较,使用'%lf' – ken 2016-04-28 02:46:08

2

这是因为浮动的精确度不是100%。所以,你也可以这样做:

[NSPredicate predicateWithFormat:@"abs(latitude - %f) < 0.0001 AND abs(longitude - %f) < 0.0001", coordinate.latitude, coordinate.longitude] 
+0

我得到这个错误信息:'''无效谓词',原因:''abs:'函数不被支持。'''' – 2016-09-14 11:52:23

0

使用该转换到的NSNumber:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude == %@ AND longitude == %@", @(coordinate.latitude), @(coordinate.longitude)];