2010-06-04 6 views
1

disons que j'ai un tas de bacs, dont chacun contient une plage de nombres. un exemple est:en utilisant une instruction switch pour voir quel 'bin' un nombre tombe en

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

est-il un moyen d'utiliser une instruction switch pour savoir quel bac un numéro appartient? J'essaie de comprendre comment faire des cas reflètent qu'un certain nombre est dans une plage, mais ils ne semblent pas être des « expressions constantes » donc je ne suis pas sûr qu'il est possible ..

modifier

Je devrais probablement être plus précis; mes bacs sont des puissances de deux ...

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

Répondre

7

Vous ne pouvez pas utiliser des plages pour case étiquettes en C - seulement un seul (-expression constante) valeurs.

Si les plages sont petites, comme votre exemple, vous pouvez le faire:

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: 
} 

Vous pouvez également utiliser une table de recherche:

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]; 

Ou, dans certains cas, vous peut déterminer une formule simple. Votre exemple actuel semble être un tel cas:

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

Réponse à modifier:

Pour votre question mise à jour, sur les pouvoirs de 2, cela est en fait assez facile. Vous pouvez utiliser la technique « bit-maculage » pour munge toutes les valeurs qui se trouvent entre deux puissances de deux enfants en une seule valeur (cela suppose que vous utilisez unsigned long pour value, avec une valeur maximale de 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

vous pouvez en cascade si:

 
case 0:case 1: case 2: case 3: case 4: ..... case 8: 
    do_something(); 
    break; 
case 9: case 10: ....... etc 
0

Si votre compilateur est GCC, vous êtes chanceux. GCC a une extension appelée case ranges, qui vous permet d'écrire votre commutateur comme celui-ci:

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

Il n'est pas standard C!

Questions connexes