You can do this with some elementary bit shifting and bitwise logical operations. This'll do it:
#include <stdio.h>
#define ALLON(X,S,E) ((X & (~((~0U << E) | ~(~0U << (S - 1))))) == (~((~0U << E) | ~(~0U << (S - 1)))))
/*
Or, simplifying with two macros...
#define ALLMASK(S,E) (~((~0U << E) | ~(~0U << (S - 1))))
#define ALLON(X,S,E) ((X & ALLMASK(S,E)) == ALLMASK(S,E))
*/
char * convert_to_8bit(char * buffer, const unsigned int n)
{
size_t k = 0;
for ( unsigned int i = 128; i > 0; i >>= 1 ) {
if ( n & i ) {
buffer[k++] = '1';
}
else {
buffer[k++] = '0';
}
}
return buffer;
}
int main(void)
{
char buffer[9] = {0};
printf("1 in binary is %s\n", convert_to_8bit(buffer, 1));
printf("ALLON(1, 2, 4) is %s\n", ALLON(1, 2, 4) ? "true" : "false");
printf("ALLON(1, 1, 1) is %s\n", ALLON(1, 1, 1) ? "true" : "false");
printf("30 in binary is %s\n", convert_to_8bit(buffer, 30));
printf("ALLON(30, 2, 4) is %s\n", ALLON(30, 2, 4) ? "true" : "false");
printf("ALLON(30, 1, 1) is %s\n", ALLON(30, 1, 1) ? "true" : "false");
printf("ALLON(30, 5, 5) is %s\n", ALLON(30, 5, 5) ? "true" : "false");
printf("ALLON(30, 5, 6) is %s\n", ALLON(30, 5, 6) ? "true" : "false");
return 0;
}
Output:
paul@horus:~/src/sandbox$ ./bs
1 in binary is 00000001
ALLON(1, 2, 4) is false
ALLON(1, 1, 1) is true
30 in binary is 00011110
ALLON(30, 2, 4) is true
ALLON(30, 1, 1) is false
ALLON(30, 5, 5) is true
ALLON(30, 5, 6) is false
paul@horus:~/src/sandbox$
Briefly, suppose we're doing ALLON(31, 2, 4):
~0U << E
takes 11111111
and left shifts it 4, so you get 11110000
~0U << (S - 1)
takes 11111111
and left shifts it 1, so you get 11111110
~(~0U << (S - 1))
negates what you just did, giving you 00000001
- ORing the two gives you
11110001
, where bits 2, 3 and 4 are 0.
- Negating that gives you
00001110
where the bits you're interested in are 1.
- If ANDing that with
X
equals the mask itself, then all your bits are set.
There's probably a shorter way to do it, but this way is at least easy to understand.