Showing posts with label bits. Show all posts
Showing posts with label bits. Show all posts

30 August 2010

Using struct to represent bit fields

#include <stdio.h>

struct packed_data
{
unsigned int :3;
unsigned int f1:1;
unsigned int f2:1;
unsigned int f3:1;
unsigned int type:8;
unsigned int index:18;
};
int main(void)
{

struct packed_data pd;
pd.type = 257;
printf("%u\n", pd.type);

pd.f1 = 4;
printf("%u\n", pd.f1);

//printf("%p\n", &(pd.f1)); ERROR

return 0;
}

21 July 2010

BigInteger using C

The following is a very simple implementation for the addition and subtraction of a Big Integer using C. Actually It was my solution for some problem in some compitions of ArabTeam2000 forums
note, I have compiled it under GCC (4.5)

//BigInteger.h

#ifndef BIG_INTEGER_H
#define BIG_INTEGER_H

typedef struct {
    char *data;
    size_t length;
    short sign; // 0 for positive (default value), otherwise for negative
} BigInteger;

// BigInteger interface functions

/**
* The char array are provided from right to left, for example if you want to reprensent the number 200, you
* should use array looks like:
* char arr[] = {0, 0, 2};
*/
BigInteger* construct(char[], size_t);
BigInteger* add(BigInteger*, BigInteger*);
BigInteger* subtract(BigInteger*, BigInteger*);
char* get(BigInteger*);
void print(BigInteger*);

// utility functions
static void intcpy(char*, char*, int);
static char** get_adjusted(BigInteger*, BigInteger*);


#endif


//BigInteger.c

#include <stdio.h>
#include <stdlib.h>

#include "BigInteger.h"

BigInteger* construct(char data[], size_t length) {
    if (length > 40)
        return NULL;
    BigInteger* bi = malloc(sizeof(BigInteger*));
    bi->length = length;
    bi->data = malloc(bi->length*sizeof(char));
    intcpy(bi->data, data, bi->length);
    return bi;
}

BigInteger* add(BigInteger* x, BigInteger* y) {
    char* add_data(char*, char*, int*);
    
    int len = (x->length > y->length) ? x->length : y->length;
    
    char** resized = get_adjusted(x, y);
    char* tmp_x = resized[0];
    char* tmp_y = resized[1];
    
    char* ret = add_data(tmp_x, tmp_y, &len);
    if (ret == NULL)
        return NULL;
    
    BigInteger *b = construct(ret, len);
    
    return b;
}

BigInteger* subtract(BigInteger* x, BigInteger* y) {
    char** resized = get_adjusted(x, y);
    char *tmp_x = resized[0];
    char *tmp_y = resized[1];
    
    enum Sign {
        EQUAL = 0, POSITIVE = 1, NEGATIVE = 2
    };
    
    short ret_sign = EQUAL;
    
    int i;
    for (i = x->length - 1; i >= 0; i--) {
        if (tmp_x[i] == tmp_y[i])
            continue;
        else if (tmp_x[i] > tmp_y[i]) {
            ret_sign = POSITIVE;
            break;
        } else {
            ret_sign = NEGATIVE;
            break;
        }
        
    }
    // TODO: separate the following logic into its own utility function
    BigInteger* bi;
    if (ret_sign == EQUAL) {
        char ret[1] = {0};
        bi= construct(ret, 1);
    }else if (ret_sign == POSITIVE){
        char ret[x->length];
        for (i=0; i<x->length;i++){
            int tmp = tmp_x[i]-tmp_y[i];
            if (tmp <0){
                tmp_x[i+1]--;
                tmp = (tmp_x[i]+10)-tmp_y[i];
            }
            ret[i] = tmp;
        }
        bi=construct(ret, x->length);
    }else{
        char ret[y->length];
        for (i=0; i<y->length;i++){
            int tmp = tmp_y[i]-tmp_x[i];
            if (tmp <0){
                tmp_y[i+1]--;
                tmp = (tmp_y[i]+10)-tmp_x[i];
            }
            ret[i] = tmp;
        }
        bi=construct(ret, y->length);
        bi->sign = 1;
    }
    
    return bi;
}

char* get(BigInteger* bi) {
    return bi->data;
}

void print(BigInteger* bi) {
    char* d = bi->data;
    if (bi->sign) printf("%c", '-');
    int i;
    for (i = (bi->length)-1; i>=0; --i) {
        printf("%i", d[i]);
    }
    printf("\n");
}

