Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSPredicate dont work with double values (%f)?

My managed object has 2 double fields: "latitude", "longitude". I need to fetch all objects, that has certain coordinates

This code not working, fetchedObjects count = 0

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

But this code work fine, fetchedObjects count = 3:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude == 53.012667 AND longitude == 36.113000"];
like image 632
abuharsky Avatar asked Jan 08 '10 09:01

abuharsky


3 Answers

it works fine with long float, %lf

like image 130
abuharsky Avatar answered Oct 24 '22 08:10

abuharsky


Don't ever use == to compare floating point values.

If you want to find objects with a "specific" value, compare against a small range. Otherwise, floating-point representation error will bite you.

So consider using:

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];
like image 30
jdeprez Avatar answered Oct 24 '22 10:10

jdeprez


It's because the precision of floats is not 100%. So you could also do this:

[NSPredicate predicateWithFormat:@"abs(latitude - %f) < 0.0001 AND abs(longitude - %f) < 0.0001", coordinate.latitude, coordinate.longitude]
like image 2
CommaToast Avatar answered Oct 24 '22 10:10

CommaToast