Có một thành ngữ tiêu chuẩn cho phạm vi kiểm tra với một hướng dẫn so sánh duy nhất.Nó đi như:
(unsigned)x - a <= (unsigned)b - a /* a <= x <= b */
(unsigned)x - a < (unsigned)b - a /* a <= x < b */
Là một ví dụ phổ biến (phiên bản này nếu isdigit
là đảm bảo được đúng theo tiêu chuẩn):
(unsigned)ch - '0' < 10
Nếu loại ban đầu của bạn là lớn hơn int
(ví dụ long long
) sau đó bạn sẽ cần phải sử dụng các loại chưa ký lớn hơn (ví dụ unsigned long long
). Nếu a
và b
là các hằng số hoặc đã có loại chưa ký hoặc nếu bạn biết b-a
sẽ không tràn, bạn có thể bỏ qua đoạn trích từ b
.
Để phương thức này hoạt động, tự nhiên bạn phải có a<=b
và các loại/giá trị phải sao cho biểu thức gốc (ví dụ: a <= x && x <= b
hoặc tương tự) hoạt động chính xác về mặt toán học. Ví dụ: nếu x
được ký và b
không được ký, x<=b
có thể đánh giá sai khi x=-1
và b=UINT_MAX-1
. Miễn là các loại ban đầu của bạn đều được ký hoặc nhỏ hơn loại chưa ký bạn đúc, đây không phải là vấn đề.
Đối với cách "lừa" này hoạt động, nó hoàn toàn xác định, sau khi giảm modulo UINT_MAX+1
, cho dù x-a
nằm trong khoảng 0 đến b-a
.
Trong trường hợp của bạn, tôi nghĩ rằng những điều sau đây nên làm việc tốt:
(unsigned)i + threshold > 2U * threshold;
Nếu threshold
không thay đổi giữa lặp loop, trình biên dịch có lẽ có thể giữ cả threshold
và 2U*threshold
trong thanh ghi.
Nói về tối ưu hóa, trình biên dịch tốt nên tối ưu hóa thử nghiệm phạm vi ban đầu của bạn để sử dụng số học chưa ký, nơi nó biết các ràng buộc được đáp ứng. Tôi nghi ngờ nhiều người làm như vậy với a
và b
không đổi, nhưng có lẽ không phải với các biểu thức phức tạp hơn. Ngay cả khi trình biên dịch có thể tối ưu hóa nó, mặc dù, thành ngữ (unsigned)x-a<b-a
vẫn cực kỳ hữu ích trong các macro mà bạn muốn đảm bảo rằng x
được đánh giá chính xác một lần.
Nguồn
2010-10-27 16:06:17
bạn nói "cả hai" nhưng có ba biến. – McKay
không thể nhớ nếu điều này làm việc chắc chắn, nhưng hãy thử 'if ((unsigned int) i> ngưỡng)' – zdav
@zdav Nó chắc chắn không làm việc cho hầu hết các trình biên dịch. Các phôi như vậy ít nhất được thực hiện theo định nghĩa và thường nhận được sự bổ sung của bạn 2. –