Как сопоставить float с перечислением без длинного стека операторов if

Учитывая float, как сопоставить его с перечислением вроде

{FAIL, POOR, OK, GOOD, EXCELLENT, PERFECT}

если деления не равны.

0.0-0.4 - FAIL
  0,4-0,6 - БЕСПЛАТНАЯ   ...
  0.8-0.999.. ОТЛИЧНО
  1.0 PERFECT

Поплавок - это значение рейтинга, рассчитанное на всех уровнях игры в игре. Он варьируется от 0..1, включительно. Обычно требуется не более 10 разделов, но интервалы могут быть настроены во время разработки.

В настоящее время я использую стек операторов if..else. Это правильный способ сделать это? Кажется немного хрупким.

Ответ 1

Использовать массив структур - либо статически распределенный, либо динамический - и затем простую процедуру для поиска - если его малая просто перебирать, если она большая, вы можете выполнять двоичный поиск.

Как вам известно минимум (0.0) и максимум (1.0), вам нужно только сохранить верхнюю границу диапазона и значения перечисления. Например:

typedef enum {FAIL, POOR, OK, GOOD, EXCELLENT, PERFECT} Rating;

typedef struct
{
   float upperBound;
   Rating score;
} RatingDivision;

static RatingDivision Divisions[] =
{
   { 0.4, FAIL },
   { 0.6, POOR },
   ...
   { 0.999, EXCELLENT },
   { 1.0, PERFECT }
};

Теперь sizeof(Divisions)/sizeof(RatingDivision) сообщит вам количество записей (необходимо для двоичного поиска) или просто повторите попытку до тех пор, пока значение, которое вы ищете, не возвращается <= Divisions[i].upperBound Divisions[i].score или upperBound достигает 1.0 с не совпадают и обрабатывают ошибку.

Ответ 2

Вы можете использовать параллельные массивы: использовать массив пороговых значений float и массив значений enum того же размера; то вы можете использовать один короткий цикл, проверяя каждое значение в массиве float и возвращая значение перечисления после пересечения порога.