char* add_data(char* x, char* y, int *len) {
    int i, reminder = 0;
    char *ret = malloc(sizeof(char) * *len);
    
    for (i = 0; i < *len; i++) {
        int tmp = x[i] + y[i] + reminder;
        ret[i] = tmp % 10;
        reminder = (tmp - ret[i]) / 10;
    }
    
    if (reminder) {
        if (i==40){
            fprintf(stderr, "Arithmetic OverFlown");
            return NULL;
        }else{
            ret[i] =reminder;
            (*len)++;
        }
    }
    return ret;
}

static void intcpy(char* dest, char* src, int l) {
    while (l-- > 0)
        *dest++ = *src++;
}

static char** get_adjusted(BigInteger* x, BigInteger *y) {
    char **ret = malloc(sizeof(char**));
    int len = (x->length > y->length) ? x->length : y->length;
    
    char *tmp_x = get(x);
    char *tmp_y = get(y);
    
    int diff;
    if ((diff = len - x->length) > 0) {
        intcpy(tmp_x, get(x), len);
        while (diff > 0) {
            tmp_x[x->length++] = 0;
            diff--;
        }
    } else if ((diff = len - y->length) > 0) {
        intcpy(tmp_y, get(y), len);
        while (diff > 0) {
            tmp_y[y->length++] = 0;
            diff--;
        }
    }
    ret[0] = tmp_x;
    ret[1] = tmp_y;
    return ret;
}


//main.c

#include <stdio.h>
#include "BigInteger.h"

void test_add1() {
    printf("Start Testing ADD n");
    char d1[] = { 1, 2};            // from right to left, so its value is 21
    char d2[] = { 5};                       // and this is 5
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = add(bi1, bi2);
    print(ret);
    printf("End Testing...n");
}
void test_add2() {
    printf("Start Testing ADD n");
    char d1[40];
    char d2[40];
    
    int i=0;
    for (i=0; i<40;i++){
        d1[i] = 3;
        d2[i] = 5;
    }
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = add(bi1, bi2);
    print(ret);
    printf("End Testing...n");
}

/**
* Will print "Arithmetic Overflow" and returns NULL
*/
void test_add3() {
    printf("Start Testing ADD n");
    char d1[40];
    char d2[40];
    
    int i=0;
    for (i=0; i<40;i++){
        d1[i] = 5;
        d2[i] = 5;
    }
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = add(bi1, bi2);
    if (ret == NULL)
        printf("NULLn");
    //print(ret);
    printf("End Testing...n");
}

void test_add4() {
    printf("Start Testing ADD n");
    char d1[] = { 9, 9};
    char d2[] = { 9, 9};
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = add(bi1, bi2);
    print(ret);
    printf("End Testing...n");
}

void test_add5() {
    printf("Start Testing ADD n");
    char d1[] = { 1, 2, 0, 0, 1, 2, 3, 4, 5, 9 ,3, 1, 3, 4, 4, 2, 1};               // from right to left, so its value is 21
    char d2[] = { 1, 3, 3, 4, 5, 5, 3, 0, 0, 0, 0, 0, 2, 1, 1, 1, 9};                       // and this is 5
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = add(bi1, bi2);
    print(ret);
    printf("End Testing...n");
}

void test_subtract1() {
    printf("Start Testing SUBTRACT n");
    char d1[] = { 1, 2};            // this is 21
    char d2[] = { 5, 2};            // and this is 25
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = subtract(bi1, bi2);
    print(ret);
    printf("End Testing...n");
}

void test_subtract2() {
    printf("Start Testing SUBTRACT n");
    
    char d1[] = { 9, 9};
    char d2[] = { 9, 9};
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = subtract(bi1, bi2);
    print(ret);
    printf("End Testing...n");
}

void test_subtract3() {
    printf("Start Testing SUBTRACT n");
    
    char d1[40];
    char d2[40];
    
    int i=0;
    for (i=0; i<40;i++){
        d1[i] = 3;
        d2[i] = 5;
    }
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = subtract(bi1, bi2);
    print(ret);
    printf("End Testing...n");
}

void test_subtract4() {
    printf("Start Testing SUBTRACT n");
    
    char d1[] = { 1, 2, 0, 0, 1, 2, 3, 4, 5, 9 ,3, 1, 3, 4, 4, 2, 1};               // from right to left, so its value is 21
    char d2[] = { 1, 3, 3, 4, 5, 5, 3, 0, 0, 0, 0, 0, 2, 1, 1, 1, 9};                       // and this is 5
    
    BigInteger* bi1 = construct(d1, sizeof(d1) / sizeof(char));
    BigInteger* bi2 = construct(d2, sizeof(d2) / sizeof(char));
    print(bi1);
    print(bi2);
    BigInteger *ret = subtract(bi1, bi2);
    print(ret);
    printf("End Testing...n");
}


