2013-04-06 2 views
-1

Предположим, у меня три числа. Два из них образуют диапазон между ними. Последний номер, я хочу проверить, попадает ли он в этот диапазон. Это простое предостережение: цифры, определяющие начало и конец диапазона, могут быть больше или меньше, чем другие. Это для алгоритма физики, производительность которого я стараюсь улучшить, поэтому я также хочу избежать использования условных операторов.Самый лаконичный способ проверки, если число падает между двумя другими номерами?

double inRange(double point, double rangeStart, double rangeEnd){ 
    // returns true if the 'point' lies within the range 
    // the 'range' is every number between 'rangeStart' and 'rangeEnd' 
    // rangeStart can be greater than or less than rangeEnd 
    // conditional branches should be avoided 


    return ?; // return values [0.0 - 1.0] are considered 'in range' 
} 

Есть ли математическое уравнение для достижения этого, не используя логику состояния?

редактировать:

Причина возвращает двойной вместо BOOL, потому, что мне нужно знать соотношение тоже; 0.0 ближе всего к одному ребру, а 1.0 ближе всего к другому.

Оригинальный алгоритм у меня есть это:

double inRange(double point, double rangeStart, double rangeEnd){ 
    if(rangeStart > rangeEnd){ 
     double temp = rangeStart; 
     rangeStart = rangeEnd; 
     rangeEnd = temp; 
    } 
    return (point - rangeStart)/(rangeEnd - rangeStart); 
} 

Мой профайлер показывает около 16% времени программа работает, расходуется в этой функции, с оптимизацией включены. Это называется довольно часто. Не уверен, что условие условие полностью виноват, но я хотел бы попробовать функцию, которая не имеет одного и видеть.

+3

Почему он возвращает 'double'? – Barry

+3

Почему, по вашему мнению, условное утверждение замедляет его? –

+0

Барри - Мне нужно знать соотношение в пределах диапазона. 0.0 ближе всего к rangeStart, а 1.0 ближе всего к диапазонуEnd –

ответ

3

, чтобы ответить на ваши спецификации «он должен вернуться к нулю, когда близко от начала и 1, когда ближе к концу», что вы не хотите условные, и что начало и конец могут быть выгружены:

return (point-std::min(rangeStart, rangeEnd))/std::abs(rangeStart - rangeEnd); 

Обратите внимание, что хотя я не знаю о конкретной реализации STL, min не обязательно требует выполнения условных обозначений. Например, min (a, b) = (a + b-abs (b-a))/2.

+0

Я только что видел ваше редактирование: ваш код был очень похож на этот. – WhitAngl

+0

Я упростил результат, уменьшив количество минут min, max. Вам не нужно вызывать их в знаменателе. –

+0

упс да, действительно! Благодаря! – WhitAngl

2

Если старт больше конца, тогда замените его.

Смежные вопросы