Как определить, находится ли число в процентах от другого числа - PullRequest
4 голосов
/ 24 августа 2009

Я пишу код iPhone, который нечетко распознает, является ли проведенная линия прямой линией. Я получаю направление двух конечных точек и сравниваю его с 0, 90, 180 и 270 градусами с допуском 10 градусов плюс или минус. Прямо сейчас я делаю это с кучей блоков if, что кажется очень неуклюжим.

Как написать функцию, которая, учитывая подшипник 0..360, допуск процент (скажем, 20% = (от -10 ° до + 10 °)) и прямой угол как 90 градусов, возвращает ли подшипник в пределах допуска?

Обновление: Возможно, я слишком конкретен. Я думаю, что хорошая, общая функция, которая определяет, находится ли число в процентах от другого числа, полезна во многих областях. .

Например: номер swipeLength в пределах 10% из maxSwipe ? Это было бы полезно.

 BOOL isNumberWithinPercentOfNumber(float firstN, float percent, float secondN) {
      // dunno how to calculate
 }

 BOOL result;

 float swipeLength1 = 303; 
 float swipeLength2 = 310; 

 float tolerance = 10.0; // from -5% to 5%
 float maxSwipe = 320.0;

 result = isNumberWithinPercentOfNumber(swipeLength1, tolerance, maxSwipe); 
 // result = NO

 result = isNumberWithinPercentOfNumber(swipeLength2, tolerance, maxSwipe);
 // result = YES

Вы видите, к чему я клоню?

Ответы [ 3 ]

4 голосов
/ 24 августа 2009
int AngularDistance (int angle, int targetAngle) 
{

    int diff = 0;
    diff = abs(targetAngle - angle)

    if (diff > 180) diff = 360 - diff;

    return diff;
}

Это должно работать для любых двух углов.

1 голос
/ 25 августа 2009

20% как десятичное число равно 0,2. Просто разделите на 100,0, чтобы получить десятичную дробь. Разделите на 2,0, чтобы получить половину допустимого диапазона. (Объединено в делитель 200.0)

Оттуда сложите и вычтите из 1,0, чтобы получить значения 90% и 110%. Если первое число находится между диапазонами, то оно у вас есть.

BOOL isNumberWithinPercentOfNumber(float firstN, float percent, float secondN) {
      float decimalPercent = percent / 200.0;
      float highRange = secondN * (1.0 + decimalPercent);
      float lowRange = secondN * (1.0 - decimalPercent);
      return lowRange <= firstN && firstN <= highRange;
 }

Примечание: здесь нет проверки ошибок для NaN или отрицательных значений. Вы захотите добавить это для производственного кода.

Обновление: в процентах включить оба диапазона +/-.

0 голосов
/ 25 августа 2009

Ответ на уточненный / новый вопрос:

bool isNumberWithinPercentOfNumber (float n1, float percentage, float n2)
{

if (n2 == 0.0) //check for div by zero, may not be necessary for float
   return false; //default for a target value of zero is false
else
   return (percentage > abs(abs(n2 - n1)/n2)*100.0);
}

Для объяснения вы берете абсолютную разницу между вашим тестом и целевым значением и делите его на целевое значение (два вызова 'abs' абсолютного значения гарантируют, что это работает и с отрицательными целевыми и тестовыми числами, но не с отрицательными процентами / допуски). Это дает вам процент от разницы, выраженной в виде десятичной дроби, умножает ее на 100, чтобы получить «общее» выражение процента (10% = 0,10),

...