Code :
- #include <stdio.h>
- #include <assert.h>
- //type d'élément pour la table de lookup, au choix
- typedef char lookup_t; //pas de multiplication de l'indice, moins encombrant
- //typedef int lookup_t; //pas de promotion pour le calcul
- //table de lookup byte -> log2up
- lookup_t log2uplk[256]= {
- 1,
- 2,
- 3,3,
- 4,4,4,4,
- 5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
- };
- //descente binaire par adresses, puis lookup octet
- int log2upA(int x) {
- const unsigned short*const pshrt= (unsigned short*)&x;
- const unsigned char *const pbyte= (unsigned char *)&x;
- if(pshrt[1])
- /**/ if(pbyte[3]) return 3*8 + log2uplk[pbyte[3]];
- /**/ else return 2*8 + log2uplk[pbyte[2]];
- else
- /**/ if(pbyte[1]) return 1*8 + log2uplk[pbyte[1]];
- /**/ else return 0*8 + log2uplk[pbyte[0]];
- }
- //idem, via indice intermédiaire
- int log2upB(int x) {
- const unsigned short*const pshrt= (unsigned short*)&x;
- const unsigned char *const pbyte= (unsigned char *)&x;
- int k= pshrt[1] ? pbyte[3]?3:2 : pbyte[1]?1:0 ;
- return k*8 + log2uplk[pbyte[k]];
- }
- //macros, pas d'appel de fonction
- #define BYTENOF(x,n) ( ((unsigned char *)&x)[n] )
- #define SHRTNOF(x,n) ( ((unsigned short*)&x)[n] )
- #define CPT(x,n) ( n*8 + log2uplk[BYTENOF(x,n)] )
- #define LOG2UP(x) SHRTNOF(x,1) ? (BYTENOF(x,3)?CPT(x,3):CPT(x,2)) : (BYTENOF(x,1)?CPT(x,1):CPT(x,0))
- int main(){
- assert(sizeof(short)==2*sizeof(char )); //1 short fait 2 char
- assert(sizeof(int )==2*sizeof(short)); //1 int fait 2 short
- //assert little endian; //comment faire ?
- int i;
- for(;;){
- scanf("%d",&i);
- printf("\t" );
- printf(" %2d", log2upA(i) );
- printf(" %2d", log2upB(i) );
- printf(" %2d", LOG2UP (i) );
- puts("" );
- }
- return 0;
- }
|