Альтернативные идеи функций могут использовать оператор переключения, как в:
int trailing_zero_bits(uint64_t x) {
int iRetVal = 0;
switch (x & 0x7f) {
case 2:
iRetVal = 1;
break;
case 4:
iRetVal = 2;
break;
case 8:
iRetVal = 3;
break;
case 16:
iRetVal = 4;
break;
case 32:
iRetVal = 5;
break;
case 64:
iRetVal = 6;
break;
default:
iRetVal = 0;
}
return iRetVal;
}
И это можно сжать, используя Устройство Даффа до:
int trailing_zero_bits(uint64_t x) {
int iRetVal = 0;
switch (x & 0x3f) {
case 64: iRetVal++;
case 32: iRetVal++;
case 16: iRetVal++;
case 8: iRetVal++;
case 4: iRetVal++;
case 2: iRetVal++;
break;
default:
break;
}
return iRetVal;
}
ИлиВы могли бы использовать подход таблицы поиска, как в:
int trailing_zero_bits(uint64_t x) {
unsigned char x1[9] = { 0, 0, 1, 0, 2, 0, 0, 0, 3 };
unsigned char x2[9] = { 0, 4, 5, 0, 6, 0, 0, 0, 0 };
return x1[x & 0xf] | x2[(x & 0x70) >> 4];
}
Или альтернативно
int trailing_zero_bits(uint64_t x) {
unsigned short x1[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 };
unsigned short xVal = (unsigned short)(x & 0x7f);
int i = 0;
if (xVal) for (i = 0; (x1[i] & xVal) == 0; i++);
return i;
}
Или исключить таблицу с помощью:
int trailing_zero_bits(uint64_t x) {
unsigned short x1 = 0x01;
unsigned short xVal = (unsigned short)(x & 0x7f);
int i = 0;
if (xVal) for (i = 0; (x1 & xVal) == 0; i++, (x1 <<= 1));
return i;
}
Или вернуться к использованиютаблица, но с указателями для исключения индексации:
int trailing_zero_bits(uint64_t x) {
unsigned short x1[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40};
unsigned short *x2 = x1;
unsigned short xVal = (unsigned short)(x & 0x7f);
if (xVal) for ( ; (*x2 & xVal) == 0; x2++);
return (x2 - x1);
}