2010-01-08 7 views
14

Đối tượng được quản lý của tôi có 2 trường kép: "vĩ độ", "kinh độ". tôi cần phải lấy tất cả các đối tượng, có một số tọa độNSPredicate không hoạt động với các giá trị kép (% f)?

Mã này không làm việc, fetchedObjects count = 0

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

Nhưng mã này làm việc tốt, fetchedObjects count = 3:

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

Trả lời

25

nó hoạt động tốt với phao dài,% lf

+0

Chấp nhận câu trả lời của bạn là đúng, nếu nó giải quyết vấn đề của bạn – Vladimir

+3

Như jdeprez nói bạn không nên so sánh giá trị float. So sánh các giá trị phao là thực hành nguy hiểm và không tốt. Thay vào đó, hãy sử dụng một vùng khá lớn làm vị từ, sau đó tính toán khoảng cách từ điểm gần nhất với điểm bạn đang tìm kiếm từ mảng đối tượng được trả về. – Christopher

+0

Bạn đã lưu ngày của tôi ..... :-) –

14

Oh geez ...

Không sử dụng == để so sánh các giá trị dấu phẩy động, bao giờ hết.

Nếu bạn muốn tìm các đối tượng có giá trị "cụ thể", hãy so sánh với một phạm vi nhỏ. Nếu không, lỗi biểu diễn dấu phẩy động sẽ cắn bạn.

Vì vậy, xem xét sử dụng:

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

Dấu phẩy ** của Clang ** định nghĩa một số hằng số có liên quan đến phao và tăng gấp đôi. Hai trong số đó là 'FLT_EPSILON' (1E-5) và' DBL_EPSILON' (1E-9), nên được sử dụng thay cho epsilon 1E-6 được đưa ra ở đây. Đặc điểm của các hằng số này được xác định bởi [C99 5.2.4.2.2] (http://c0x.coding-guidelines.com/5.2.4.2.2.html). –

+1

Sử dụng '% lf' nếu bạn so sánh với Doubles – ken

2

Đó là bởi vì độ chính xác của nổi không phải là 100%. Vì vậy, bạn cũng có thể làm điều này:

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

Tôi nhận được thông báo lỗi này:' '' 'Vị từ không hợp lệ', lý do: 'Chức năng' abs: 'không được hỗ trợ.'''' –

0

Convert to NSNumber sử dụng này:

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