使用switch语句查看数字落入哪个"bin"

Ton*_*ark 1 c switch-statement

假设我有一堆箱子,每个箱子都有一系列数字.一个例子是:

bin 1: 0-8
bin 2: 9-16
bin 3: 17-24
etc
Run Code Online (Sandbox Code Playgroud)

有没有办法使用switch语句来确定一个数字属于哪个bin?我试图弄清楚如何使案例反映一个数字在一个范围内,但它们似乎不是"常量表达式"所以我不确定它是否可能......

编辑

我应该更准确; 我的箱子是两个人的力量......

bin 1: 0 to 2^3
bin 2: 2^3 + 1 to 2^4
bin 3: 2^4 + 1 to 2^5
etc
Run Code Online (Sandbox Code Playgroud)

caf*_*caf 7

您不能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:
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用查找表:

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];
Run Code Online (Sandbox Code Playgroud)

或者,在某些情况下,您可以确定一个简单的公式.您当前的示例似乎是这样的情况:

bin = 1 + (value - 1 / 8);
Run Code Online (Sandbox Code Playgroud)

回复编辑:

对于你的更新问题,关于2的幂,这实际上非常简单.您可以使用"位涂抹"技术将位于两个幂之间的所有值合并为一个值(假设您使用的unsigned longvalue,最大值为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 */
}
Run Code Online (Sandbox Code Playgroud)