используя оператор switch, чтобы увидеть, в какой «бин» попадает число - PullRequest
1 голос
/ 04 июня 2010

Допустим, у меня есть куча корзин, каждая из которых содержит диапазон чисел. пример:

bin 1: 0-8
bin 2: 9-16
bin 3: 17-24
etc

есть ли способ использовать оператор switch, чтобы выяснить, к какому бину принадлежит число? я пытаюсь выяснить, как заставить случаи отражать, что число находится в пределах диапазона, но они не являются «постоянными выражениями», поэтому я не уверен, что это возможно

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

Я, наверное, должен быть более точным; мои мусорные ведра имеют силу двух ...

bin 1: 0 to 2^3
bin 2: 2^3 + 1 to 2^4
bin 3: 2^4 + 1 to 2^5
etc

Ответы [ 3 ]

7 голосов
/ 04 июня 2010

Нельзя использовать диапазоны для case меток в C - только отдельные значения (с постоянным выражением).

Если диапазоны малы, как в вашем примере, то вы можете сделать это:

switch (value)
{
    case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
    bin = 1;
    break;

    case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16:
    bin = 2;
    break;

    case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24:
    bin = 3;
    break;

    default:
}

В качестве альтернативы вы можете использовать справочную таблицу:

static const int val_bin[] = {
    1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 to 8 */
    2, 2, 2, 2, 2, 2, 2, 2, /* 9 to 16 */
    3, 3, 3, 3, 3, 3, 3, 3 /* 17 to 24 */
};

bin = val_bin[value];

Или, в некоторых случаях, вы можете определить простую формулу. Ваш текущий пример выглядит так:

bin = 1 + (value - 1 / 8);

Ответ на редактирование:

Для вашего обновленного вопроса, на степени 2, это на самом деле довольно легко. Вы можете использовать технику «размазывания битов», чтобы разбить все значения, которые лежат между двумя степенями двойки, в одно значение (предполагается, что вы используете unsigned long для value, с максимальным значением 2^32 - 1):

if (value > 0)
    value -= 1; /* This is needed because your specified bins are "off by one" from the natural definitions */

value |= value >> 16;
value |= value >> 8;
value |= value >> 4;
value |= value >> 2;
value |= value >> 1;

switch (value)
{
    case 0x00000000UL: /* 0, 1 */
    case 0x00000001UL: /* 2 */
    case 0x00000003UL: /* 2^1 + 1 ... 2^2 */
    case 0x00000007UL: /* 2^2 + 1 ... 2^3 */
    bin = 1;
    break;

    case 0x0000000fUL: /* 2^3 + 1 ... 2^4 */
    bin = 2;
    break;

    case 0x0000001fUL: /* 2^4 + 1 ... 2^5 */
    bin = 3;
    break;

    /* etc */
}
2 голосов
/ 04 июня 2010

Вы можете каскадировать их, хотя:

case 0:case 1: case 2: case 3: case 4: ..... case 8:
    do_something();
    break;
case 9: case 10: ....... etc
0 голосов
/ 04 июня 2010

Если ваш компилятор GCC, вам повезло. GCC имеет расширение, называемое case case , которое позволяет записать ваш переключатель следующим образом:

switch (value) {
    case 0 ... 8:
        bin = 1;
        break;
    case 9 ... 16:
        bin = 2;
        break;
    /* and so on */
}

Это не стандарт C!

...