Wednesday, May 1, 2013

To find if the nth bit is set

Following from the previous example, this is to find if the nth bit is set or not. Of course, ensure  the second argument i.e. bit_pos is send correctly, have sufficient checks for that. Again, here the assumption is bit_pos starts from 0 to 31 for 32 bit integer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stdio.h"
#include "limits.h"

static unsigned short is_set(unsigned int x,
                        unsigned short bit_pos)
{
        return !!((1<<bit_pos) & x);
}


int main(int argc, char **argv)
{

        /* 0x1000 = 0000 0000 0000 0000 0001 0000 0000 0000
                                           |
                                          12th Bit
        */
        printf("0x%08x - %d \n", 0x1000, is_set(0x1000, 12));
        printf("0x%08x - %d \n", 0x1000, is_set(0x1000, 13));


        return 0;
}


[root@Imperfecto_1 ~]# gcc -g run.c && ./a.out
0x00001000 - 1
0x00001000 - 0

Finding MSB and LSB

How to find if the MSB or the LSB is set?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "stdio.h"
#include "limits.h"

/* This creates a 32 bit value with only MSB set
 * 1 << 31 times produces 10000000000000000000000000000000 i.e. 0x80000000
 * And then we AND it with x which will either yield 0x80000000 or 0x0
 * !!(0x80000000) = 1 and !!(0x0) = 0
 */
static unsigned short is_set_MSB(unsigned int x)
{
        return !!((1<<(sizeof(unsigned int) * CHAR_BIT - 1)) & x);
}

/* This is straight forward, x & 1 will either yield 1 or 0 directly.
 */
static unsigned short is_set_LSB(int x)
{
        return (x & 1);
}

int main(int argc, char **argv)
{

        printf("%08x - %d \n", 0xffffffff, is_set_LSB(0xffffffff));
        printf("%08x - %d \n", 0xfffffff0, is_set_LSB(0xfffffff0));
        printf("%08x - %d \n", 0xffffffff, is_set_MSB(0xffffffff));
        printf("%08x - %d \n", 0x0fffffff, is_set_MSB(0x0fffffff));

        return 0;
}


[root@Imperfecto_1 ~]# gcc -g run.c && ./a.out
ffffffff - 1
fffffff0 - 0
ffffffff - 1
0fffffff - 0

Swap without using a third variable

We know how to swap 2 values using a third temp variable. This is how you do it without using a third variable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "stdio.h"

static void swap(int *x, int *y)
{
        *x = *x + *y;
        *y = *x - *y;
        *x = *x - *y;
        return;
}

static void swap_xor(int *x, int *y)
{
        *x = *x ^ *y;
        *y = *x ^ *y;
        *x = *x ^ *y;
        return;
}

int main(int argc, char **argv)
{

        int x = 10, y = 20;
        printf("1> %d %d\n", x, y);
        swap(&x, &y);
        printf("2> %d %d\n", x, y);
        swap_xor(&x, &y);
        printf("3> %d %d\n", x, y);

        return 0;
}

[root@Imperfecto_1 ~]# gcc -g run.c && ./a.out
1> 10 20
2> 20 10
3> 10 20

Print bits in an Integer

How to print bits in an integer? There are many ways to do this, I mean logically. I have 2 functions here, one recursive and the other one using a loop.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "limits.h"

/* This function prints the bits in a recursive mode
 * It takes out the bits from right side i.e. 0, 1, 2
 * and prints, this being recursive will print the
 * output in reverse order which will be finally
 * the correct order
 */
static void recurse_bits(int x, int *size)
{
        int bit = x & 0x1;
        if((*size)--){
                recurse_bits(x>>=1, size);
                printf("%d ", bit);
        }
}

/* This function prints the bit by taking it from the left
 * side, i.e. 31, 30 etc and printing it right away
 */
static void print_bits(unsigned int x, int *size)
{
        unsigned short bits = *size;
        unsigned int mask = 0x1 << (bits-1);
        while(bits--){
                printf("%d ", !!(x & mask));
                x<<=1;
        }
        return;
}

int main(int argc, char **argv)
{

        int size = sizeof(unsigned int) * CHAR_BIT;
        int val = 9;

        print_bits(val, &size);
        printf("\n");

        recurse_bits(val, &size);
        printf("\n");

        return 0;
}


[root@Imperfecto_1 ~]# gcc -g run.c && ./a.out
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1