int main(void) {
    test_add1();
    test_add2();
    test_add3();
    test_add4();
    test_add5();
    test_subtract1();
    test_subtract2();
    test_subtract3();
    test_subtract4();
    return 0;
}

How to compile the program:

1- copy the three above files to a new directory (say c_big_int)
ls -l
-rw-r--r-- 1 mhewedy mhewedy 4858 2011-04-05 22:41 main.c
-rw-r--r-- 1 mhewedy mhewedy 4440 2011-04-05 22:41 BigInteger.c
-rw-r--r-- 1 mhewedy mhewedy  712 2011-04-05 22:40 BigInteger.h

2- compile the BigInteger.c
cc -c BigInteger.c

3- make sure that the compilation process generated the object file:
ls -l
-rw-r--r-- 1 mhewedy mhewedy 3180 2011-04-05 22:48 BigInteger.o
-rw-r--r-- 1 mhewedy mhewedy 4858 2011-04-05 22:41 main.c
-rw-r--r-- 1 mhewedy mhewedy 4440 2011-04-05 22:41 BigInteger.c
-rw-r--r-- 1 mhewedy mhewedy  712 2011-04-05 22:40 BigInteger.h

4- Let's generate the binary file:
cc -o main main.c -L. BigInteger.o

5- Now you can run the program using the following command:
./main

**EDIT** The code has been reformatted, if it is no longer working please let me know in the comments

14 July 2010

Decimal to Binary in C

// decimal_2_binary.c

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

char* decimal2binary(unsigned);

int main(void){


unsigned n = 10;
printf("Enter a Positive Number? ");
scanf("%u", &n);

char *binary = decimal2binary(n);

int i;
for (i=0; i<32; i++)
printf("%i", binary[i]);

printf("\n");
return 0;
}


char* decimal2binary(unsigned x){
int size = sizeof(unsigned*)* CHAR_BIT;
char *bits = (char*) malloc(size);
char *ptr = bits;

ptr +=(size-1);
while (x > 0){
char t;
t = x &1;
x = x >>1;
*ptr--=t;
}
while ( ptr - bits >= 0){
*ptr--=0;
}

return bits;
}

13 July 2010

BIT_FLAGS.c


#include <stdio.h>

enum Level{
OK=1, CANCEL=2, ERROR=4, WARNNING=8
};

int main(void){

int u_level;

puts("Enter Level (1 for OK, 2 for CANCEL, 4 for ERROR, 8 for WARNNING or a combination): " );
scanf("%i", &u_level);

if ((u_level&OK) == OK)
puts("OK");
if ((u_level&CANCEL) == CANCEL)
puts("CANCEL");
if ((u_level&ERROR) == ERROR)
puts("ERROR");
if ((u_level&WARNNING) == WARNNING)
puts("WARNNING");


return 0;
}

21 June 2010

Two ways to convert decimal numbers to binary strings

I'll show you two ways to convert decimal to binary.

First, the most basic way is apply the following pseudo-code:

int x
char[80] arr
do{
reminder = x%2;
arr[i] = reminder
}while (x/2 > 0);
reverse arr;


And the other is more advanced (and more simple), it use bitwise operations instead:

int x
while (x > 0){
arr[i] = ((x & 1) ? '1' : '0');
x >>=1;
}
reverse arr


and here's a C code for the last one:
 
//I am not the author of this function, I copied from the link below
void dec2binary(long i){

char* str = malloc(sizeof(long)*8*sizeof(char));

char* p = str;
while (i > 0){
*p++ = ((i & 1) ? '1' : '0');
i >>=1;
}

while( p-- != str ) /* print out the result backwards */
printf("%c",*p);

free(str);
}


please see:
http://www.daniweb.com/code/snippet216349.html

20 May 2010

Shift operators in Java

Here's a very simple lesson that illustrate the shift operators in java

http://www.sap-img.com/java/java-bitwise-shift-operators.htm

Summary:

We have three shift operators in java >>, >>> and <<

1- >>
definition:
right shift with the outermost (hi bit) value
example:
9>> 2
9 in binary is 0000000000001001
so, we need to shift right 2 bites adding instead 2 bits of the hi bit
so, result will be 0000000000000010

2- >>>
It is the same as the above, but adds 0 at the left most (not the hi bit)
so, suppose we have
-1 >> 2
-1 in binary is 1111111111111111 (the 2's complement of 1)
so, the result will be -1 also. but if we applied >>> instead, we will always add 0's to the left of the bit pattern.

3- <<
left right is the oposite to the left shift (<<), that add the hi bit from the right.
ex:
9 << 1
9 in binary is 0000000000001001
result will be 0000000000010010 (in decimal is 18 )

(please let me know if there's any errors because I wrote that conclusion in hurry ;) )