Showing posts with label c. Show all posts
Showing posts with label c. Show all posts

Wednesday, 22 January 2014

Bitwise Operators in C

BITWISE OPERATORS:

    Bitwise operators are u.d to manipulate one or more bits from integral operands like char, int, short, long.

    C language supports the following bitwise operators.

        | – Bitwise OR
   
    & – Bitwise AND

        ~ – One’s complement
   
    ^ – Bitwise XOR
   
    << – left shift
   
    >> – right shift

Note on shifting signed and unsigned numbers:

While performing shifting, if the operand is a signed value, then arithmetic shift will be used. If the type is unsigned, then logical shift will be used.

In case of arithmetic shift, the sign-bit ( MSB ) is preserved. Logical shift will not preserve the signed bit. Let’s see this via an example.

#include<stdio.h>

int main()
   
    {
        signed char a=-8;
         signed char b= a >> 1;
         printf("%d\n",b);
    }

In the above code, we are right shifting -8 by 1. The result will be “-4". Here arithmetic shift is applied since the operand is a signed value.

#include<stdio.h>

int main()
   
    {
         unsigned char a=-8;
        unsigned char b= a >> 1;
        printf("%d\n",b);
     }

 Negative number are represented using 2's complement of its positive equivalent.

2's compliment of +8 is

1111 1000

Right shifting by 1 yields,

0111 1100 ( 124 in decimal )

The above code will result in 124 ( Positive value ). Here logical shift is applied since the operand is unsigned, and it won’t preserve the MSB of the operand.

Right shifts preserve the sign bit. When a signed integer shifts right, the most-significant bit remains set. When an unsigned integer shifts right, the most-significant bit is cleared.

C PROGRAMMING TRICKS

C Programming Tricks:

1.

Always try to compare like

if ( 0 == i )

rather than

if ( i == 0)

In this way you can catch error for unintended assignments like

if ( 0 = i) .


2.

Dont use strlen in a loop condition:

The strlen function is expensive. For every call it must loop over every character in the input string until a nul terminator is found. Therefore, it is very unwise to call it more often than needed. This is bad code:

for ( int ix = 0; ix < strlen(a_str); ix++)
{
     a_str[ix] = tolower( (unsigned char) a_str[ix] );
}


Lets consider a string 1000 characters in length. strlen will be called 1001 times and loop over 1000 characters each time. That is over one million wasted iterations. If the tolower call and assignment takes the equivalent of 10 iterations we can calculate that the operation takes one hundred times longer than it would if written correctly.

strlen as a loop condition should be replaced with:

for ( int ix = 0; a_str[ix] != '\0'; ix++)
{
     a_str[ix] = tolower( (unsigned char) a_str[ix] );
}


or the slightly less efficient:

int len = strlen(a_str);
for ( int ix = 0; ix < len; ix++)
{
     a_str[ix] = tolower( (unsigned char) a_str[ix] );
}


As well as removing unnecessary strlen calls from loops, we should try to remove any other expensive function calls.

3.

Temporarily swap:

Here's a neat trick to swap two variables without creating a temporary:

void swap(int& a, int& b)
{
   a ^= b;
   b ^= a;
   a ^= b;
}


To check correctness, you only need to know that (a^b)^a = b and (b^a)^b = a.